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>
