Index: src/m3core.h =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/m3core.h,v retrieving revision 1.8 diff -u -r1.8 m3core.h --- src/m3core.h 19 Mar 2010 17:07:58 -0000 1.8 +++ src/m3core.h 19 Mar 2010 17:08:41 -0000 @@ -404,6 +404,13 @@ UINT32 __cdecl Uin__htonl(UINT32 x); UINT16 __cdecl Uin__htons(UINT16 x); +typedef void (*PThreadForkHandler)(void); + +INTEGER +RTOS__PThreadAtFork(PThreadForkHandler prep, + PThreadForkHandler parent, + PThreadForkHandler child); + #ifdef __cplusplus } /* extern "C" */ #endif Index: src/runtime/common/RTCollector.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/runtime/common/RTCollector.m3,v retrieving revision 1.88 diff -u -r1.88 RTCollector.m3 --- src/runtime/common/RTCollector.m3 15 Dec 2009 19:52:08 -0000 1.88 +++ src/runtime/common/RTCollector.m3 19 Mar 2010 17:08:42 -0000 @@ -2033,19 +2033,31 @@ VAR startedWeakCleaner := FALSE; -PROCEDURE WeakRefFromRef (r: REFANY; p: WeakRefCleanUpProc := NIL): WeakRef = +PROCEDURE StartWeakCleaner () = VAR start := FALSE; - result: WeakRef; BEGIN - <* ASSERT r # NIL *> TRY RTOS.LockHeap(); - (* create a WeakCleaner thread the first time through *) - IF p # NIL AND NOT startedWeakCleaner THEN + IF NOT startedWeakCleaner THEN start := TRUE; startedWeakCleaner := TRUE; END; + FINALLY + RTOS.UnlockHeap(); + END; + IF start THEN + EVAL Thread.Fork(NEW(Thread.Closure, apply := WeakCleaner)); + END; + END StartWeakCleaner; + +PROCEDURE WeakRefFromRef (r: REFANY; p: WeakRefCleanUpProc := NIL): WeakRef = + VAR + result: WeakRef; + BEGIN + <* ASSERT r # NIL *> + TRY + RTOS.LockHeap(); (* if necessary, expand weakTable *) IF weakFree0 = -1 THEN ExpandWeakTable(); END; IF p # NIL THEN @@ -2075,9 +2087,8 @@ FINALLY RTOS.UnlockHeap(); END; - IF start THEN - EVAL Thread.Fork(NEW(Thread.Closure, apply := WeakCleaner)); - END; + (* create a WeakCleaner thread the first time through *) + StartWeakCleaner(); RETURN result; END WeakRefFromRef; @@ -2771,8 +2782,24 @@ (*** INITIALIZATION ***) +PROCEDURE PThreadForkChild() = + BEGIN + IF startedForeground THEN + StartBackgroundCollection(); + END; + IF startedBackground THEN + StartBackgroundCollection(); + END; + IF startedWeakCleaner THEN + StartWeakCleaner(); + END; + END PThreadForkChild; + PROCEDURE Init () = + VAR r: INTEGER; BEGIN + r := RTOS.PThreadAtFork((*prepare*)NIL, (*parent*)NIL, PThreadForkChild); + <* ASSERT r = 0 *> IF RTParams.IsPresent("paranoidgc") THEN InstallSanityCheck(); END; IF RTParams.IsPresent("nogc") THEN disableCount := 1; END; IF RTParams.IsPresent("noincremental") THEN incremental := FALSE; END; Index: src/runtime/common/RTOS.i3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/runtime/common/RTOS.i3,v retrieving revision 1.10 diff -u -r1.10 RTOS.i3 --- src/runtime/common/RTOS.i3 8 Sep 2009 05:54:55 -0000 1.10 +++ src/runtime/common/RTOS.i3 19 Mar 2010 17:08:42 -0000 @@ -5,7 +5,7 @@ (*| modified on Sun Feb 21 14:15:00 PST 1993 by jdd *) (*| modified on Wed Jan 27 22:27:27 PST 1993 by mjordan *) -(* "RTOS" is a private interface that provides the low-level, +(* "RTOS" is a semi-private interface that provides the low-level, OS-specific memory allocation and shutdown routines. *) INTERFACE RTOS; @@ -40,4 +40,13 @@ (* Write the "n" bytes beginning at address "a" to the standard error output file or console. *) +(* ThreadF__PThreadAtFork calls pthread_atfork + * on pthreads platform, otherwise does nothing. + * Return value is from pthread_atform, 0 for success, + * always 0 with user threads and Win32 threads. + *) +TYPE PThreadForkHandler = PROCEDURE(); +<* EXTERNAL RTOS__PThreadAtFork *> +PROCEDURE PThreadAtFork(prep, parent, child: PThreadForkHandler): INTEGER; + END RTOS. Index: src/runtime/common/m3makefile =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/runtime/common/m3makefile,v retrieving revision 1.27 diff -u -r1.27 m3makefile --- src/runtime/common/m3makefile 14 Dec 2009 08:09:48 -0000 1.27 +++ src/runtime/common/m3makefile 19 Mar 2010 17:08:42 -0000 @@ -58,7 +58,7 @@ Interface ("RTSignal") Interface ("RTStack") Interface ("RTTypeSRC") -interface ("RTOS") +Interface ("RTOS") proc FileExists(a) is return not stale (a, a) Index: src/thread/POSIX/ThreadPosixC.c =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/POSIX/ThreadPosixC.c,v retrieving revision 1.32 diff -u -r1.32 ThreadPosixC.c --- src/thread/POSIX/ThreadPosixC.c 16 Dec 2009 12:21:36 -0000 1.32 +++ src/thread/POSIX/ThreadPosixC.c 19 Mar 2010 17:08:42 -0000 @@ -279,6 +279,14 @@ #endif } +INTEGER +RTOS__PThreadAtFork(PThreadForkHandler prep, + PThreadForkHandler parent, + PThreadForkHandler child) +{ + return 0; +} + #ifdef __cplusplus } /* extern "C" */ #endif Index: src/thread/PTHREAD/ThreadPThread.m3 =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v retrieving revision 1.233 diff -u -r1.233 ThreadPThread.m3 --- src/thread/PTHREAD/ThreadPThread.m3 18 Mar 2010 11:12:10 -0000 1.233 +++ src/thread/PTHREAD/ThreadPThread.m3 19 Mar 2010 17:08:42 -0000 @@ -6,7 +6,7 @@ Scheduler, SchedulerPosix, RTOS, RTHooks, ThreadPThread; IMPORT Cerrno, FloatMode, MutexRep, - RTCollectorSRC, RTError, RTHeapRep, RTIO, RTParams, + RTCollectorSRC, RTError, RTHeapRep, RTIO, RTOS, RTParams, RTPerfTool, RTProcess, ThreadEvent, Time, Unix, Utime, Word, Usched, Uerror, Uexec; @@ -1294,18 +1294,18 @@ (*-------------------------------------------------------- Initialization ---*) -PROCEDURE Init ()= +PROCEDURE InitWithStackBase (stackbase: ADDRESS) = VAR self: T; me: Activation; BEGIN - InitC(ADR(self)); + InitC(stackbase); me := NEW(Activation, mutex := pthread_mutex_new(), cond := pthread_cond_new()); InitActivations(me); - me.stackbase := ADR(self); (* not quite accurate but hopefully ok *) + me.stackbase := stackbase; IF me.mutex = NIL OR me.cond = NIL THEN Die(ThisLine(), "Thread initialization failed."); END; @@ -1322,8 +1322,48 @@ IF RTParams.IsPresent("foregroundgc") THEN RTCollectorSRC.StartForegroundCollection(); END; + END InitWithStackBase; + +PROCEDURE Init ()= + VAR r: INTEGER; + BEGIN + r := RTOS.PThreadAtFork(PThreadAtForkPrepare, PThreadAtForkParent, PThreadAtForkChild); + IF r # 0 THEN DieI(ThisLine(), r) END; + InitWithStackBase(ADR(r)); (* not quite accurate but hopefully ok *) END Init; +VAR locks := ARRAY [0..3] OF pthread_mutex_t{ + activeMu, slotsMu, initMu, perfMu}; + +PROCEDURE PThreadAtForkPrepare() = + VAR r: int; + BEGIN + joinMu.acquire(); + LockHeap(); + FOR i := FIRST(locks) TO LAST(locks) DO + r := pthread_mutex_lock(locks[i]); + IF r # 0 THEN DieI(ThisLine(), r) END; + END; + (* Walk activations and lock all threads? *) + END PThreadAtForkPrepare; + +PROCEDURE PThreadAtForkParent() = + VAR r: int; + BEGIN + FOR i := LAST(locks) TO FIRST(locks) BY -1 DO + r := pthread_mutex_unlock(locks[i]); + IF r # 0 THEN DieI(ThisLine(), r) END; + END; + UnlockHeap(); + joinMu.release(); + END PThreadAtForkParent; + +PROCEDURE PThreadAtForkChild() = + BEGIN + PThreadAtForkParent(); + InitWithStackBase(GetActivation().stackbase); + END PThreadAtForkChild; + (*------------------------------------------------------------- collector ---*) (* These procedures provide synchronization primitives for the allocator and collector. *) Index: src/thread/PTHREAD/ThreadPThreadC.c =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThreadC.c,v retrieving revision 1.123 diff -u -r1.123 ThreadPThreadC.c --- src/thread/PTHREAD/ThreadPThreadC.c 25 Feb 2010 08:31:36 -0000 1.123 +++ src/thread/PTHREAD/ThreadPThreadC.c 19 Mar 2010 17:08:42 -0000 @@ -414,6 +414,14 @@ #endif } +INTEGER +RTOS__PThreadAtFork(PThreadForkHandler prep, + PThreadForkHandler parent, + PThreadForkHandler child) +{ + return pthread_atfork(prep, parent, child); +} + #ifdef __cplusplus } /* extern "C" */ #endif Index: src/thread/WIN32/ThreadWin32C.c =================================================================== RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/WIN32/ThreadWin32C.c,v retrieving revision 1.64 diff -u -r1.64 ThreadWin32C.c --- src/thread/WIN32/ThreadWin32C.c 16 Jan 2010 12:44:56 -0000 1.64 +++ src/thread/WIN32/ThreadWin32C.c 19 Mar 2010 17:08:42 -0000 @@ -146,6 +146,15 @@ p(bottom, __getReg(?)); /* bsp? bspstore? try numbers until we find it? */ #endif } + +/*-------------------------------------------------------------------------*/ + +INTEGER +RTOS__PThreadAtFork(PThreadForkHandler prep, + PThreadForkHandler parent, + PThreadForkHandler child) +{ + return 0; } /*-------------------------------------------------------------------------*/