-/* -----------------------------------------------------------------------------
- General scheme
-
- ToDo: move this to the wiki when the implementation is done.
-
- We're only going to try to parallelise the copying GC for now. The
- Plan is as follows.
-
- Each thread has a gc_thread structure (see below) which holds its
- thread-local data. We'll keep a pointer to this in a thread-local
- variable, or possibly in a register.
-
- In the gc_thread structure is a step_workspace for each step. The
- primary purpose of the step_workspace is to hold evacuated objects;
- when an object is evacuated, it is copied to the "todo" block in
- the thread's workspace for the appropriate step. When the todo
- block is full, it is pushed to the global step->todos list, which
- is protected by a lock. (in fact we intervene a one-place buffer
- here to reduce contention).
-
- A thread repeatedly grabs a block of work from one of the
- step->todos lists, scavenges it, and keeps the scavenged block on
- its own ws->scavd_list (this is to avoid unnecessary contention
- returning the completed buffers back to the step: we can just
- collect them all later).
-
- When there is no global work to do, we start scavenging the todo
- blocks in the workspaces. This is where the scan_bd field comes
- in: we can scan the contents of the todo block, when we have
- scavenged the contents of the todo block (up to todo_bd->free), we
- don't want to move this block immediately to the scavd_list,
- because it is probably only partially full. So we remember that we
- have scanned up to this point by saving the block in ws->scan_bd,
- with the current scan pointer in ws->scan. Later, when more
- objects have been copied to this block, we can come back and scan
- the rest. When we visit this workspace again in the future,
- scan_bd may still be the same as todo_bd, or it might be different:
- if enough objects were copied into this block that it filled up,
- then we will have allocated a new todo block, but *not* pushed the
- old one to the step, because it is partially scanned.
-
- The reason to leave scanning the todo blocks until last is that we
- want to deal with full blocks as far as possible.
- ------------------------------------------------------------------------- */
-
-
-/* -----------------------------------------------------------------------------
- Step Workspace
-
- A step workspace exists for each step for each GC thread. The GC
- thread takes a block from the todos list of the step into the
- scanbd and then scans it. Objects referred to by those in the scan
- block are copied into the todo or scavd blocks of the relevant step.
-
- ------------------------------------------------------------------------- */
-
-typedef struct step_workspace_ {
- step * step; // the step for this workspace
- struct gc_thread_ * gct; // the gc_thread that contains this workspace