qthread_init(3)

πŸ“¦ version 1.22^20251007gitcedb1fc, in fedora 43, fedora 44

πŸ’– qthread_init β€” bestie edition πŸ’–

okay so this is a page from the libqthread manual (that's the manual name, and the page is qthread_init(3), iykyk), and we're about to make your whole qthreads situation make sense. grab a boba, we're going in πŸ§‹βœ¨


🌸 NAME 🌸

qthread_init, qthread_initialize β€” the two functions that wake the qthread library up so it can actually do stuff πŸ’…


✨ SYNOPSIS ✨

#include <qthread.h>

int
qthread_init (qthread_shepherd_id_t nshepherds);

int
qthread_initialize ();

like. look at them. two little functions. one of them is lowkey deprecated. we'll get there 🫢


πŸ‘‘ DESCRIPTION πŸ‘‘

okay so here's the tea: you use these functions to initialize the qthreads environment before you touch literally any other qthread function. no cap, this is the "hello are you awake" step. πŸŒ…

so qthread_init() is deprecated β€” not cancelled, just... deprecated β€” in favor of qthread_initialize(), which will attempt to auto-detect the correct number of shepherds for your system. she's smart like that. 🧠✨

but you can still forcibly specify the number of shepherds with the environment variable QTHREAD_NUM_SHEPHERDS. forceful. we love a decisive queen.

qthread_init() is literally just a wrapper around qthread_initialize() that exports the QTHREAD_NUM_SHEPHERDS environment variable. that's it. that's the whole job. and honestly? iconic.

if QTHREAD_NUM_SHEPHERDS is 0 or unset, the library will try to guess the correct number of shepherds, and if it can't find any information about the system it defaults to a single shepherd. one lonely little shepherd. it's giving main character energy, but sad. 😭

also! shepherds will attempt to pin themselves to processors using whatever CPU affinity libraries happen to be available. they're claiming their territory. πŸ¦‹


🌈 ENVIRONMENT 🌈

the operation of qthread_init() is modified by several environment variables. and here's a cute little detail: all environment variables may begin with either QTHREAD_ or QT_ β€” Qthreads treats them the same. same vibe, different prefix. πŸ’œ

the following environment variables may be considered (and no, not all of them apply to all environments, so don't come for me):

  • QTHREAD_INFO β€” this one controls what kind of status info gets printed during initialization. set it to "1" and Qthreads prints the number of shepherds, the number of workers per shepherd, and the stack size of each qthread to stdout. set it to "2" and it additionally prints the name and value of every environment variable it checks. yes, every single one. it's a whole gossip session. πŸ‘€
  • QTHREAD_AFFINITY β€” set this to "no" and the shepherds will not pin themselves to specific locations. they're free-range now. πŸ“
  • QTHREAD_STACK_SIZE β€” 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 considered when qthread_init() is run. set it early or don't set it at all, bestie.
  • QTHREAD_NUM_SHEPHERDS β€” specifies how many shepherds to create. that's it. that's the whole thing. πŸ‘
  • QTHREAD_NUM_WORKERS_PER_SHEPHERD β€” specifies how many worker threads to assign to each shepherd. heads up: this setting is ignored by some schedulers that only allow one worker per shepherd. they're monogamous like that. πŸ’€
  • QTHREAD_HWPAR β€” specifies how much hardware parallelism to use. it lets the number of shepherds and worker threads per shepherd be chosen according to the machine topology while only specifying how many may be running. if this number doesn't divide evenly among the appropriate number of shepherds, extra workers will be created but will begin in a disabled state. they're on the bench. πŸ™ˆ
  • QTHREAD_ARGCOPY_SIZE β€” controls the amount of memory preallocated for storing argument data per task. not all tasks have memory preallocated for argument data, but when they do, this variable controls the amount. ✨
  • QTHREAD_TASKLOCAL_SIZE β€” similar to the previous variable, but instead of argument data, it controls the size of the preallocated per-task scratchpad. πŸ“
  • QTHREAD_STEAL_CHUNK β€” applies to certain work-stealing schedulers (like the default Sherwood scheduler 🏹) and controls the number of tasks stolen during load-balancing operations. by default, or when this variable is set to zero, half of the victim's work is stolen. otherwise, thief workers will attempt to steal at most this many tasks. thief behavior. we respect it. πŸ₯·
  • QTHREAD_MAX_IO_WORKERS β€” controls the maximum number of threads that can be spawned to service the I/O subsystem's queue. in effect, it limits the amount of OS overhead that the I/O subsystem can consume. put a cap on it. 🧒
  • QTHREAD_IO_TIMEOUT β€” controls how long each I/O subsystem thread will wait for additional work before exiting. patience is a virtue but it does run out. ⏳
  • QTHREAD_SHEPHERD_BOUNDARY β€” used to control shepherd affinity. essentially, it sets the physical boundary that the shepherd will represent. currently only used when using the hwloc library. valid values are: node, cache, socket, core, pu, L1cache, L2cache, L3cache, and L4cache. pick your fighter. πŸ₯Š
  • QTHREAD_WORKER_UNIT β€” used to control worker thread affinity; essentially it controls worker spacing. for example, one could force a single shepherd to cover a whole node with the QTHREAD_SHEPHERD_BOUNDARY, and then use this variable to put one worker on each socket. the valid values are the same as for QTHREAD_SHEPHERD_BOUNDARY, but this one MUST be lower in the topology hierarchy than the shepherd boundary. the default is "pu". lowercase pu. don't forget. 🫢

πŸŽ€ RETURN VALUE πŸŽ€

on success, the system is ready to fork threads and 0 is returned. πŸŽ‰

on error, a non-zero error code is returned. 😭


πŸ’€ ERRORS πŸ’€

  • ENOMEM β€” not enough memory could be allocated. the vibes were there but the RAM was not. πŸͺ¦

🌟 SEE ALSO 🌟

qthread_finalize(3) β€” the part where you say goodbye. πŸ₯Ή


and that's the page, bestie!! no cap, you're now officially qualified to initialize a thread library. πŸ’…βœ¨

this came from the libqthread source, version dated NOVEMBER 2006 β€” yes, 2006, she's vintage and she still slays πŸŽ€πŸ¦‹πŸ’–

πŸ“¦ where this page comes from