[MLton-commit] r6450

spoons at mlton.org spoons at mlton.org
Mon Mar 3 07:36:17 PST 2008


Changes to included code for parallelism.

Update included files, mostly to reflect were global state has
been moved into GC_state.

----------------------------------------------------------------------

U   mlton/branches/shared-heap-multicore/include/c-chunk.h
U   mlton/branches/shared-heap-multicore/include/c-common.h
U   mlton/branches/shared-heap-multicore/include/c-main.h
U   mlton/branches/shared-heap-multicore/include/x86-main.h

----------------------------------------------------------------------

Modified: mlton/branches/shared-heap-multicore/include/c-chunk.h
===================================================================
--- mlton/branches/shared-heap-multicore/include/c-chunk.h	2008-03-03 15:34:36 UTC (rev 6449)
+++ mlton/branches/shared-heap-multicore/include/c-chunk.h	2008-03-03 15:36:16 UTC (rev 6450)
@@ -43,7 +43,7 @@
 
 #define C(ty, x) (*(ty*)(x))
 #define G(ty, i) (global##ty [i])
-#define GPNR(i) G(ObjptrNonRoot, i)
+#define GPNR(i) (((Pointer*)(GCState + GlobalObjptrNonRootOffset))[i])
 #define O(ty, b, o) (*(ty*)((b) + (o)))
 #define X(ty, b, i, s, o) (*(ty*)((b) + ((i) * (s)) + (o)))
 #define S(ty, i) *(ty*)(StackTop + (i))
@@ -98,15 +98,15 @@
 #define Chunk(n)                                                \
         DeclareChunk(n) {                                       \
                 struct cont cont;                               \
+                Pointer GCState = (Pointer)(pthread_getspecific (gcstate_key)); \
                 register unsigned int frontier asm("g5");       \
-                uintptr_t l_nextFun = nextFun;                  \
                 register unsigned int stackTop asm("g6");
 #else
 #define Chunk(n)                                \
         DeclareChunk(n) {                       \
                 struct cont cont;               \
+                Pointer GCState = (Pointer)(pthread_getspecific (gcstate_key)); \
                 Pointer frontier;               \
-                uintptr_t l_nextFun = nextFun;  \
                 Pointer stackTop;
 #endif
 
@@ -123,8 +123,8 @@
 #define EndChunk                                                        \
                 default:                                                \
                         /* interchunk return */                         \
-                        nextFun = l_nextFun;                            \
-                        cont.nextChunk = (void*)nextChunks[nextFun];    \
+                        cont.nextFun = l_nextFun;                       \
+                        cont.nextChunk = (void*)nextChunks[l_nextFun];  \
                         leaveChunk:                                     \
                                 FlushFrontier();                        \
                                 FlushStackTop();                        \
@@ -142,7 +142,7 @@
                 if (DEBUG_CCODEGEN)                                     \
                         fprintf (stderr, "%s:%d: Thread_returnToC()\n", \
                                         __FILE__, __LINE__);            \
-                returnToC = TRUE;                                       \
+                (*(uint32_t*)(GCState + ReturnToCOffset)) = TRUE;       \
                 return cont;                                            \
         } while (0)
 
@@ -150,9 +150,10 @@
 /*                      farJump                      */
 /* ------------------------------------------------- */
 
+/* XXX spoons should take cont as arg? */
 #define FarJump(n, l)                           \
         do {                                    \
-                PrepFarJump(n, l);              \
+                PrepFarJump(cont, n, l);        \
                 goto leaveChunk;                \
         } while (0)
 

Modified: mlton/branches/shared-heap-multicore/include/c-common.h
===================================================================
--- mlton/branches/shared-heap-multicore/include/c-common.h	2008-03-03 15:34:36 UTC (rev 6449)
+++ mlton/branches/shared-heap-multicore/include/c-common.h	2008-03-03 15:36:16 UTC (rev 6450)
@@ -13,26 +13,28 @@
 #define DEBUG_CCODEGEN FALSE
 #endif
 
+/* A key whose value will be a unique integer per thread */
+extern C_Pthread_Key_t gcstate_key;
+
 struct cont {
         void *nextChunk;
+        uintptr_t nextFun;
 };
 
-extern uintptr_t nextFun;
-extern int returnToC;
 extern struct cont (*nextChunks []) (void);
-extern struct GC_state gcState;
+extern struct GC_state * gcState;
 
 #define ChunkName(n) Chunk ## n
 
 #define DeclareChunk(n)                         \
-        struct cont ChunkName(n)(void)
+        struct cont ChunkName(n)(uintptr_t l_nextFun)
 
 #define Chunkp(n) &(ChunkName(n))
 
-#define PrepFarJump(n, l)                               \
+#define PrepFarJump(cont, n, l)                         \
         do {                                            \
                 cont.nextChunk = (void*)ChunkName(n);   \
-                nextFun = l;                            \
+                cont.nextFun = l;                       \
         } while (0)
 
 #endif /* #ifndef _C_COMMON_H_ */

Modified: mlton/branches/shared-heap-multicore/include/c-main.h
===================================================================
--- mlton/branches/shared-heap-multicore/include/c-main.h	2008-03-03 15:34:36 UTC (rev 6449)
+++ mlton/branches/shared-heap-multicore/include/c-main.h	2008-03-03 15:36:16 UTC (rev 6450)
@@ -16,54 +16,108 @@
         return (GC_frameIndex)ra;
 }
 
-#define Main(al, mg, mfs, mmc, pk, ps, mc, ml)                          \
+#define Main(al, mg, mfs, mmc, pk, ps, gnr, mc, ml)                     \
 /* Globals */                                                           \
-uintptr_t nextFun;                                                      \
-int returnToC;                                                          \
-void MLton_callFromC () {                                               \
+pthread_key_t gcstate_key;                                              \
+void MLton_callFromC (uint32_t ffiOp) {                                 \
         struct cont cont;                                               \
-        GC_state s;                                                     \
+        GC_state s = pthread_getspecific (gcstate_key);                 \
                                                                         \
         if (DEBUG_CCODEGEN)                                             \
                 fprintf (stderr, "MLton_callFromC() starting\n");       \
-        s = &gcState;                                                   \
         s->savedThread = s->currentThread;                              \
         s->atomicState += 3;                                            \
+        s->ffiOp = ffiOp;                                               \
         /* Switch to the C Handler thread. */                           \
         GC_switchToThread (s, s->callFromCHandlerThread, 0);            \
-        nextFun = *(uintptr_t*)(s->stackTop - GC_RETURNADDRESS_SIZE);   \
-        cont.nextChunk = nextChunks[nextFun];                           \
-        returnToC = FALSE;                                              \
+        cont.nextFun = *(uintptr_t*)(s->stackTop - GC_RETURNADDRESS_SIZE); \
+        cont.nextChunk = nextChunks[cont.nextFun];                      \
+        s->returnToC = FALSE;                                           \
         do {                                                            \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
-        } while (not returnToC);                                        \
+                cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+        } while (not s->returnToC);                                     \
         GC_switchToThread (s, s->savedThread, 0);                       \
         s->savedThread = BOGUS_OBJPTR;                                  \
         if (DEBUG_CCODEGEN)                                             \
                 fprintf (stderr, "MLton_callFromC done\n");             \
 }                                                                       \
-int main (int argc, char **argv) {                                      \
+                                                                        \
+void run (void *arg) {                                                  \
         struct cont cont;                                               \
-        Initialize (al, mg, mfs, mmc, pk, ps);                          \
-        if (gcState.amOriginal) {                                       \
+        GC_state s = (GC_state)arg;                                     \
+        uint32_t num = Proc_processorNumber (s)                         \
+                * s->controls->affinityStride                           \
+                + s->controls->affinityBase;                            \
+        plpa_cpu_set_t cpuset;                                          \
+                                                                        \
+        PLPA_CPU_ZERO (&cpuset);                                        \
+        PLPA_CPU_SET (num, &cpuset);                                    \
+        if (plpa_sched_setaffinity (0, sizeof(cpuset), &cpuset)) {      \
+                fprintf (stderr, "Warning: unable to set CPU affinity\n"); \
+        }                                                               \
+                                                                        \
+        /* Save our state locally */                                    \
+        pthread_setspecific (gcstate_key, s);                           \
+        if (s->amOriginal) {                                            \
                 real_Init();                                            \
-                PrepFarJump(mc, ml);                                    \
+                PrepFarJump(cont, mc, ml);                              \
         } else {                                                        \
                 /* Return to the saved world */                         \
-                nextFun = *(uintptr_t*)(gcState.stackTop - GC_RETURNADDRESS_SIZE); \
-                cont.nextChunk = nextChunks[nextFun];                   \
+                cont.nextFun = *(uintptr_t*)(s->stackTop - GC_RETURNADDRESS_SIZE); \
+                cont.nextChunk = nextChunks[cont.nextFun];              \
         }                                                               \
-        /* Trampoline */                                                \
-        while (1) {                                                     \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
-                cont=(*(struct cont(*)(void))cont.nextChunk)();         \
+        /* Check to see whether or not we are the first thread */       \
+        if (Proc_amPrimary (s)) {                                       \
+                /* Trampoline */                                        \
+                while (1) {                                             \
+                        cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+                        cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+                        cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+                        cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+                        cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+                        cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+                        cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+                        cont=(*(struct cont(*)(uintptr_t))cont.nextChunk)(cont.nextFun); \
+                }                                                       \
         }                                                               \
+        else {                                                          \
+                Proc_waitForInitialization (s);                         \
+                Parallel_run ();                                        \
+        }                                                               \
+}                                                                       \
+int main (int argc, char **argv) {                                      \
+        int procNo;                                                     \
+        pthread_t *threads;                                             \
+        {                                                               \
+                struct GC_state s;                                      \
+                /* Initialize with a generic state to read in @MLtons, etc */ \
+                Initialize (s, al, mg, mfs, mmc, pk, ps, gnr);          \
+                                                                        \
+                threads = (pthread_t *) malloc ((s.numberOfProcs - 1) * sizeof (pthread_t)); \
+                gcState = (GC_state) malloc (s.numberOfProcs * sizeof (struct GC_state)); \
+                /* Create key */                                        \
+                if (pthread_key_create(&gcstate_key, NULL)) {           \
+                        fprintf (stderr, "pthread_key_create failed: %s\n", strerror (errno)); \
+                        exit (1);                                       \
+                }                                                       \
+                /* Now copy initialization to the first processor state */      \
+                memcpy (&gcState[0], &s, sizeof (struct GC_state));     \
+                gcState[0].procStates = gcState;                        \
+                GC_lateInit (&gcState[0]);                              \
+        }                                                               \
+        /* Fill in per-processor data structures */                     \
+        for (procNo = 1; procNo < gcState[0].numberOfProcs; procNo++) { \
+                Duplicate (&gcState[procNo], &gcState[0]);              \
+                gcState[procNo].procStates = gcState;                   \
+        }                                                               \
+        /* Now create the threads */                                    \
+        for (procNo = 1; procNo < gcState[0].numberOfProcs; procNo++) { \
+                if (pthread_create (&threads[procNo - 1], NULL, &run, (void *)&gcState[procNo])) { \
+                        fprintf (stderr, "pthread_create failed: %s\n", strerror (errno)); \
+                        exit (1);                                       \
+                }                                                       \
+        }                                                               \
+        run ((void *)&gcState[0]);                                      \
 }
 
 #endif /* #ifndef _C_MAIN_H */

Modified: mlton/branches/shared-heap-multicore/include/x86-main.h
===================================================================
--- mlton/branches/shared-heap-multicore/include/x86-main.h	2008-03-03 15:34:36 UTC (rev 6449)
+++ mlton/branches/shared-heap-multicore/include/x86-main.h	2008-03-03 15:36:16 UTC (rev 6450)
@@ -66,13 +66,15 @@
 int main (int argc, char **argv) {                                      \
         pointer jump;                                                   \
         extern pointer ml;                                              \
+        int procNumber = 0;                                             \
+        gcState = (GC_state *) malloc (MAX_PROCS * sizeof (GC_state));  \
                                                                         \
-        Initialize (al, mg, mfs, mmc, pk, ps);                          \
-        if (gcState.amOriginal) {                                       \
+        Initialize (procNumber, al, mg, mfs, mmc, pk, ps);              \
+        if (gcState[procNumber].amOriginal) {                           \
                 real_Init();                                            \
                 jump = (pointer)&ml;                                    \
         } else {                                                        \
-                jump = *(pointer*)(gcState.stackTop - GC_RETURNADDRESS_SIZE); \
+                jump = *(pointer*)(gcState[procNumber].stackTop - GC_RETURNADDRESS_SIZE); \
         }                                                               \
         MLton_jumpToSML(jump);                                          \
         return 1;                                                       \




More information about the MLton-commit mailing list