NAME
src/thread.c - Thread handling stuff
DESCRIPTION
Threads are created by creating new ParrotInterpreter
objects.
Functions
static PMC *make_local_copy
Creates a local copy of the PMC if necessary.
(No copy is made if it is marked shared.) This includes workarounds for Parrot_clone() not doing the Right Thing with subroutines (specifically,
code segments aren't preserved and it is difficult to do so as long as Parrot_clone() depends on freezing).
static Shared_gc_info *get_pool
Gets the shared gc information.
For now this is global data; ideally it will become something other than a static variable.
If everything uses this function,
it will be easier to change.
void pt_free_pool
Frees the shared GC information.
This clears any global data when joining all threads at parent interpreter destruction.
static PMC *make_local_args_copy
Make a local copy of the corresponding array of arguments.
PMC *pt_shared_fixup
Modifies a PMC to be sharable.
Right now,
reassigns the vtable to one owned by some master interpreter,
so the PMC can be safely reused after thread death.In the future the PMC returned might be different than the one passed,
e.g.,
if we need to reallocate the PMC in a different interpreter.
static void pt_thread_signal
Wakes up an void pt_thread_wait_with
Waits for this interpreter to be signalled through its condition variable,
dealing properly with GC issues.
static void pt_thread_wait
Waits for a signal,
handling GC matters correctly.
static void *thread_func
The actual thread function.
interp
which should have called pt_thread_wait().
*mutex
is assumed locked on entry and will be locked on exit from this function.
If a GC run occurs in the middle of this function,
then a spurious wakeup may occur.
interpreter_array_mutex
is assumed held.
Spurious wakeups may occur.
Helper functions used also for running plain interpreters
void pt_clone_code
Copies/clones the packfile/code from interpreter static void pt_ns_clone
Clones all globals from void pt_clone_globals
Copies the global namespace when cloning a new interpreter.
void pt_thread_prepare_for_run
Sets up a new thread to run.
s
to d
.
All resources are created in d
.
s
to d
.
ParrotThread methods
PMC *pt_transfer_sub
Clones the sub so that it's suitable for the other interpreter.
int pt_thread_run
Runs the int pt_thread_run_1
Runs a thread that shares nothing and does not communicate with the other interpreter.
int pt_thread_run_2
Runs an interpreter in a thread with no shared variables,
but which communicates by sending messages.
int pt_thread_run_3
Runs an interpreter in a thread,
allowing shared variables and using a thread pool.
void pt_thread_yield
Relinquishes hold on the processor.
static Parrot_Interp pt_check_tid
Helper function.
Checks if the given thread ID is valid.
The caller holds the mutex.
Returns the interpreter for static void mutex_unlock
Unlocks the mutex static int is_suspended_for_gc
Returns true iff static QUEUE_ENTRY *remove_queued_suspend_gc
Removes an event requesting that the interpreter suspend itself for a garbage-collection run from the event queue.
static int pt_gc_count_threads
Returns the number of active threads in the system (running or suspended).
Be sure to hold static void pt_gc_wait_for_stage
Waits until all threads have reached the desired stage.
Takes an interpreter,
starting stage and ending stage as arguments.
Updates the thread information.
Used in static void pt_gc_wakeup_check
Checks if it's necessary to wake threads to perform garbage collection.
This is called after thread death.
Be sure to hold static void pt_suspend_one_for_gc
Suspends a single interpreter for GC.
Be sure to hold static void pt_suspend_all_for_gc
Notifies all threads to perform a GC run.
void pt_suspend_self_for_gc
Suspends this thread for a full GC run.XXX FIXME -- if GC is blocked,
we need to do a GC run as soon as it becomes unblocked.
PMC *pt_thread_join
Joins (by waiting for) a joinable thread.
void pt_join_threads
Possibly waits for other running threads.
This is called when destroying static Parrot_Interp detach
Helper for detach and kill.Returns the interpreter,
if it didn't finish yet.
void pt_thread_detach
Detaches the thread,
making it non-joinable.
void pt_thread_kill
Kills the thread.
*sub
PMC in a separate thread using the interpreter in *dest_interp
.arg
should be an array of arguments for the subroutine.
tid
.
*arg
.
interp
is suspended for a global GC run.
Be sure to hold interpreter_array_mutex
.
interpreter_array_mutex
.
pt_gc_start_mark
and pt_gc_stop_mark
.
interpreter_array_mutex
.
interpreter_array_mutex
.
interp
.
Threaded interpreter book-keeping
void pt_add_to_interpreters
Stores the given interpreter in the array of all interpreters.
Be sure to hold
interpreter_array_mutex
.GC Synchronization Functions
void pt_gc_start_mark
Record that the mark phase of GC is about to begin.
In the presence of shared PMCs,
we can only run one GC run at a time because void pt_gc_mark_root_finished
Records that GC has finished for the root set.
EXCEPTION_UNIMPLEMENTED
void pt_gc_stop_mark
Records that the mark phase of GC has completed.
void Parrot_shared_gc_block
Blocks stop-the-world GC runs.
void Parrot_shared_gc_unblock
Unblocks stop-the-world GC runs.
PMC->next_for_GC
may be changed.flags
are the GC flags.
We check if we need to collect shared objects or not.TODO - Have a count of shared PMCs and check it during GC.TODO - Evaluate if a interpreter lock is cheaper when gc_mark_ptr
is updated.