[M3devel] SIGCHLD diff
Tony Hosking
hosking at cs.purdue.edu
Sun Feb 13 21:18:03 CET 2011
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:
>
> Index: ThreadPosix.i3
> ===================================================================
> 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 ----
>
> (*---------------------------------------------------------------------------*)
>
> + <*EXTERNAL ThreadPosix__value_of_SIGCHLD*>
> + PROCEDURE ValueOfSIGCHLD(): int;
> +
> END ThreadPosix.
> Index: ThreadPosix.m3
> ===================================================================
> 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 = pausing, the time at which we can restart *)
> waitingForTime: Time.T;
>
> + (* if state = pausing, the signal that truncates the pause *)
> + waitingForSig: int := -1;
> +
> (* true if we are waiting during an AlertWait or AlertJoin
> or AlertPause *)
> alertable: BOOLEAN := FALSE;
> ***************
> *** 147,152 ****
> --- 150,160 ----
>
> defaultStackSize := 3000;
>
> + (* note that even though the "heavy machinery" is only used for
> + 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 *)
> +
> VAR
> stats: RECORD
> n_forks := 0;
> ***************
> *** 511,527 ****
> XPause(until, FALSE);
> END Pause;
>
> PROCEDURE AlertPause(n: LONGREAL) RAISES {Alerted}=
> VAR until := n + Time.Now ();
> BEGIN
> XPause(until, TRUE);
> END AlertPause;
>
> ! PROCEDURE XPause (READONLY until: Time.T; alertable := FALSE) RAISES {Alerted} =
> BEGIN
> INC (inCritical);
> self.waitingForTime := until;
> self.alertable := alertable;
> ICannotRun (State.pausing);
> DEC (inCritical);
> InternalYield ();
> --- 519,546 ----
> XPause(until, FALSE);
> END Pause;
>
> + PROCEDURE SigPause(n: LONGREAL; sig: int)=
> + <*FATAL Alerted*>
> + VAR until := n + Time.Now ();
> + BEGIN
> + XPause(until, FALSE, sig);
> + END SigPause;
> +
> PROCEDURE AlertPause(n: LONGREAL) RAISES {Alerted}=
> VAR until := n + Time.Now ();
> BEGIN
> XPause(until, TRUE);
> END AlertPause;
>
> ! PROCEDURE XPause (READONLY until: Time.T; alertable := FALSE; sig:int := -1)
> ! RAISES {Alerted} =
> BEGIN
> INC (inCritical);
> self.waitingForTime := until;
> self.alertable := alertable;
> + IF sig # -1 THEN
> + self.waitingForSig := sig
> + END;
> ICannotRun (State.pausing);
> DEC (inCritical);
> InternalYield ();
> ***************
> *** 703,712 ****
> END;
> END StartSwitching;
>
> ! PROCEDURE switch_thread (<*UNUSED*> sig: int) RAISES {Alerted} =
> BEGIN
> allow_sigvtalrm ();
> ! IF inCritical = 0 AND heapState.inCritical = 0 THEN InternalYield () END;
> END switch_thread;
>
> (*------------------------------------------------------------- scheduler ---*)
> --- 722,750 ----
> END;
> END StartSwitching;
>
> ! CONST MaxSigs = 64;
> ! TYPE Sig = [ 0..MaxSigs-1 ];
> !
> ! (* in order to listen to other signals, they have to be enabled in
> ! allow_sigvtalrm as well *)
> ! VAR (*CONST*) SIGCHLD := ValueOfSIGCHLD();
> !
> ! gotSigs := SET OF Sig { };
> !
> ! PROCEDURE switch_thread (sig: int) RAISES {Alerted} =
> BEGIN
> allow_sigvtalrm ();
> !
> ! INC(inCritical);
> ! (* mark signal as being delivered *)
> ! IF sig >= 0 AND sig < MaxSigs THEN
> ! gotSigs := gotSigs + SET OF Sig { sig }
> ! END;
> ! DEC(inCritical);
> !
> ! IF inCritical = 0 AND heapState.inCritical = 0 THEN
> ! InternalYield ()
> ! END;
> END switch_thread;
>
> (*------------------------------------------------------------- scheduler ---*)
> ***************
> *** 782,792 ****
> IF t.alertable AND t.alertPending THEN
> CanRun (t);
> EXIT;
>
> ELSIF t.waitingForTime <= now THEN
> CanRun (t);
> EXIT;
> !
> ELSIF NOT somePausing THEN
> earliest := t.waitingForTime;
> somePausing := TRUE;
> --- 820,835 ----
> IF t.alertable AND t.alertPending THEN
> CanRun (t);
> EXIT;
> +
> + ELSIF t.waitingForSig IN gotSigs THEN
> + t.waitingForSig := -1;
> + CanRun(t);
> + EXIT;
>
> ELSIF t.waitingForTime <= now THEN
> CanRun (t);
> EXIT;
> !
> ELSIF NOT somePausing THEN
> earliest := t.waitingForTime;
> somePausing := TRUE;
> ***************
> *** 886,891 ****
> --- 929,936 ----
> END;
> END;
>
> + gotSigs := SET OF Sig {};
> +
> IF t.state = 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 ****
>
> PROCEDURE WaitProcess (pid: int; VAR status: int): int =
> (* ThreadPThread.m3 and ThreadPosix.m3 are very similar. *)
> ! CONST Delay = 0.1D0;
> BEGIN
> LOOP
> WITH r = Uexec.waitpid(pid, ADR(status), Uexec.WNOHANG) DO
> IF r # 0 THEN RETURN r END;
> END;
> ! Pause(Delay);
> END;
> END WaitProcess;
>
> --- 993,1005 ----
>
> PROCEDURE WaitProcess (pid: int; VAR status: int): int =
> (* ThreadPThread.m3 and ThreadPosix.m3 are very similar. *)
> ! CONST Delay = 10.0D0;
> BEGIN
> LOOP
> WITH r = Uexec.waitpid(pid, ADR(status), Uexec.WNOHANG) DO
> IF r # 0 THEN RETURN r END;
> END;
> ! SigPause(Delay,SIGCHLD);
> END;
> END WaitProcess;
>
> ***************
> *** 1361,1364 ****
> --- 1406,1412 ----
> VAR debug := RTParams.IsPresent ("debugthreads");
>
> 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
> ===================================================================
> 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 ----
>
> sigemptyset(&ThreadSwitchSignal);
> sigaddset(&ThreadSwitchSignal, SIG_TIMESLICE);
> + sigaddset(&ThreadSwitchSignal, SIGCHLD);
>
> act.sa_handler = handler;
> act.sa_flags = SA_RESTART;
> sigemptyset(&(act.sa_mask));
> if (sigaction (SIG_TIMESLICE, &act, NULL)) abort();
> + if (sigaction (SIGCHLD, &act, NULL)) abort();
> + }
> +
> + int
> + __cdecl
> + ThreadPosix__value_of_SIGCHLD(void)
> + {
> + return SIGCHLD;
> }
>
> void
More information about the M3devel
mailing list