Multi-threading operations to spawn threads and thread pools.

Collection Info

View Source
Collection
core
Path
thread
Entries
50

Source Files

Constants

2

IS_SUPPORTED #

Source
IS_SUPPORTED :: _IS_SUPPORTED

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

MAX_USER_ARGUMENTS #

Source
MAX_USER_ARGUMENTS :: 8

Maximum number of user arguments for polymorphic thread procedures.

Types

11

Pool #

Source
Pool :: Pool

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.

Thread #

Source
Thread :: Thread

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

Thread_Proc #

Source
Thread_Proc :: Thread_Proc

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

Procedures

37

create #

Source
create :: proc(procedure: Thread_Proc, priority: Thread_Priority = Thread_Priority.Normal) -> ^Thread {…}

Create a thread in a suspended state with the given priority. This procedure creates a thread that will be set to run the procedure specified by `procedure` parameter with a specified priority. The returned thread will be in a suspended state, until `start()` procedure is called. To start the thread, call `start()`. Also the `create_and_start()` procedure can be called to create and start the thread immediately.

create_and_start #

Source
create_and_start :: proc(fn: proc(), init_context: Maybe($T=Context) = nil, priority: Thread_Priority = Thread_Priority.Normal, self_cleanup: bool = false) -> (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. **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 #

Source
create_and_start_with_data :: proc(data: rawptr, fn: proc(data: rawptr), init_context: Maybe($T=Context) = nil, priority: Thread_Priority = Thread_Priority.Normal, self_cleanup: bool = false) -> (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. **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 #

Source
create_and_start_with_poly_data :: proc(data: $T, fn: proc(data: $T), init_context: Maybe($T=Context) = nil, priority: Thread_Priority = Thread_Priority.Normal, self_cleanup: bool = false) -> (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. **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 #

Source
create_and_start_with_poly_data2 :: proc(
	arg1:         $T1, 
	arg2:         $T2, 
	fn:           proc($T1, $T2), 
	init_context: Maybe($T=Context) = nil, 
	priority:     Thread_Priority = Thread_Priority.Normal, 
	self_cleanup: bool = false, 
) -> (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. **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 #

Source
create_and_start_with_poly_data3 :: proc(
	arg1:         $T1, 
	arg2:         $T2, 
	arg3:         $T3, 
	fn:           proc(arg1: $T1, arg2: $T2, arg3: $T3), 
	init_context: Maybe($T=Context) = nil, 
	priority:     Thread_Priority = Thread_Priority.Normal, 
	self_cleanup: bool = false, 
) -> (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. **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 #

Source
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: Maybe($T=Context) = nil, 
	priority:     Thread_Priority = Thread_Priority.Normal, 
	self_cleanup: bool = false, 
) -> (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. **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 #

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

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

join_multiple #

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

Wait for all threads to finish work.

pool_add_task #

Source
pool_add_task :: proc(pool: ^Pool, allocator: 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.

pool_finish #

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

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

pool_init #

Source
pool_init :: proc(
	pool:         ^Pool, 
	allocator:    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 #

Source
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 #

Source
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 #

Source
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 #

Source
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 #

Source
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 #

Source
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 #

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

Use this to take out finished tasks.

pool_shutdown #

Source
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_stop_all_tasks #

Source
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 #

Source
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 #

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

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. **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 #

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

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. **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 #

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

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. **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 #

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

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. **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 #

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

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. **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 #

Source
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: Maybe($T=Context) = nil, 
	priority:     Thread_Priority = Thread_Priority.Normal, 
) {…}

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. **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.

yield #

Source
yield :: proc() {…}

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