package core:thread

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,
	is_running:        bool,
	threads:           []^Thread,
	tasks:             [dynamic]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.

Task ¶

Task :: struct {
	procedure:  Task_Proc,
	data:       rawptr,
	user_index: int,
	allocator:  runtime.Allocator,
}

Task_Proc ¶

Task_Proc :: proc "odin" (task: Task)

Thread ¶

Thread :: struct {
	specific:           Thread_Os_Specific,
	id:                 int,
	procedure:          Thread_Proc,
	data:               rawptr,
	user_index:         int,
	user_args:          [8]rawptr,
	init_context:       runtime.Maybe(runtime.Context),
	creation_allocator: runtime.Allocator,
}

Thread_Priority ¶

Thread_Priority :: enum int {
	Normal, 
	Low, 
	High, 
}

Thread_Proc ¶

Thread_Proc :: proc "odin" (_: ^Thread)

Constants

MAX_USER_ARGUMENTS ¶

MAX_USER_ARGUMENTS :: 8

Variables

This section is empty.

Procedures

create ¶

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

create_and_start ¶

create_and_start :: proc "odin" (fn: Thread_Proc, init_context: runtime.Maybe(runtime.Context) = nil, priority: Thread_Priority = Thread_Priority.Normal) -> ^Thread {…}

create_and_start_with_data ¶

create_and_start_with_data :: proc "odin" (data: rawptr, fn: proc "odin" (ptr: rawptr), init_context: runtime.Maybe(runtime.Context) = nil, priority: Thread_Priority = Thread_Priority.Normal) -> ^Thread {…}

create_and_start_with_poly_data ¶

create_and_start_with_poly_data :: proc "odin" (data: $, fn: proc "odin" (data: $), init_context: runtime.Maybe(runtime.Context) = nil, priority: Thread_Priority = Thread_Priority.Normal) -> ^Thread {…}

create_and_start_with_poly_data2 ¶

create_and_start_with_poly_data2 :: proc "odin" (arg1: $, arg2: $, fn: proc "odin" (_: $, _: $), init_context: runtime.Maybe(runtime.Context) = nil, priority: Thread_Priority = Thread_Priority.Normal) -> ^Thread {…}

create_and_start_with_poly_data3 ¶

create_and_start_with_poly_data3 :: proc "odin" (
	arg1:         $, 
	arg2:         $, 
	arg3:         $, 
	fn:           proc "odin" (arg1: $, arg2: $, arg3: $), 
	init_context: runtime.Maybe(runtime.Context) = nil, 
) -> ^Thread {…}

create_and_start_with_poly_data4 ¶

create_and_start_with_poly_data4 :: proc "odin" (
	arg1:         $, 
	arg2:         $, 
	arg3:         $, 
	arg4:         $, 
	fn:           proc "odin" (arg1: $, arg2: $, arg3: $, arg4: $), 
	init_context: runtime.Maybe(runtime.Context) = nil, 
) -> ^Thread {…}

destroy ¶

destroy :: proc "odin" (_: ^Thread) {…}

is_done ¶

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

join ¶

join :: proc "odin" (_: ^Thread) {…}

join_multiple ¶

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

pool_add_task ¶

pool_add_task :: proc "odin" (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.

pool_destroy ¶

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

pool_do_work ¶

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

Mostly for internal use.

pool_finish ¶

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

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

pool_init ¶

pool_init :: proc "odin" (pool: ^Pool, allocator: runtime.Allocator, thread_count: int) {…}
 

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 "odin" (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 "odin" (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 "odin" (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 "odin" (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 "odin" (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 "odin" (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 "odin" (pool: ^Pool) -> (task: Task, got_task: bool) {…}
 

Use this to take out finished tasks.

pool_pop_waiting ¶

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

Mostly for internal use.

pool_start ¶

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

run ¶

run :: proc "odin" (fn: proc "odin" (), init_context: runtime.Maybe(runtime.Context) = nil, priority: Thread_Priority = Thread_Priority.Normal) {…}

run_with_data ¶

run_with_data :: proc "odin" (data: rawptr, fn: proc "odin" (ptr: rawptr), init_context: runtime.Maybe(runtime.Context) = nil, priority: Thread_Priority = Thread_Priority.Normal) {…}

run_with_poly_data ¶

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

run_with_poly_data2 ¶

run_with_poly_data2 :: proc "odin" (arg1: $, arg2: $, fn: proc "odin" (_: $, _: $), init_context: runtime.Maybe(runtime.Context) = nil, priority: Thread_Priority = Thread_Priority.Normal) {…}

run_with_poly_data3 ¶

run_with_poly_data3 :: proc "odin" (
	arg1:         $, 
	arg2:         $, 
	arg3:         $, 
	fn:           proc "odin" (arg1: $, arg2: $, arg3: $), 
	init_context: runtime.Maybe(runtime.Context) = nil, 
) {…}

run_with_poly_data4 ¶

run_with_poly_data4 :: proc "odin" (
	arg1:         $, 
	arg2:         $, 
	arg3:         $, 
	arg4:         $, 
	fn:           proc "odin" (arg1: $, arg2: $, arg3: $, arg4: $), 
	init_context: runtime.Maybe(runtime.Context) = nil, 
) {…}

start ¶

start :: proc "odin" (_: ^Thread) {…}

terminate ¶

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

yield ¶

yield :: proc "odin" () {…}

Procedure Groups

This section is empty.

Source Files

Generation Information

Generated with odin version dev-2022-10 (vendor "odin") Windows_amd64 @ 2022-10-06 21:11:36.862835700 +0000 UTC