So we can parallelise minor collections too. Sometimes it's worth it.
The evacuate() code
-------------------------------------------------------------------------- */
-#define MINOR_GC
+#define PARALLEL_GC
#include "Evac.c-inc"
-#undef MINOR_GC
+#undef PARALLEL_GC
#include "Evac.c-inc"
/* -----------------------------------------------------------------------------
// non-minor, parallel, GC. This file contains the code for both,
// controllled by the CPP symbol MINOR_GC.
-#ifdef MINOR_GC
-#define copy(a,b,c,d) copy0(a,b,c,d)
-#define copy_tag(a,b,c,d,e) copy_tag0(a,b,c,d,e)
-#define copyPart(a,b,c,d,e) copyPart0(a,b,c,d,e)
-#define evacuate(a) evacuate0(a)
+#ifndef PARALLEL_GC
+#define copy(a,b,c,d) copy1(a,b,c,d)
+#define copy_tag(a,b,c,d,e) copy_tag1(a,b,c,d,e)
+#define copyPart(a,b,c,d,e) copyPart1(a,b,c,d,e)
+#define evacuate(a) evacuate1(a)
#else
#undef copy
#undef copy_tag
nat i;
StgWord info;
-#if !defined(MINOR_GC) && defined(THREADED_RTS)
+#if defined(PARALLEL_GC) && defined(THREADED_RTS)
spin:
info = xchg((StgPtr)&src->header.info, (W_)&stg_WHITEHOLE_info);
// so.. what is it?
// }
((StgEvacuated*)from)->evacuee = (StgClosure *)tagged_to;
-#if !defined(MINOR_GC) && defined(THREADED_RTS)
+#if defined(PARALLEL_GC) && defined(THREADED_RTS)
write_barrier();
((StgEvacuated*)from)->header.info = &stg_EVACUATED_info;
#endif
nat i;
StgWord info;
-#if !defined(MINOR_GC) && defined(THREADED_RTS)
+#if defined(PARALLEL_GC) && defined(THREADED_RTS)
spin:
info = xchg((StgPtr)&src->header.info, (W_)&stg_WHITEHOLE_info);
if (info == (W_)&stg_WHITEHOLE_info) {
}
((StgEvacuated*)from)->evacuee = (StgClosure *)to;
-#if !defined(MINOR_GC) && defined(THREADED_RTS)
+#if defined(PARALLEL_GC) && defined(THREADED_RTS)
write_barrier();
((StgEvacuated*)from)->header.info = &stg_EVACUATED_info;
#endif
if (!HEAP_ALLOCED(q)) {
-#ifdef MINOR_GC
- return;
-#endif
if (!major_gc) return;
info = get_itbl(q);
#endif
REGPARM1 void evacuate (StgClosure **p);
-REGPARM1 void evacuate0 (StgClosure **p);
+REGPARM1 void evacuate1 (StgClosure **p);
extern lnat thunk_selector_depth;
extern nat N;
extern rtsBool major_gc;
+extern nat n_gc_threads;
extern gc_thread **gc_threads;
register gc_thread *gct __asm__("%rbx");
Scavenge a block
------------------------------------------------------------------------- */
-#define MINOR_GC
+#define PARALLEL_GC
#include "Scav.c-inc"
-#undef MINOR_GC
+#undef PARALLEL_GC
#include "Scav.c-inc"
/* ----------------------------------------------------------------------------
// to scavenge the whole thing and then push it on
// our scavd list. This saves pushing out the
// scan_bd block, which might be partial.
- if (N == 0) {
- scavenge_block0(bd, bd->start);
+ if (n_gc_threads == 1) {
+ scavenge_block1(bd, bd->start);
} else {
scavenge_block(bd, bd->start);
}
// scavenge everything up to the free pointer.
if (ws->scan != NULL && ws->scan < ws->scan_bd->free)
{
- if (N == 0) {
- scavenge_block0(ws->scan_bd, ws->scan);
+ if (n_gc_threads == 1) {
+ scavenge_block1(ws->scan_bd, ws->scan);
} else {
scavenge_block(ws->scan_bd, ws->scan);
}
*
* ---------------------------------------------------------------------------*/
-// This file is #included into Scav.c, twice: firstly with MINOR_GC
+// This file is #included into Scav.c, twice: firstly with PARALLEL_GC
// defined, the second time without.
-#ifdef MINOR_GC
-#define scavenge_block(a,b) scavenge_block0(a,b)
-#define evacuate(a) evacuate0(a)
+#ifndef PARALLEL_GC
+#define scavenge_block(a,b) scavenge_block1(a,b)
+#define evacuate(a) evacuate1(a)
#else
#undef scavenge_block
#undef evacuate
}
case FUN_2_0:
-#ifndef MINOR_GC
scavenge_fun_srt(info);
-#endif
evacuate(&((StgClosure *)p)->payload[1]);
evacuate(&((StgClosure *)p)->payload[0]);
p += sizeofW(StgHeader) + 2;
break;
case THUNK_2_0:
-#ifndef MINOR_GC
scavenge_thunk_srt(info);
-#endif
evacuate(&((StgThunk *)p)->payload[1]);
evacuate(&((StgThunk *)p)->payload[0]);
p += sizeofW(StgThunk) + 2;
break;
case THUNK_1_0:
-#ifndef MINOR_GC
scavenge_thunk_srt(info);
-#endif
evacuate(&((StgThunk *)p)->payload[0]);
p += sizeofW(StgThunk) + 1;
break;
case FUN_1_0:
-#ifndef MINOR_GC
scavenge_fun_srt(info);
-#endif
case CONSTR_1_0:
evacuate(&((StgClosure *)p)->payload[0]);
p += sizeofW(StgHeader) + 1;
break;
case THUNK_0_1:
-#ifndef MINOR_GC
scavenge_thunk_srt(info);
-#endif
p += sizeofW(StgThunk) + 1;
break;
case FUN_0_1:
-#ifndef MINOR_GC
scavenge_fun_srt(info);
-#endif
case CONSTR_0_1:
p += sizeofW(StgHeader) + 1;
break;
case THUNK_0_2:
-#ifndef MINOR_GC
scavenge_thunk_srt(info);
-#endif
p += sizeofW(StgThunk) + 2;
break;
case FUN_0_2:
-#ifndef MINOR_GC
scavenge_fun_srt(info);
-#endif
case CONSTR_0_2:
p += sizeofW(StgHeader) + 2;
break;
case THUNK_1_1:
-#ifndef MINOR_GC
scavenge_thunk_srt(info);
-#endif
evacuate(&((StgThunk *)p)->payload[0]);
p += sizeofW(StgThunk) + 2;
break;
case FUN_1_1:
-#ifndef MINOR_GC
scavenge_fun_srt(info);
-#endif
case CONSTR_1_1:
evacuate(&((StgClosure *)p)->payload[0]);
p += sizeofW(StgHeader) + 2;
break;
case FUN:
-#ifndef MINOR_GC
scavenge_fun_srt(info);
-#endif
goto gen_obj;
case THUNK:
{
StgPtr end;
-#ifndef MINOR_GC
scavenge_thunk_srt(info);
-#endif
end = (P_)((StgThunk *)p)->payload + info->layout.payload.ptrs;
for (p = (P_)((StgThunk *)p)->payload; p < end; p++) {
evacuate((StgClosure **)p);
debugTrace(DEBUG_gc, " scavenged %ld bytes",
(unsigned long)((bd->free - scan) * sizeof(W_)));
}
+
+#undef scavenge_block
+#undef evacuate