46. Thread Manager

46.1. Purpose

The Thread Manager handles various thread-related functions required by the MPS. These are:

  • stack scanning;

  • suspension and resumption of the mutator threads.

46.2. Context

The barrier requires suspension and resumption of threads in order to ensure that the collector has exclusive access to part of memory. [design.mps.barrier.@@@@]

Stack scanning is provided as a service to the client. [Link?@@@@]

46.3. Overview

struct mps_thr_s *Thread

Each thread is represented by an object of type Thread. The Thread type is implemented as an ADT. A list of Thread objects is maintained in the arena (as the Ring structure arena->threadRing). The Thread object contains operating-system-dependent information about the thread – information necessary for manipulating the thread and for scanning the thread context. Thread “registration” adds or removes the current thread to the Thread list in the arena.

46.4. Detailed Design

46.4.1. Stack scan

This is a module providing a stack scanning function. The scanning is architecture and operating system dependent. Typically the function will push the subste of the save registers (those preserved across function calls) which may contain pointers (that is, neither floating-point or debugging registers) and call TraceScanStack() on the appropriate range.

46.4.2. Thread interface

Res ThreadRegister(Thread *threadReturn, Arena arena)

Register the current thread with the arena, allocating a new *threadReturn to point to it.

void ThreadDeregister(Thread thread, Arena arena)

Remove thread from the list of threads managed by the arena and free it.

void ThreadRingSuspend(Ring threadRing)

Suspend all the threads on the list threadRing, except for the current thread.

void ThreadRingResume(Ring threadRing)

Resume all the threads on the list threadRing.

Res ThreadScan(ScanState ss, Thread thread, void *stackBot)

Scan the stacks and root registers of thread, treating each value found as an ambiguous reference. The exact definition is operating system and architecture dependent

46.4.3. Single-threaded generic implementation

In than.c.

46.4.4. POSIX threads implementation

In thix.c. See design.mps.pthreadext.

46.4.5. Win32 implementation

In thw3.c.

  • Supports multiple threads.

  • Structured exception style faults are expected.

  • ThreadRingSuspend() and ThreadRingResume() loop over threads and call Win32 API functions SuspendThread() and ResumeThread().

  • ThreadRegister() records information for the current thread:

    • A Win32 “handle” with access flags THREAD_SUSPEND_RESUME and THREAD_GET_CONTEXT. This handle is needed as parameter to SuspendThread() and ResumeThread().

    • The Win32 GetCurrentThreadId() so that the current thread may be identified.

  • Stack scanning is Win32 specific:

    • ThreadScan() calls StackScan() if the thread is current. GetThreadContext() doesn’t work on the current thread (the context would not necessarily have the values which were in the saved registers on entry to the MM).

    • Otherwise it calls GetThreadContext() to get the root registers and the stack pointer.

    • The thread’s registers are dumped into a CONTEXT structure and fixed in memory.

    • Scan the stack (getting the stack pointer from CONTEXT.Rsp).

46.5. Issues

  1. Scanning after exceptions. StackScan() relies on the non-preserved registers having been pushed on the stack. If we want to scan after a fault we must make sure that these registers are either already stored on the stack, or, have an extra function to do this explicitly.

  2. Multiple registration. It is not clear whether a thread should be allowed to be registered multiple times. We do not provide a mechanism for knowing whether a thread is already registered with an arena.