plibsys
Typedefs | Enumerations | Functions | Variables
puthread.h File Reference

Multithreading support. More...

#include <pmacros.h>
#include <ptypes.h>
Include dependency graph for puthread.h:

Go to the source code of this file.

Typedefs

typedef struct PUThread_ PUThread
 Thread opaque data type. More...
 
typedef struct PUThreadKey_ PUThreadKey
 TLS key opaque data type. More...
 
typedef enum PUThreadPriority_ PUThreadPriority
 Thread priority. More...
 

Enumerations

enum  PUThreadPriority_ {
  P_UTHREAD_PRIORITY_INHERIT = 0, P_UTHREAD_PRIORITY_IDLE = 1, P_UTHREAD_PRIORITY_LOWEST = 2, P_UTHREAD_PRIORITY_LOW = 3,
  P_UTHREAD_PRIORITY_NORMAL = 4, P_UTHREAD_PRIORITY_HIGH = 5, P_UTHREAD_PRIORITY_HIGHEST = 6, P_UTHREAD_PRIORITY_TIMECRITICAL = 7
}
 Thread priority. More...
 

Functions

P_LIB_API PUThreadp_uthread_create_full (PUThreadFunc func, ppointer data, pboolean joinable, PUThreadPriority prio, psize stack_size, const pchar *name)
 Creates a new PUThread and starts it. More...
 
P_LIB_API PUThreadp_uthread_create (PUThreadFunc func, ppointer data, pboolean joinable, const pchar *name)
 Creates a PUThread and starts it. More...
 
P_LIB_API void p_uthread_exit (pint code)
 Exits from the currently running (caller) thread. More...
 
P_LIB_API pint p_uthread_join (PUThread *thread)
 Waits for the selected thread to become finished. More...
 
P_LIB_API pint p_uthread_sleep (puint32 msec)
 Sleeps the current thread (caller) for a specified amount of time. More...
 
P_LIB_API pboolean p_uthread_set_priority (PUThread *thread, PUThreadPriority prio)
 Sets a thread priority. More...
 
P_LIB_API void p_uthread_yield (void)
 Tells the scheduler to skip the current (caller) thread in the current planning stage. More...
 
P_LIB_API P_HANDLE p_uthread_current_id (void)
 Gets an ID of the current (caller) thread. More...
 
P_LIB_API PUThreadp_uthread_current (void)
 Gets a thread structure of the current (caller) thread. More...
 
P_LIB_API pint p_uthread_ideal_count (void)
 Gets the ideal number of threads for the system based on the number of avaialble CPUs and cores (physical and logical). More...
 
P_LIB_API void p_uthread_ref (PUThread *thread)
 Increments a thread reference counter. More...
 
P_LIB_API void p_uthread_unref (PUThread *thread)
 Decrements a thread reference counter. More...
 
P_LIB_API PUThreadKeyp_uthread_local_new (PDestroyFunc free_func)
 Create a new TLS reference key. More...
 
P_LIB_API void p_uthread_local_free (PUThreadKey *key)
 Frees a TLS reference key. More...
 
P_LIB_API ppointer p_uthread_get_local (PUThreadKey *key)
 Gets a TLS value. More...
 
P_LIB_API void p_uthread_set_local (PUThreadKey *key, ppointer value)
 Sets a TLS value. More...
 
P_LIB_API void p_uthread_replace_local (PUThreadKey *key, ppointer value)
 Replaces a TLS value. More...
 

Variables

P_BEGIN_DECLS typedef ppointer(* PUThreadFunc )(ppointer arg)
 Typedef for a PUThread running method. More...
 

Detailed Description

Multithreading support.

Author
Alexander Saprykin

A thread is a system execution unit which is managed independently by the scheduler of the operating system. It allows to do things in parallel or concurrently.

PUThread provides a convinient way of multithreading support using native routines to provide the best performance on the target system.

To create the thread use the p_uthread_create() or p_uthread_create_full() routines. Joinable threads allow to wait until their execution is finished before proceeding further. Thus you can synchronize threads' execution within the main thread.

A reference counter mechanism is used to keep track of a PUThread structure. It means that the structure will be freed automatically when the reference counter becomes zero. Use p_uthread_ref() to hold the structure and p_uthread_unref() to decrement the counter back. A running thread holds a reference to itself structure, so you do not require to hold a reference to the thread while it is running.

Priorities (if supported) allow to tune scheduler behavior: threads with higher priority will be executed more frequently. Be careful that improper priorities may lead to negative effects when some threads may receive almost zero execution time.

Thread priorities are unreliable: not all operating systems respect thread priorities in favour of process ones. Priorities may be ignored for bound threads (every thread bound to a kernel light-weight thread as 1:1), other systems may require administrative privileges to change the thread priority (i.e. Linux). Windows always respects thread priorities.

To put the current thread (even if it was not created using the PUThread routines) in a sleep state use p_uthread_sleep().

You can give a hint to the scheduler that the current thread do not need an execution time with the p_uthread_yield() routine. This is useful when some of the threads are in an idle state so you do not want to waste a CPU time. This only tells to the scheduler to skip the current scheduling cycle for the calling thread, though the scheduler can ingnore it.

A thread local storage (TLS) is provided. The TLS key's value can be accessed through a reference key defined as a PUThreadKey. A TLS reference key is some sort of a token which has an associated value. But every thread has its own token value though using the same token object.

After creating the TLS reference key every thread can use it to access a local-specific value. Use the p_uthread_local_new() call to create the TLS reference key and pass it to every thread which needs local-specific values. You can also provide a destroy notification function which would be called upon a TLS key removal which is usually performed on the thread exit.

There are two calls to set a TLS key's value: p_uthread_set_local() and p_uthread_replace_local(). The only difference is that the former one calls the provided destroy notification function before replacing the old value.

Thread names are used on most of operating systems for debugging purposes, thereby some limitations for long name can be applied and too long names will be truncated automatically.

Typedef Documentation

◆ PUThread

typedef struct PUThread_ PUThread

Thread opaque data type.

◆ PUThreadKey

typedef struct PUThreadKey_ PUThreadKey

TLS key opaque data type.

◆ PUThreadPriority

Thread priority.

Enumeration Type Documentation

◆ PUThreadPriority_

Thread priority.

Enumerator
P_UTHREAD_PRIORITY_INHERIT 

Inherits the caller thread priority.

Default priority.

P_UTHREAD_PRIORITY_IDLE 

Scheduled only when no other threads are running.

P_UTHREAD_PRIORITY_LOWEST 

Scheduled less often than P_UTHREAD_PRIORITY_LOW.

P_UTHREAD_PRIORITY_LOW 

Scheduled less often than P_UTHREAD_PRIORITY_NORMAL.

P_UTHREAD_PRIORITY_NORMAL 

Operating system's default priority.

P_UTHREAD_PRIORITY_HIGH 

Scheduled more often than P_UTHREAD_PRIORITY_NORMAL.

P_UTHREAD_PRIORITY_HIGHEST 

Scheduled more often than P_UTHREAD_PRIORITY_HIGH.

P_UTHREAD_PRIORITY_TIMECRITICAL 

Scheduled as often as possible.

Function Documentation

◆ p_uthread_create()

P_LIB_API PUThread* p_uthread_create ( PUThreadFunc  func,
ppointer  data,
pboolean  joinable,
const pchar name 
)

Creates a PUThread and starts it.

A short version of p_uthread_create_full().

Parameters
funcMain thread function to run.
dataPointer to pass into the thread main function, may be NULL.
joinableWhether to create a joinable thread or not.
nameThread name, maybe NULL.
Returns
Pointer to PUThread in case of success, NULL otherwise.
Since
0.0.1
Note
Unreference the returned value after use with p_uthread_unref(). You do not need to call p_uthread_ref() explicitly on the returned value.

◆ p_uthread_create_full()

P_LIB_API PUThread* p_uthread_create_full ( PUThreadFunc  func,
ppointer  data,
pboolean  joinable,
PUThreadPriority  prio,
psize  stack_size,
const pchar name 
)

Creates a new PUThread and starts it.

Parameters
funcMain thread function to run.
dataPointer to pass into the thread main function, may be NULL.
joinableWhether to create a joinable thread or not.
prioThread priority.
stack_sizeThread stack size, in bytes. Leave zero to use a default value.
nameThread name, maybe NULL.
Returns
Pointer to PUThread in case of success, NULL otherwise.
Since
0.0.1
Note
Unreference the returned value after use with p_uthread_unref(). You do not need to call p_uthread_ref() explicitly on the returned value.

◆ p_uthread_current()

P_LIB_API PUThread* p_uthread_current ( void  )

Gets a thread structure of the current (caller) thread.

Returns
The thread structure of the current thread.
Since
0.0.1
Note
This call doesn't not increment the reference counter of the returned structure.

A thread structure will be returned even for the thread which was created outside the library. But you should not use thread manipulation routines over that structure.

◆ p_uthread_current_id()

P_LIB_API P_HANDLE p_uthread_current_id ( void  )

Gets an ID of the current (caller) thread.

Returns
The ID of the current thread.
Since
0.0.1

This is a platform-dependent type. You shouldn't treat it as a number, it only gives you the uniquer ID of the thread accross the system.

◆ p_uthread_exit()

P_LIB_API void p_uthread_exit ( pint  code)

Exits from the currently running (caller) thread.

Parameters
codeExit code.
Since
0.0.1

◆ p_uthread_get_local()

P_LIB_API ppointer p_uthread_get_local ( PUThreadKey key)

Gets a TLS value.

Parameters
keyTLS reference key to get the value for.
Returns
TLS value for the given key.
Since
0.0.1
Note
This call may fail only in case of abnormal use or program behavior, the NULL value will be returned to tolerance the failure.

◆ p_uthread_ideal_count()

P_LIB_API pint p_uthread_ideal_count ( void  )

Gets the ideal number of threads for the system based on the number of avaialble CPUs and cores (physical and logical).

Returns
Ideal number of threads, 1 in case of failed detection.
Since
0.0.3

◆ p_uthread_join()

P_LIB_API pint p_uthread_join ( PUThread thread)

Waits for the selected thread to become finished.

Parameters
threadThread to wait for.
Returns
Thread exit code in case of success, -1 otherwise.
Since
0.0.1
Note
Thread must be joinable to return the non-negative result.

◆ p_uthread_local_free()

P_LIB_API void p_uthread_local_free ( PUThreadKey key)

Frees a TLS reference key.

Parameters
keyTLS reference key to free.
Since
0.0.1

It doesn't remove the TLS key itself but only removes a reference used to access the TLS slot.

◆ p_uthread_local_new()

P_LIB_API PUThreadKey* p_uthread_local_new ( PDestroyFunc  free_func)

Create a new TLS reference key.

Parameters
free_funcTLS key destroy notification call, leave NULL if not need.
Returns
New TLS reference key in case of success, NULL otherwise.
Since
0.0.1

◆ p_uthread_ref()

P_LIB_API void p_uthread_ref ( PUThread thread)

Increments a thread reference counter.

Parameters
threadPUThread to increment the reference counter.
Since
0.0.1
Note
The PUThread object will not be removed until the reference counter is positive.

◆ p_uthread_replace_local()

P_LIB_API void p_uthread_replace_local ( PUThreadKey key,
ppointer  value 
)

Replaces a TLS value.

Parameters
keyTLS reference key to replace the value for.
valueTLS value to set.
Since
0.0.1
Note
This call may fail only in case of abnormal use or program behavior.

This call does perform the notification function provided with p_uthread_local_new() on the old TLS value. This is the only difference with p_uthread_set_local().

◆ p_uthread_set_local()

P_LIB_API void p_uthread_set_local ( PUThreadKey key,
ppointer  value 
)

Sets a TLS value.

Parameters
keyTLS reference key to set the value for.
valueTLS value to set.
Since
0.0.1
Note
This call may fail only in case of abnormal use or program behavior.

It doesn't call the destructor notification function provided with p_uthread_local_new().

◆ p_uthread_set_priority()

P_LIB_API pboolean p_uthread_set_priority ( PUThread thread,
PUThreadPriority  prio 
)

Sets a thread priority.

Parameters
threadThread to set the priority for.
prioPriority to set.
Returns
TRUE in case of success, FALSE otherwise.
Since
0.0.1

◆ p_uthread_sleep()

P_LIB_API pint p_uthread_sleep ( puint32  msec)

Sleeps the current thread (caller) for a specified amount of time.

Parameters
msecMilliseconds to sleep.
Returns
0 in case of success, -1 otherwise.
Since
0.0.1

◆ p_uthread_unref()

P_LIB_API void p_uthread_unref ( PUThread thread)

Decrements a thread reference counter.

Parameters
threadPUThread to decrement the reference counter.
Since
0.0.1
Note
When the reference counter becomes zero the PUThread is removed from the memory.

◆ p_uthread_yield()

P_LIB_API void p_uthread_yield ( void  )

Tells the scheduler to skip the current (caller) thread in the current planning stage.

Since
0.0.1

The scheduler shouldn't give time ticks for the current thread during the current period, but it may ignore this call.

Variable Documentation

◆ PUThreadFunc

P_BEGIN_DECLS typedef ppointer(* PUThreadFunc) (ppointer arg)

Typedef for a PUThread running method.