#define GCTHREAD_H
#include "OSThreads.h"
+#include "WSDeque.h"
/* -----------------------------------------------------------------------------
General scheme
StgPtr todo_free; // free ptr for todo_bd
StgPtr todo_lim; // lim for todo_bd
- bdescr * buffer_todo_bd; // buffer to reduce contention
- // on the step's todos list
+ WSDeque * todo_q;
+ bdescr * todo_overflow;
+ nat n_todo_overflow;
// where large objects to be scavenged go
bdescr * todo_large_objects;
- // Objects that have already been, scavenged.
+ // Objects that have already been scavenged.
bdescr * scavd_list;
nat n_scavd_blocks; // count of blocks in this list
bdescr * part_list;
unsigned int n_part_blocks; // count of above
- StgWord pad[5];
+ StgWord pad[3];
} step_workspace ATTRIBUTE_ALIGNED(64);
// align so that computing gct->steps[n] is a shift, not a multiply
typedef struct gc_thread_ {
#ifdef THREADED_RTS
OSThreadId id; // The OS thread that this struct belongs to
- Mutex wake_mutex;
- Condition wake_cond; // So we can go to sleep between GCs
- rtsBool wakeup;
- rtsBool exit;
+ SpinLock gc_spin;
+ SpinLock mut_spin;
+ volatile rtsBool wakeup;
#endif
nat thread_index; // a zero based index identifying the thread
// block that is currently being scanned
bdescr * scan_bd;
+ // Remembered sets on this CPU. Each GC thread has its own
+ // private per-generation remembered sets, so it can add an item
+ // to the remembered set without taking a lock. The mut_lists
+ // array on a gc_thread is the same as the one on the
+ // corresponding Capability; we stash it here too for easy access
+ // during GC; see recordMutableGen_GC().
+ bdescr ** mut_lists;
+
// --------------------
// evacuate flags
#define GLOBAL_REG_DECL(type,name,reg) register type name REG(reg);
-#if defined(REG_Base)
+#if defined(sparc_HOST_ARCH)
+// Don't use REG_base or R1 for gct on SPARC because they're getting clobbered
+// by something else. Not sure what yet. -- BL 2009/01/03
+
+extern __thread gc_thread* gct;
+#define DECLARE_GCT __thread gc_thread* gct;
+
+#elif defined(REG_Base) && !defined(i386_HOST_ARCH)
+// on i386, REG_Base is %ebx which is also used for PIC, so we don't
+// want to steal it
GLOBAL_REG_DECL(gc_thread*, gct, REG_Base)
#define DECLARE_GCT /* nothing */