qthread_spawn(3)
β¨ qthread_spawn(3) β the libqthread page bestie π
okay so. welcome to the manual page for qthread_spawn(3), which lives in libqthread, and which is genuinely the moment. sit down, grab a strawberry π, and let's get into it.
π NAME π
qthread_spawn β spawn a qthread (task). that's it, that's the whole vibe. you're making a task and you're putting it out into the world π
πΈ SYNOPSIS πΈ
#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);
look at her. eight whole arguments. she's an icon, she's a legend, and she IS the moment π
π DESCRIPTION π
okay so this is the master function for generating and scheduling new tasks. like, the mother of all spawners. every other function that spawns tasks β especially the ones whose names start with the string "qthread_fork" β is fundamentally just a convenience wrapper function around this one. they're all her little sisters. no cap π«Ά
f (the first argument) 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);
arg (second argument) is an argument for the function. the way this pointer gets treated depends entirely on the value of the third argument, arg_size:
- if
arg_sizeis zero, the pointer is passed to the functionfunchanged. no notes, just the raw pointer, walking in as-is. - if
arg_sizeis non-zero, thenarg_sizebytes will be copied fromargand stored in task-specific memory. this memory is usually pre-allocated (unlessarg_sizeis very large), so the performance is limited primarily by the speed ofmemcpy(). and whenfgets called, a pointer to the copy is passed as the argument tofinstead of the original value ofarg. it's giving "i made you a copy, bestie, you're safe" π
ret (fourth argument) 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. here's the tea:
- if the type is an
aligned_t, the return value location is emptied byqthread_spawn()and is stored by callingqthread_writeF()when the task returns. - if the type is a
syncvar_t, the return value location is emptied byqthread_spawn()and is stored by callingqthread_syncvar_writeF()when the task returns. - if the type is a
qt_sinc_t, when the task returns, the functionqt_sinc_submit()is called on the sinc. and if it's so configured (by passing the flagQTHREAD_SPAWN_RET_SINC_VOIDto thefeature_flagargument), the return value is submitted to the sinc.
npreconds and preconds (fifth and sixth arguments) are for creating "preconditioned" tasks, also sometimes referred to as "data-dependent" tasks or "triggered" tasks. so fancy of them. β¨
precondsis expected to be an array ofnprecondspointers either toaligned_t's orsyncvar_t's (depending on the flags passed to thefeature_flagargument).- 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.
π¨ bestie, seriously, that last one. undefined behavior is not a cute look. if your precondition can go back to empty before the spawn happens, all bets are off. periodt.
target_shep (seventh argument) specifies a destination shepherd for the task. the task will only ever execute on the specified shepherd unless that shepherd is disabled. if you want the task to be able to execute anywhere, use the pre-defined constant NO_SHEPHERD to specify the lack of preference. she's flexible like that π
feature_flag (eighth argument) is a way of passing additional flags to control task behavior. the available flags are as follows:
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). high risk, high reward, honestly.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 areadFF()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. it's giving group project, but make it synchronized π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. adjacent, but independent. we love boundaries π¦QTHREAD_SPAWN_RET_SYNCVAR_Tβ this flag specifies that the return value location,ret, points to asyncvar_t. this flag conflicts with otherQTHREAD_SPAWN_RET_*flags. if noQTHREAD_SPAWN_RET_*flags are specified, the return value location is assumed to point to analigned_t. choose one, bestie, don't be messy πQTHREAD_SPAWN_RET_SINCβ this flag specifies that the return value location,ret, points to aqt_sinc_t, and that the return value itself should be submitted to the sinc. this flag conflicts with otherQTHREAD_SPAWN_RET_*flags. if noQTHREAD_SPAWN_RET_*flags are specified, the return value location is assumed to point to analigned_t.QTHREAD_SPAWN_RET_SINC_VOIDβ this flag specifies that the return value location,ret, points to aqt_sinc_t, and that the return value itself should be ignored. this flag conflicts with otherQTHREAD_SPAWN_RET_*flags. if noQTHREAD_SPAWN_RET_*flags are specified, the return value location is assumed to point to analigned_t. return value said "not my problem" πQTHREAD_SPAWN_PC_SYNCVAR_Tβ this flag specifies that the precondition array,preconds, is an array of pointers tosyncvar_t's, rather thanaligned_t's. flip the switch, change the type, that's the whole flag π
π§ SPAWN CACHE π§
okay so here's the lore. 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. iykyk π₯
this cache can be disabled at configure time, in which case tasks are pushed into the globally visible scheduling queue as they are spawned. no waiting, no holding, just immediate main character energy β¨
π ENVIRONMENT π
the operation of these functions is modified by the following environment variables:
QTHREAD_STACK_SIZEβ this variable specifies, in bytes, 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 whenqthread_initialize()is run. so set it early or don't bother, bestie β
π RETURN VALUE π
on success, the thread is spawned and 0 is returned. on error, a non-zero error code is returned. slay when it's zero, cry when it's not π
π©· ERRORS π©·
ENOMEMβ not enough memory was available to spawn a task. the runtime is broke, respectfully. π
π SEE ALSO π
qthread_fork(3), qthread_migrate_to(3)
go read those too, they're the supporting cast and they ate π«Ά
and that's the page!! π
this was libqthread, and the page itself is dated AUGUST 2012 β yes, she's been iconic for that long and she's still serving. bye bestie, go spawn something responsibly πΈπ¦β¨
π¦ where this page comes from
- fedora 43: qthreads-devel 1.22^20251007gitcedb1fc-1.fc43 Β· BSD-3-Clause AND MIT AND dtoa
- fedora 44: qthreads-devel 1.22^20251007gitcedb1fc-2.fc44 Β· BSD-3-Clause AND MIT AND dtoa
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms