### Navigation

- index
- next |
- previous |
- Memory Pool System 1.111.0 documentation »
- Reference »

# 8. Threads

## 8.1. Thread safety

The MPS is designed to run in an environment with multiple threads all calling into the MPS. Some code is known to operate with exclusive access to the data it manipulates (for example, allocation via allocation points, in the common case where the buffer does not need to be refilled, and location dependencies), so this code is safe. For the rest of the code, shared data structures are locked by the use of a single lock per arena. This lock is claimed on entry to the MPS and released on exit from it. So there is at most a single thread (per arena) running “inside” the MPS at a time.

## 8.2. Thread registration

In order to scan a thread’s registers for references (which happens at each flip), the MPS needs to be able to suspend that thread, and in order to gain exclusive atomic access to memory in order to scan it, the MPS needs to be able to suspend all threads that might access that memory. This means that threads must be registered with the MPS by calling `mps_thread_reg()` (and thread roots created; see Thread roots).

For simplicity, we recommend that a thread must be registered with an arena if:

- its registers and control stack form a root (this is enforced by `mps_root_create_reg()`); or
- it reads or writes from a location in an automatically managed pool in the arena.

However, some automatically managed pool classes may be more liberal than this. See the documentation for the pool class.

Warning

On Unix platforms, the MPS suspends and resumes threads by sending them signals. There’s a shortage of available signals that aren’t already dedicated to other purposes (for example, LinuxThreads uses `SIGUSR1` and `SIGUSR2`), so the MPS uses `SIGXCPU` and `SIGXFSZ`. This means that a program that handles these signals needs to co-operate with the MPS.

The mechanism for co-operation is currently undocumented: please contact us.

## 8.3. Signal handling issues

The MPS uses barriers(1) to protect memory from the client program and handles the signals that result from barrier hits.

Warning

The use of barriers has the consequence that a program that handles `SIGBUS` (on OS X), `SIGSEGV` (on FreeBSD or Linux), or first-chance exceptions (on Windows) needs to co-operate with the MPS.

The mechanism for co-operation is currently undocumented: please contact us.

## 8.4. Thread interface

`mps_thr_t`

  The type of registered thread descriptions.

  In a multi-threaded environment where incremental garbage collection is used, threads must be registered with the MPS by calling `mps_thread_reg()` so that the MPS can suspend them as necessary in order to have exclusive access to their state.

  Even in a single-threaded environment it may be necessary to register a thread with the MPS so that its stack can be registered as a root by calling `mps_root_create_reg()`.

mps_res_t `mps_thread_reg`(mps_thr_t *thr_o, mps_arena_t arena)

  Register the current thread with an arena.

  `thr_o` points to a location that will hold the address of the registered thread description, if successful.

  `arena` is the arena.

  Returns `MPS_RES_OK` if successful, or another result code if not.

  A thread must be registered with an arena if it ever uses a pointer to a location in an automatically managed pool belonging to that arena.

  Note

  It is recommended that all threads be registered with all arenas.

void `mps_thread_dereg`(mps_thr_t thr)

  Deregister a thread.

  `thr` is the description of the thread.

  After calling this function, the thread whose registration with an arena was recorded in `thr` must not read or write from a location in an automatically managed pool belonging to that arena.

  Note

  Some pool classes may be more liberal about what a thread may do after it has been deregistered. See the documentation for the pool class.

  Note

  It is recommended that threads be deregistered only when they are just about to exit.

void `mps_tramp`(void **r_o, mps_tramp_t f, void *p, size_t s)

  Deprecated

  starting with version 1.111.

  Call a function via the MPS trampoline.

  `r_o` points to a location that will store the result of calling `f`.

  `f` is the function to call.

  `p` and `s` are arguments that will be passed to `f` each time it is called. This is intended to make it easy to pass, for example, an array and its size as parameters.

  The MPS relies on barriers(1) to protect memory that is in an inconsistent state. On some operating systems, barrier hits generate exceptions that have to be caught by a handler that is on the stack. On these operating systems, any code that uses memory managed by the MPS must be called from inside such an exception handler, that is, inside a call to `mps_tramp()`.

  If you have multiple threads that run code that uses memory managed by the MPS, each thread must execute such code inside a call to `mps_tramp()`.

  Since version 1.111, this is not required on any of operating systems supported by the MPS.

void *`(*mps_tramp_t)`(void *p, size_t s)

  Deprecated

  starting with version 1.111.

  The type of a function called by `mps_tramp()`.

  `p` and `s` are the corresponding arguments that were passed to `mps_tramp()`.

### Navigation

- index
- next |
- previous |
- Memory Pool System 1.111.0 documentation »
- Reference »