[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