package core:thread

⌘K
Ctrl+K
or
/

    Types

    Pool ¶

    Pool :: struct {
    	allocator:         runtime.Allocator,
    	mutex:             sync.Mutex,
    	sem_available:     sync.Sema,
    	// the following values are atomic
    	num_waiting:       int,
    	num_in_processing: int,
    	num_outstanding:   int,
    	// num_waiting + num_in_processing
    	num_done:          int,
    	// called once per thread at startup
    	thread_init_proc:  Thread_Init_Proc,
    	thread_init_data:  rawptr,
    	// called once per thread at shutdown
    	thread_fini_proc:  Thread_Fini_Proc,
    	thread_fini_data:  rawptr,
    	is_running:        bool,
    	threads:           []^Thread,
    	tasks:             container_queue.Queue($T=Task),
    	tasks_done:        [dynamic]Task,
    }
     

    Do not access the pool's members directly while the pool threads are running, since they use different kinds of locking and mutual exclusion devices. Careless access can and will lead to nasty bugs. Once initialized, the pool's memory address is not allowed to change until it is destroyed.

    Related Procedures With Parameters

    Pool_Thread_Data ¶

    Pool_Thread_Data :: struct {
    	pool: ^Pool,
    	task: Task,
    }

    Task ¶

    Task :: struct {
    	procedure:  Task_Proc,
    	data:       rawptr,
    	user_index: int,
    	allocator:  runtime.Allocator,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    Task_Proc ¶

    Task_Proc :: proc(task: Task)
    Related Procedures With Parameters

    Thread ¶

    Thread :: struct {
    	using specific:     Thread_Os_Specific,
    	flags:              bit_set[Thread_State; u8],
    	// Thread ID. Depending on the platform, may start out as 0 (zero) until the thread
    	// has had a chance to run.
    	id:                 int,
    	// The thread procedure.
    	procedure:          Thread_Proc,
    	// User-supplied pointer, that will be available to the thread once it is
    	// started. Should be set after the thread has been created, but before
    	// it is started.
    	data:               rawptr,
    	// Thread's Name/Description that will get set during thread creation
    	// it will be set using init_context's allocator to allocate and free a cstring buffer
    	// for thread's creation only : do not refer to it, use thread.get_name instead
    	name:               runtime.Maybe($T=string),
    	// User-supplied integer, that will be available to the thread once it is
    	// started. Should be set after the thread has been created, but before
    	// it is started.
    	user_index:         int,
    	// User-supplied array of arguments, that will be available to the thread,
    	// once it is started. Should be set after the thread has been created,
    	// but before it is started.
    	user_args:          [8]rawptr,
    	// The thread context.
    	// This field can be assigned to directly, after the thread has been
    	// created, but __before__ the thread has been started. This field must
    	// not be changed after the thread has started.
    	// 
    	// **Note**: If this field is **not** set, the temp allocator will be managed
    	// automatically. If it is set, the allocators must be handled manually.
    	// 
    	// **IMPORTANT**:
    	// By default, the thread proc will get the same context as `main()` gets.
    	// In this situation, the thread will get a new temporary allocator which
    	// will be cleaned up when the thread dies. ***This does NOT happen when
    	// `init_context` field is initialized***.
    	// 
    	// If `init_context` is initialized, and `temp_allocator` field is set to
    	// the default temp allocator, then `runtime.default_temp_allocator_destroy()`
    	// procedure needs to be called from the thread procedure, in order to prevent
    	// any memory leaks.
    	init_context:       runtime.Maybe($T=Context),
    	// The allocator used to allocate data for the thread.
    	creation_allocator: runtime.Allocator,
    }
     

    Type representing a thread handle and the associated with that thread data.

    Related Procedures With Parameters
    Related Procedures With Returns

    Thread_Fini_Proc ¶

    Thread_Fini_Proc :: proc(thread: ^Thread, user_data: rawptr)

    Thread_Init_Proc ¶

    Thread_Init_Proc :: proc(thread: ^Thread, user_data: rawptr)
    Related Procedures With Parameters

    Thread_Os_Specific ¶

    Thread_Os_Specific :: struct {}

    Thread_Proc ¶

    Thread_Proc :: proc(^Thread)
     

    Type for a procedure that will be run in a thread, after that thread has been started.

    Related Procedures With Parameters

    Thread_State ¶

    Thread_State :: enum u8 {
    	Started, 
    	Joined, 
    	Done, 
    	Self_Cleanup, 
    }
     

    Type representing the state/flags of the thread.

    Constants

    IS_SUPPORTED ¶

    IS_SUPPORTED :: _IS_SUPPORTED
     

    Value, specifying whether core:thread functionality is available on the current platform.

    MAX_USER_ARGUMENTS ¶

    MAX_USER_ARGUMENTS :: 8
     

    Maximum number of user arguments for polymorphic thread procedures.

    Variables

    This section is empty.

    Procedures

    create ¶

    create :: proc(procedure: Thread_Proc, priority: Thread_Priority = Thread_Priority.Normal, name: runtime.Maybe($T=string) = nil) -> ^Thread {…}

    create_and_start ¶

    create_and_start :: proc(fn: proc(), init_context: runtime.Maybe($T=Context) = nil, priority: Thread_Priority = Thread_Priority.Normal, self_cleanup: bool = false, name: runtime.Maybe($T=string) = nil) -> (t: ^Thread) {…}
     

    Run a procedure on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    If self_cleanup is specified, after the thread finishes the execution of the fn procedure, the resources associated with the thread are going to be automatically freed.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    Do not dereference the ^Thread pointer, if this flag is specified. That includes calling join, which needs to dereference ^Thread`.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    create_and_start_with_data ¶

    create_and_start_with_data :: proc(
    	data:         rawptr, 
    	fn:           proc(data: rawptr), 
    	init_context: runtime.Maybe($T=Context) = nil, 
    	priority:     Thread_Priority = Thread_Priority.Normal, 
    	self_cleanup: bool = false, 
    	name:         runtime.Maybe($T=string) = nil, 
    ) -> (t: ^Thread) {…}
     

    Run a procedure with one pointer parameter on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    If self_cleanup is specified, after the thread finishes the execution of the fn procedure, the resources associated with the thread are going to be automatically freed.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    Do not dereference the ^Thread pointer, if this flag is specified. That includes calling join, which needs to dereference ^Thread`.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    create_and_start_with_poly_data ¶

    create_and_start_with_poly_data :: proc(
    	data:         $T, 
    	fn:           proc(data: $T), 
    	init_context: runtime.Maybe($T=Context) = nil, 
    	priority:     Thread_Priority = Thread_Priority.Normal, 
    	self_cleanup: bool = false, 
    	name:         runtime.Maybe($T=string) = nil, 
    ) -> (t: ^Thread) {…}
     

    Run a procedure with one polymorphic parameter on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    If self_cleanup is specified, after the thread finishes the execution of the fn procedure, the resources associated with the thread are going to be automatically freed.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    Do not dereference the ^Thread pointer, if this flag is specified. That includes calling join, which needs to dereference ^Thread`.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    create_and_start_with_poly_data2 ¶

    create_and_start_with_poly_data2 :: proc(
    	arg1:         $T1, 
    	arg2:         $T2, 
    	fn:           proc($T1, $T2), 
    	init_context: runtime.Maybe($T=Context) = nil, 
    	priority:     Thread_Priority = Thread_Priority.Normal, 
    	self_cleanup: bool = false, 
    	name:         runtime.Maybe($T=string) = nil, 
    ) -> (t: ^Thread) {…}
     

    Run a procedure with two polymorphic parameters on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    If self_cleanup is specified, after the thread finishes the execution of the fn procedure, the resources associated with the thread are going to be automatically freed.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    Do not dereference the ^Thread pointer, if this flag is specified. That includes calling join, which needs to dereference ^Thread`.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    create_and_start_with_poly_data3 ¶

    create_and_start_with_poly_data3 :: proc(
    	arg1:         $T1, 
    	arg2:         $T2, 
    	arg3:         $T3, 
    	fn:           proc(arg1: $T1, arg2: $T2, arg3: $T3), 
    	init_context: runtime.Maybe($T=Context) = nil, 
    	priority:     Thread_Priority = Thread_Priority.Normal, 
    	self_cleanup: bool = false, 
    	name:         runtime.Maybe($T=string) = nil, 
    ) -> (t: ^Thread) {…}
     

    Run a procedure with three polymorphic parameters on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    If self_cleanup is specified, after the thread finishes the execution of the fn procedure, the resources associated with the thread are going to be automatically freed.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    Do not dereference the ^Thread pointer, if this flag is specified. That includes calling join, which needs to dereference ^Thread`.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    create_and_start_with_poly_data4 ¶

    create_and_start_with_poly_data4 :: proc(
    	arg1:         $T1, 
    	arg2:         $T2, 
    	arg3:         $T3, 
    	arg4:         $T4, 
    	fn:           proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4), 
    	init_context: runtime.Maybe($T=Context) = nil, 
    	priority:     Thread_Priority = Thread_Priority.Normal, 
    	self_cleanup: bool = false, 
    	name:         runtime.Maybe($T=string) = nil, 
    ) -> (t: ^Thread) {…}
     

    Run a procedure with four polymorphic parameters on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    If self_cleanup is specified, after the thread finishes the execution of the fn procedure, the resources associated with the thread are going to be automatically freed.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    Do not dereference the ^Thread pointer, if this flag is specified. That includes calling join, which needs to dereference ^Thread`.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    destroy ¶

    destroy :: proc(thread: ^Thread) {…}
     

    Wait for the thread to finish and free all data associated with it.

    get_name ¶

    get_name :: proc(thread: ^Thread = nil, allocator := context.temp_allocator, loc := #caller_location) -> (string, runtime.Allocator_Error) {…}
     

    Get thread's name/description.

    This procedure returns the name of the given thread. If thread is nil, this procedure returns the name of the calling thread. OS level errors are silently ignored.

    Note(linux, bsd): Because the thread name is stored in as the cmdline, if the thread name was not set, the command that has been used to create the process will be used as the name of the thread.

    allocates memory for the returned string using provided allocator.

    is_done ¶

    is_done :: proc(thread: ^Thread) -> bool {…}
     

    Check if the thread has finished work.

    join ¶

    join :: proc(thread: ^Thread) {…}
     

    Wait for the thread to finish work.

    join_multiple ¶

    join_multiple :: proc(threads: ..^Thread) {…}
     

    Wait for all threads to finish work.

    pool_add_task ¶

    pool_add_task :: proc(pool: ^Pool, allocator: runtime.Allocator, procedure: Task_Proc, data: rawptr, user_index: int = 0) {…}
     

    Add a task to the thread pool.

    Tasks can be added from any thread, not just the thread that created the thread pool. You can even add tasks from inside other tasks.

    Each task also needs an allocator which it either owns, or which is thread safe.

    Completed tasks remain in the pool until removed with pool_pop_done. When reusing the pool, call it once for every task added.

    pool_destroy ¶

    pool_destroy :: proc(pool: ^Pool) {…}

    pool_do_work ¶

    pool_do_work :: proc(pool: ^Pool, task: Task) {…}
     

    Mostly for internal use.

    pool_finish ¶

    pool_finish :: proc(pool: ^Pool) {…}
     

    Process the rest of the tasks, also use this thread for processing, then join all the pool threads.

    Completed tasks are not removed. Retrieve each one with pool_pop_done. The pool cannot be restarted after this procedure returns.

    pool_init ¶

    pool_init :: proc(
    	pool:         ^Pool, 
    	allocator:    runtime.Allocator, 
    	thread_count: int, 
    	init_proc:    Thread_Init_Proc = nil, 
    	init_data:    rawptr = nil, 
    	fini_proc:    Thread_Init_Proc = nil, 
    	fini_data:    rawptr = nil, 
    ) {…}
     

    Once initialized, the pool's memory address is not allowed to change until it is destroyed.

    The thread pool requires an allocator which it either owns, or which is thread safe.

    pool_is_empty ¶

    pool_is_empty :: proc(pool: ^Pool) -> bool {…}
     

    If tasks are only being added from one thread, and this procedure is being called from that same thread, it will reliably tell if the thread pool is empty or not. Empty in this case means there are no tasks waiting, being processed, or _done_.

    pool_join ¶

    pool_join :: proc(pool: ^Pool) {…}
     

    Finish tasks that have already started processing, then shut down all pool threads. Might leave over waiting tasks, any memory allocated for the user data of those tasks will not be freed.

    pool_num_done ¶

    pool_num_done :: proc(pool: ^Pool) -> int {…}
     

    Number of tasks which are done processing. Only informational, mostly for debugging. Don't rely on this value being consistent with other num_* values.

    pool_num_in_processing ¶

    pool_num_in_processing :: proc(pool: ^Pool) -> int {…}
     

    Number of tasks currently being processed. Only informational, mostly for debugging. Don't rely on this value being consistent with other num_* values.

    pool_num_outstanding ¶

    pool_num_outstanding :: proc(pool: ^Pool) -> int {…}
     

    Outstanding tasks are all tasks that are not done, that is, tasks that are waiting, as well as tasks that are currently being processed. Only informational, mostly for debugging. Don't rely on this value being consistent with other num_* values.

    pool_num_waiting ¶

    pool_num_waiting :: proc(pool: ^Pool) -> int {…}
     

    Number of tasks waiting to be processed. Only informational, mostly for debugging. Don't rely on this value being consistent with other num_* values.

    pool_pop_done ¶

    pool_pop_done :: proc(pool: ^Pool) -> (task: Task, got_task: bool) {…}
     

    Remove and return the next completed task, if one is available.

    The caller is responsible for processing the result and releasing any resources associated with the task.

    pool_pop_waiting ¶

    pool_pop_waiting :: proc(pool: ^Pool) -> (task: Task, got_task: bool) {…}
     

    Mostly for internal use.

    pool_shutdown ¶

    pool_shutdown :: proc(pool: ^Pool, exit_code: int = 1) {…}
     

    Force the pool to stop all of its threads and put it into a state where it will no longer run any more tasks.

    The pool must still be destroyed after this.

    pool_start ¶

    pool_start :: proc(pool: ^Pool) {…}

    pool_stop_all_tasks ¶

    pool_stop_all_tasks :: proc(pool: ^Pool, exit_code: int = 1) {…}
     

    Forcibly stop all running tasks.

    The same notes from pool_stop_task apply here.

    pool_stop_task ¶

    pool_stop_task :: proc(pool: ^Pool, user_index: int, exit_code: int = 1) -> bool {…}
     

    Forcibly stop a running task by its user index.

    This will terminate the underlying thread. Ideally, you should use some means of communication to stop a task, as thread termination may leave resources unclaimed.

    The thread will be restarted to accept new tasks.

    Returns true if the task was found and terminated.

    run ¶

    run :: proc(fn: proc(), init_context: runtime.Maybe($T=Context) = nil, priority: Thread_Priority = Thread_Priority.Normal, name: runtime.Maybe($T=string) = nil) {…}
     

    Run a procedure on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    run_with_data ¶

    run_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_context: runtime.Maybe($T=Context) = nil, priority: Thread_Priority = Thread_Priority.Normal, name: runtime.Maybe($T=string) = nil) {…}
     

    Run a procedure with one pointer parameter on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    run_with_poly_data ¶

    run_with_poly_data :: proc(data: $T, fn: proc(data: $T), init_context: runtime.Maybe($T=Context) = nil, priority: Thread_Priority = Thread_Priority.Normal, name: runtime.Maybe($T=string) = nil) {…}
     

    Run a procedure with one polymorphic parameter on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    run_with_poly_data2 ¶

    run_with_poly_data2 :: proc(
    	arg1:         $T1, 
    	arg2:         $T2, 
    	fn:           proc($T1, $T2), 
    	init_context: runtime.Maybe($T=Context) = nil, 
    	priority:     Thread_Priority = Thread_Priority.Normal, 
    	name:         runtime.Maybe($T=string) = nil, 
    ) {…}
     

    Run a procedure with two polymorphic parameters on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    run_with_poly_data3 ¶

    run_with_poly_data3 :: proc(
    	arg1:         $T1, 
    	arg2:         $T2, 
    	arg3:         $T3, 
    	fn:           proc(arg1: $T1, arg2: $T2, arg3: $T3), 
    	init_context: runtime.Maybe($T=Context) = nil, 
    	priority:     Thread_Priority = Thread_Priority.Normal, 
    	name:         runtime.Maybe($T=string) = nil, 
    ) {…}
     

    Run a procedure with three polymorphic parameters on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    run_with_poly_data4 ¶

    run_with_poly_data4 :: proc(
    	arg1:         $T1, 
    	arg2:         $T2, 
    	arg3:         $T3, 
    	arg4:         $T4, 
    	fn:           proc(arg1: $T1, arg2: $T2, arg3: $T3, arg4: $T4), 
    	init_context: runtime.Maybe($T=Context) = nil, 
    	priority:     Thread_Priority = Thread_Priority.Normal, 
    	name:         runtime.Maybe($T=string) = nil, 
    ) {…}
     

    Run a procedure with four polymorphic parameters on a different thread.

    This procedure runs the given procedure on another thread. The context specified by init_context will be used as the context in which fn is going to execute. The thread will have priority specified by the priority parameter.

    Optionally specify the thread's name/description. the name/description will be truncated to fit the OS's limit.

    IMPORTANT: If init_context is specified and the default temporary allocator is used, the thread procedure needs to call runtime.default_temp_allocator_destroy() in order to free the resources associated with the temporary allocations.

    start ¶

    start :: proc(thread: ^Thread) {…}
     

    Start a suspended thread.

    terminate ¶

    terminate :: proc(thread: ^Thread, exit_code: int) {…}
     

    Forcibly terminate a running thread.

    yield ¶

    yield :: proc() {…}
     

    Yield the execution of the current thread to another OS thread or process.

    Procedure Groups

    This section is empty.

    Source Files

    Generation Information

    Generated with odin version dev-2026-08 (vendor "odin") Windows_amd64 @ 2026-08-08 21:20:28.067961100 +0000 UTC