[M3devel] SIGCHLD diff

Tony Hosking hosking at cs.purdue.edu
Sun Feb 13 21:44:11 CET 2011


Sorry, I missed you e-mail describing this change.  Looks good.

Antony Hosking | Associate Professor | Computer Science | Purdue University
305 N. University Street | West Lafayette | IN 47907 | USA
Office +1 765 494 6001 | Mobile +1 765 427 5484




On Feb 13, 2011, at 3:37 PM, Mika Nystrom wrote:

> Tony,
> 
> The old user threads has an old problem with Process.Wait.  It has a 
> Thread.Pause(0.1d0) in it.  This causes the compiler to run three times
> slower than it should.  The m3build I've been using for years has
> that Thread.Pause removed (so it uses 100% CPU instead, busy-waiting...)
> 
> But yeah user threads works the same as it used to (except for 
> now calling pthread_atfork, which I'll return to in another email...)
> 
>     Mika
> 
> Tony Hosking writes:
>> Hi Mika, Why was this change needed (I haven't looked closely)?  I don't =
>> think we diverged much from previous implementations of user threads, =
>> which presumably used to work for you.
>> 
>> On Feb 12, 2011, at 3:44 PM, Mika Nystrom wrote:
>> 
>>> =20
>>> Index: ThreadPosix.i3
>>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>>> RCS file: =
>> /usr/cvs/cm3/m3-libs/m3core/src/thread/POSIX/ThreadPosix.i3,v
>>> retrieving revision 1.16
>>> diff -c -r1.16 ThreadPosix.i3
>>> *** ThreadPosix.i3	14 Apr 2010 09:53:34 -0000	1.16
>>> --- ThreadPosix.i3	12 Feb 2011 20:43:26 -0000
>>> ***************
>>> *** 39,42 ****
>>> --- 39,45 ----
>>> =20
>>> =
>> (*------------------------------------------------------------------------=
>> ---*)
>>> =20
>>> + <*EXTERNAL ThreadPosix__value_of_SIGCHLD*>
>>> + PROCEDURE ValueOfSIGCHLD(): int;
>>> +=20
>>> END ThreadPosix.
>>> Index: ThreadPosix.m3
>>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>>> RCS file: =
>> /usr/cvs/cm3/m3-libs/m3core/src/thread/POSIX/ThreadPosix.m3,v
>>> retrieving revision 1.73
>>> diff -c -r1.73 ThreadPosix.m3
>>> *** ThreadPosix.m3	28 Dec 2010 10:13:46 -0000	1.73
>>> --- ThreadPosix.m3	12 Feb 2011 20:43:26 -0000
>>> ***************
>>> *** 97,102 ****
>>> --- 97,105 ----
>>>     (* if state =3D pausing, the time at which we can restart *)
>>>     waitingForTime: Time.T;
>>> =20
>>> +     (* if state =3D pausing, the signal that truncates the pause *)
>>> +     waitingForSig: int :=3D -1;
>>> +=20
>>>     (* true if we are waiting during an AlertWait or AlertJoin=20
>>>        or AlertPause *)
>>>     alertable: BOOLEAN :=3D FALSE;
>>> ***************
>>> *** 147,152 ****
>>> --- 150,160 ----
>>> =20
>>>   defaultStackSize :=3D 3000;
>>> =20
>>> +   (* note that even though the "heavy machinery" is only used for=20
>>> +      multipleThreads, we still need to set up the signal handler so
>>> +      that we can catch signals from other sources than thread =
>> switching.
>>> +      e.g., we use SIGCHLD to speed up Process.Wait *)
>>> +=20
>>> VAR
>>>   stats: RECORD
>>>            n_forks :=3D 0;
>>> ***************
>>> *** 511,527 ****
>>>     XPause(until, FALSE);
>>>   END Pause;
>>> =20
>>> PROCEDURE AlertPause(n: LONGREAL) RAISES {Alerted}=3D
>>>   VAR until :=3D n + Time.Now ();
>>>   BEGIN
>>>     XPause(until, TRUE);
>>>   END AlertPause;
>>> =20
>>> ! PROCEDURE XPause (READONLY until: Time.T; alertable :=3D FALSE) =
>> RAISES {Alerted} =3D
>>>   BEGIN
>>>     INC (inCritical);
>>>       self.waitingForTime :=3D until;
>>>       self.alertable :=3D alertable;
>>>       ICannotRun (State.pausing);
>>>     DEC (inCritical);
>>>     InternalYield ();
>>> --- 519,546 ----
>>>     XPause(until, FALSE);
>>>   END Pause;
>>> =20
>>> + PROCEDURE SigPause(n: LONGREAL; sig: int)=3D
>>> +   <*FATAL Alerted*>
>>> +   VAR until :=3D n + Time.Now ();
>>> +   BEGIN
>>> +     XPause(until, FALSE, sig);
>>> +   END SigPause;
>>> +=20
>>> PROCEDURE AlertPause(n: LONGREAL) RAISES {Alerted}=3D
>>>   VAR until :=3D n + Time.Now ();
>>>   BEGIN
>>>     XPause(until, TRUE);
>>>   END AlertPause;
>>> =20
>>> ! PROCEDURE XPause (READONLY until: Time.T; alertable :=3D FALSE; =
>> sig:int :=3D -1)=20
>>> !   RAISES {Alerted} =3D
>>>   BEGIN
>>>     INC (inCritical);
>>>       self.waitingForTime :=3D until;
>>>       self.alertable :=3D alertable;
>>> +       IF sig # -1 THEN
>>> +         self.waitingForSig :=3D sig
>>> +       END;
>>>       ICannotRun (State.pausing);
>>>     DEC (inCritical);
>>>     InternalYield ();
>>> ***************
>>> *** 703,712 ****
>>>     END;
>>>   END StartSwitching;
>>> =20
>>> ! PROCEDURE switch_thread (<*UNUSED*> sig: int) RAISES {Alerted} =3D
>>>   BEGIN
>>>     allow_sigvtalrm ();
>>> !     IF inCritical =3D 0 AND heapState.inCritical =3D 0 THEN =
>> InternalYield () END;
>>>   END switch_thread;
>>> =20
>>> (*------------------------------------------------------------- =
>> scheduler ---*)
>>> --- 722,750 ----
>>>     END;
>>>   END StartSwitching;
>>> =20
>>> ! CONST MaxSigs =3D 64;
>>> ! TYPE Sig =3D [ 0..MaxSigs-1 ];
>>> !=20
>>> ! (* in order to listen to other signals, they have to be enabled in
>>> !    allow_sigvtalrm as well *)
>>> ! VAR (*CONST*) SIGCHLD :=3D ValueOfSIGCHLD();
>>> !              =20
>>> !     gotSigs :=3D SET OF Sig { };
>>> !=20
>>> ! PROCEDURE switch_thread (sig: int) RAISES {Alerted} =3D
>>>   BEGIN
>>>     allow_sigvtalrm ();
>>> !=20
>>> !     INC(inCritical);
>>> !     (* mark signal as being delivered *)
>>> !     IF sig >=3D 0 AND sig < MaxSigs THEN
>>> !       gotSigs :=3D gotSigs + SET OF Sig { sig }
>>> !     END;
>>> !     DEC(inCritical);
>>> !=20
>>> !     IF inCritical =3D 0 AND heapState.inCritical =3D 0 THEN=20
>>> !       InternalYield ()=20
>>> !     END;
>>>   END switch_thread;
>>> =20
>>> (*------------------------------------------------------------- =
>> scheduler ---*)
>>> ***************
>>> *** 782,792 ****
>>>             IF t.alertable AND t.alertPending THEN
>>>               CanRun (t);
>>>               EXIT;
>>> =20
>>>             ELSIF t.waitingForTime <=3D now THEN
>>>               CanRun (t);
>>>               EXIT;
>>> !  =20
>>>             ELSIF NOT somePausing THEN
>>>               earliest :=3D t.waitingForTime;
>>>               somePausing :=3D TRUE;
>>> --- 820,835 ----
>>>             IF t.alertable AND t.alertPending THEN
>>>               CanRun (t);
>>>               EXIT;
>>> +              =20
>>> +             ELSIF t.waitingForSig IN gotSigs THEN
>>> +               t.waitingForSig :=3D -1;
>>> +               CanRun(t);
>>> +               EXIT;
>>> =20
>>>             ELSIF t.waitingForTime <=3D now THEN
>>>               CanRun (t);
>>>               EXIT;
>>> !=20
>>>             ELSIF NOT somePausing THEN
>>>               earliest :=3D t.waitingForTime;
>>>               somePausing :=3D TRUE;
>>> ***************
>>> *** 886,891 ****
>>> --- 929,936 ----
>>>       END;
>>>     END;
>>> =20
>>> +     gotSigs :=3D SET OF Sig {};
>>> +=20
>>>     IF t.state =3D State.alive AND (scanned OR NOT someBlocking) THEN
>>>       IF perfOn THEN PerfRunning (t.id); END;
>>>       (* At least one thread wants to run; transfer to it *)
>>> ***************
>>> *** 948,960 ****
>>> =20
>>> PROCEDURE WaitProcess (pid: int; VAR status: int): int =3D
>>>   (* ThreadPThread.m3 and ThreadPosix.m3 are very similar. *)
>>> !   CONST Delay =3D 0.1D0;
>>>   BEGIN
>>>     LOOP
>>>       WITH r =3D Uexec.waitpid(pid, ADR(status), Uexec.WNOHANG) DO
>>>         IF r # 0 THEN RETURN r END;
>>>       END;
>>> !       Pause(Delay);
>>>     END;
>>>   END WaitProcess;
>>> =20
>>> --- 993,1005 ----
>>> =20
>>> PROCEDURE WaitProcess (pid: int; VAR status: int): int =3D
>>>   (* ThreadPThread.m3 and ThreadPosix.m3 are very similar. *)
>>> !   CONST Delay =3D 10.0D0;
>>>   BEGIN
>>>     LOOP
>>>       WITH r =3D Uexec.waitpid(pid, ADR(status), Uexec.WNOHANG) DO
>>>         IF r # 0 THEN RETURN r END;
>>>       END;
>>> !       SigPause(Delay,SIGCHLD);
>>>     END;
>>>   END WaitProcess;
>>> =20
>>> ***************
>>> *** 1361,1364 ****
>>> --- 1406,1412 ----
>>> VAR debug :=3D RTParams.IsPresent ("debugthreads");
>>> =20
>>> BEGIN
>>> +   (* we need to call set up the signal handler for other reasons =
>> than
>>> +      just thread switching now *)
>>> +   setup_sigvtalrm (switch_thread);
>>> END ThreadPosix.
>>> Index: ThreadPosixC.c
>>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
>> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
>>> RCS file: =
>> /usr/cvs/cm3/m3-libs/m3core/src/thread/POSIX/ThreadPosixC.c,v
>>> retrieving revision 1.59
>>> diff -c -r1.59 ThreadPosixC.c
>>> *** ThreadPosixC.c	12 Feb 2011 00:56:32 -0000	1.59
>>> --- ThreadPosixC.c	12 Feb 2011 20:43:26 -0000
>>> ***************
>>> *** 78,88 ****
>>> --- 78,97 ----
>>> =20
>>>   sigemptyset(&ThreadSwitchSignal);
>>>   sigaddset(&ThreadSwitchSignal, SIG_TIMESLICE);
>>> +   sigaddset(&ThreadSwitchSignal, SIGCHLD);
>>> =20
>>>   act.sa_handler =3D handler;
>>>   act.sa_flags =3D SA_RESTART;
>>>   sigemptyset(&(act.sa_mask));
>>>   if (sigaction (SIG_TIMESLICE, &act, NULL)) abort();
>>> +   if (sigaction (SIGCHLD, &act, NULL)) abort();
>>> + }
>>> +=20
>>> + int
>>> + __cdecl
>>> + ThreadPosix__value_of_SIGCHLD(void)
>>> + {
>>> + 	return SIGCHLD;
>>> }
>>> =20
>>> void




More information about the M3devel mailing list