[M3devel] SIGCHLD diff
Mika Nystrom
mika at async.caltech.edu
Sat Feb 12 21:44:06 CET 2011
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