Commit 94fe2b71 authored by Kunshan Wang's avatar Kunshan Wang

Added thread-local.

The thread-local object reference gives each thread a reference to an
arbitrary object, which can hold thread-local states. New API functions
and new (common) instructions are added. It is also a thread states and
a GC root.
parent 4e1c3202
......@@ -106,6 +106,18 @@ the **DEAD** state. The current thread stops running.
Return the current stack.
::
[0x205]@uvm.set_threadlocal (%ref: ref<void>)
Set the thread-local object reference of the current thread to ``%ref``.
::
[0x206]@uvm.get_threadlocal -> ref<void>
Return the current thread-local object reference of the current thread.
64-bit Tagged Reference
=======================
......
......@@ -238,9 +238,16 @@ struct MuCtx {
// Thread and stack creation and stack destruction
MuStackRefValue (*new_stack )(MuCtx *ctx, MuFuncRefValue func);
MuThreadRefValue (*new_thread)(MuCtx *ctx, MuStackRefValue stack,
MuHowToResume htr, MuValue *vals, int nvals, MuRefValue exc);
MuRefValue threadlocal,
MuHowToResume htr, MuValue *vals, int nvals,
MuRefValue exc);
void (*kill_stack)(MuCtx *ctx, MuStackRefValue stack);
// Thread-local object reference
void (*set_threadlocal)(MuCtx *ctx, MuThreadRefValue thread,
MuRefValue threadlocal);
MuRefValue (*get_threadlocal)(MuCtx *ctx, MuThreadRefValue thread);
// Frame cursor operations
MuFCRefValue (*new_cursor )(MuCtx *ctx, MuStackRefValue stack);
void (*next_frame )(MuCtx *ctx, MuFCRefValue cursor);
......
......@@ -62,6 +62,44 @@ stack) or terminates after returning from the trap handler.
TODO: https://github.com/microvm/microvm-meta/issues/42 Extend the unbinding
to undefined function handling.
State of Threads
================
The state of a thread include:
- the *stack* it is bound to (explained in this chapter)
- a *thread-local object reference* (see below)
- a thread-local *pinning multi-set* (see `object pinning
<native-interface.rest#pinning>`__)
NOTE: Implementations may keep more thread-local states, such as the
thread-local memory pool for the garbage collector. They are implementation
details.
The **thread-local object reference** is an arbitrary object reference, and can
be ``NULL``. It is initialised when a thread is created. It can be read and
modified by the thread itself. It can also be read and modified by the client in
the trap handler, but the trap handler can only read and modify the thread-local
object reference of the thread that triggered the trap. It cannot be read or
modified in any other ways.
NOTE: This design ensures that:
1. The access to the thread-local object reference itself is data-race-free.
2. It is only a single object reference, so the reference can fit in a
machine register. In this way, if the implementation reserves a register
for that reference, accessing fields in the object it refers to can be as
efficient as register-indexed addressing.
It also off-loads the responsibility of resizing or redefining the
thread-local object to the client. If the client wishes to add more fields
to that object (e.g. when more bundles are loaded), it can use watchpoints
to stop existing threads and replace their thread-local object references in
the trap handler.
States of Stacks and Frames
===========================
......
......@@ -669,9 +669,15 @@ Stack and thread operations
MuStackRefValue (*new_stack )(MuCtx *ctx, MuFuncRefValue func);
MuThreadRefValue (*new_thread)(MuCtx *ctx, MuStackRefValue stack,
MuHowToResume htr, MuValue *vals, int nvals, MuRefValue exc);
MuRefValue threadlocal,
MuHowToResume htr, MuValue *vals, int nvals,
MuRefValue exc);
void (*kill_stack)(MuCtx *ctx, MuStackRefValue stack);
void (*set_threadlocal)(MuCtx *ctx, MuThreadRefValue thread,
MuRefValue threadlocal);
MuRefValue (*get_threadlocal)(MuCtx *ctx, MuThreadRefValue thread);
typedef int MuHowToResume;
#define MU_REBIND_PASS_VALUES 0x01
#define MU_REBIND_THROW_EXC 0x02
......@@ -695,6 +701,10 @@ are
In either case, the ignored MuValue arguments can be the C ``NULL`` pointer.
The ``threadlocal`` parameter is the initial thread-local reference of the new
thread. If it is a C ``NULL`` pointer, it is equivalent to a Mu ``NULL`` object
reference.
``kill_stack`` kills the ``stack``. The stack must be in the **READY<Ts>** state
for some *Ts*. The stack enters the **DEAD** state. If the stack contains
native frames, the behaviour is implementation-defined.
......@@ -712,6 +722,15 @@ native frames, the behaviour is implementation-defined.
message does not unwind the stack. It simply marks the whole stack for
deletion.
``set_threadlocal`` sets the thread-local object reference of the ``thread``
argument to ``threadlocal``.
``get_threadlocal`` returns the current thread-local object reference of
``thread``.
Both ``get_threadlocal`` and ``set_threadlocal`` can only be used in the trap
handler and only on the thread that caused the trap.
Stack introspection
-------------------
......
......@@ -159,6 +159,7 @@ A **root** is an object reference or internal reference in:
* any global cell, or
* any bound Mu stacks, or
* the thread-local object reference in any threads, or
* any values held by any client contexts in the API.
A live stack contains references in its alloca cells and live local SSA
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment