Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Jun 1998 21:39:25 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, phk@critter.freebsd.dk
Cc:        current@FreeBSD.ORG, jb@cimlogic.com.au, jdp@polstra.com, rb@gid.co.uk
Subject:   Re: Spurious SIGXCPU
Message-ID:  <199806111139.VAA06458@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>>>>Another sign of the bug is that accounting for rapid context switches
>>>>is broken again:
>>>>
>>>>	$ time ./fork-benchmark 10000
>>>>	        6.10 real         0.01 user         8.33 sys
>>>
>>>if you make it always call
>>>	microuptime(&p->p_switchtime);
>>>
>>>after cpu_switch() in kern_synch, does that make it any different ?
>>
>>Probably.  I fixed it by clearing switchtime.tv_sec in fork_trampoline()
>>and am now trying to figure out why that works :-).  
>
>huh ???

exit() doesn't switch off via mi_switch(), so a stale switchtime
was often used after exit().  Clearing switchtime.tv_sec in
fork_trampoline() fixed the problem in the particular case of child
processes that exit() immediately after the fork().  Ignoring switchtime
of course fixes the problem.  Except both clearing and ignoring lose
track of a little time.

I fixed this in calcru() by setting switchtime.  calcru() is called by
exit1() just before it leaves the kernel, and the value for switchtime
set by this call will be used for the next process unless the system
goes idle.  The value won't be used in other cases (since everything
except exit() switches via mi_switch() which reinitializes switchtime).
Setting switchtime in a natural place (later in exit1()) would leave
the time between the calls to microuptime() unaccounted for.
The other changes in calcru() are cosmetic.

The changes in fork_trampoline() are to avoid leaving the time between
another pair of calls to microtime() unnaccounted for.  switchtime seems
to always be set in fork_trampoline().

Bruce

diff -c2 i386/i386/exception.s~ i386/i386/exception.s
*** i386/i386/exception.s~	Fri May 29 12:52:34 1998
--- i386/i386/exception.s	Thu Jun 11 11:40:44 1998
***************
*** 346,352 ****
--- 431,446 ----
  	movl	_curproc,%eax
  	addl	$P_SWITCHTIME,%eax
+ 	movl	_switchtime,%ecx
+ 	testl	%ecx,%ecx
+ 	jne	1f
  	pushl	%eax
  	call	_microuptime
  	popl	%eax
+ 	jmp	2f
+ 1:
+ 	movl	%ecx,(%eax)
+ 	movl	_switchtime+4,%edx
+ 	movl	%edx,4(%eax)
+ 2:
  
  	/*
diff -c2 kern/kern_resource.c~ kern/kern_resource.c
*** kern/kern_resource.c~	Fri May 29 13:02:39 1998
--- kern/kern_resource.c	Thu Jun 11 11:36:39 1998
  			/* can't set someone else's */
***************
*** 511,517 ****
  	}
  
- 	totusec = p->p_runtime;
  #ifdef SMP
  	if (p->p_oncpu != (char)0xff) {
  #else
  	if (p == curproc) {
--- 511,516 ----
  	}
  
  #ifdef SMP
  	if (p->p_oncpu != (char)0xff) {
  #else
  	if (p == curproc) {
***************
*** 523,529 ****
  		 */
  		microuptime(&tv);
! 		totusec += (tv.tv_usec - p->p_switchtime.tv_usec) +
! 		    (tv.tv_sec - p->p_switchtime.tv_sec) * (int64_t)1000000;
! 	}
  	if (totusec < 0) {
  		/* XXX no %qd in kernel.  Truncate. */
--- 522,531 ----
  		 */
  		microuptime(&tv);
! 		switchtime = tv;	/* XXX */
! 		totusec = p->p_runtime +
! 		    (tv.tv_sec - p->p_switchtime.tv_sec) * (int64_t)1000000 +
! 		    (tv.tv_usec - p->p_switchtime.tv_usec);
! 	} else
! 		totusec = p->p_runtime;
  	if (totusec < 0) {
  		/* XXX no %qd in kernel.  Truncate. */

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199806111139.VAA06458>