[M3devel] SIGCHLD diff
Mika Nystrom
mika at async.caltech.edu
Sun Feb 13 21:37:26 CET 2011
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