[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