Table of Contents
qthread_spawn - spawn a qthread (task)
#include <qthread.h>
int
qthread_spawn (qthread_f f,
const void *arg,
size_t arg_size,
void *ret,
size_t npreconds,
void *preconds,
qthread_shepherd_id_t target_shep,
unsigned int feature_flags);
This is the master function
for generating and scheduling new tasks. All other functions that spawn
tasks, particularly those beginning with the string "qthread_fork", are
fundamentally convenience wrapper functions around this function.
The first
argument, f, is a function that will be run to completion as the created
task. The qthread_f function must have a prototype like this:
aligned_t
function(void *arg);
The second argument, arg, is an argument for the function.
The treatment of this pointer depends on the value of the third argument,
arg_size. If arg_size is zero, the pointer will be passed to the function
f unchanged. However, if arg_size is non-zero, then arg_size bytes will be
copied from arg and stored in task-specific memory. This memory is usually
pre-allocated (unless arg_size is very large), so the performance is limited
primarily by the speed of memcpy(). When f is called, a pointer to the copy
will be passed as the argument to f instead of the original value of arg.
The fourth argument, ret, is a pointer indicating where to store the return
value of f. This location may be an aligned_t, a syncvar_t, or a qt_sinc_t,
and the type is indicated with flags passed in the feature_flags argument.
The location may also be NULL. If the type is an aligned_t, the return value
location is emptied by qthread_spawn() and is stored by calling qthread_writeF()
when the task returns. If the type is a syncvar_t, the return value location
is emptied by qthread_spawn() and is stored by calling qthread_syncvar_writeF()
when the task returns. If the type is a qt_sinc_t, when the task returns,
the function qt_sinc_submit() is called on the sinc. If so configured (by
passing the flag QTHREAD_SPAWN_RET_SINC_VOID to the feature_flag argument),
return value is submitted to the sinc.
The fifth and sixth arguments, npreconds
and preconds, are for creating "preconditioned" tasks, also sometimes referred
to as "data-dependent" tasks or "triggered" tasks. The preconds argument
is expected to be an array of npreconds pointers either to aligned_t’s or
syncvar_t’s (depending on the flags passed to the feature_flag argument).
The task will be scheduled only when all of the preconditions have been
in the relevant "full" state at least once. The preconditions are queried
in an undefined order, so preconditions that can return to the empty state
before the task is spawned create undefined behavior.
The seventh argument,
target_shep, specifies a destination shepherd for the task. The task will
only ever execute on the specified shepherd unless that shepherd is disabled.
If the task should be able to execute anywhere, use the pre-defined constant
NO_SHEPHERD to specify the lack of preference.
The eighth argument, feature_flag,
is a way of passing additional flags to control task behavior. The available
flags are as follows:
- QTHREAD_SPAWN_FUTURE
- This flag specifies that the
task spawned is to be considered a resource-limited task. This is equivalent
to the future_fork() function and requires that the future system has been
initialized.
- QTHREAD_SPAWN_PARENT
- This flag only has meaning if the ROSE
OpenMP interface has been enabled. It specifies that the task spawned is
a parent task, and alters how task tracking happens for OpenMP taskwait
operations.
- QTHREAD_SPAWN_SIMPLE
- This flag specifies that the task spawned
will not block. Violations of this promise will cause the program to abort.
In exchange for making this promise, the runtime can avoid a great deal
of context-swap overhead and can provide the task with much more stack space
for "free" (it uses the worker thread’s stack).
- QTHREAD_SPAWN_NEW_TEAM
- Tasks
are, by default, spawned into their parent’s team. This flag specifies that
the spawned task will be the founding member of a new task team and not
a member of the calling task’s team. Task teams are collections of tasks.
Any task that performs a readFF() operation on the return value location
of a task that is the founding member of a task team will not be unblocked
until all of the tasks in that team also return.
- QTHREAD_SPAWN_NEW_SUBTEAM
- This flag specifies that the spawned task will be the founding member of
a new task team that is dependent upon the calling task’s team, but not
a member of the calling task’s team.
- QTHREAD_SPAWN_RET_SYNCVAR_T
- This flag
specifies that the return value location, ret, points to a syncvar_t. This
flag conflicts with other QTHREAD_SPAWN_RET_* flags. If no QTHREAD_SPAWN_RET_*
flags are specified, the return value location is assumed to point to an
aligned_t.
- QTHREAD_SPAWN_RET_SINC
- This flag specifies that the return value
location, ret, points to a qt_sinc_t, and that the return value itself
should be submitted to the sinc. This flag conflicts with other QTHREAD_SPAWN_RET_*
flags. If no QTHREAD_SPAWN_RET_* flags are specified, the return value location
is assumed to point to an aligned_t.
- QTHREAD_SPAWN_RET_SINC_VOID
- This flag
specifies that the return value location, ret, points to a qt_sinc_t, and
that the return value itself should be ignored. This flag conflicts with
other QTHREAD_SPAWN_RET_* flags. If no QTHREAD_SPAWN_RET_* flags are specified,
the return value location is assumed to point to an aligned_t.
- QTHREAD_SPAWN_PC_SYNCVAR_T
- This flag specifies that the precondition array, preconds, is an array
of pointers to syncvar_t’s, rather than aligned_t’s.
Tasks are
normally spawned into a thread-local cache of tasks. The contents of this
cache are not visible to other tasks until the next scheduling event, at
which point the cache is flushed into the local shepherd’s globally visible
scheduling queue. Scheduling events are times when the scheduling queue
must be checked, namely, when the current task either blocks or yields.
This cache can be disabled at configure time, in which case, tasks are
pushed into the globally visible scheduling queue as they are spawned.
The operation of these functions is modified by the following
environment variables:
- QTHREAD_STACK_SIZE
- This variable adjusts the size
of the stacks that will be created for each thread. Changes to this value
during the course of the program run are ignored; the value is only evaluated
when qthread_initialize() is run.
On success, the thread is
spawned and 0 is returned. On error, a non-zero error code is returned.
- ENOMEM
- Not enough memory was available to spawn a task.
qthread_fork(3)
,
qthread_migrate_to(3)
Table of Contents