solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
Loading...
Searching...
No Matches
Typedefs | Functions
thread.h File Reference

Cross-platform thread management and system information utilities. More...

#include <stdint.h>
#include <errno.h>
#include <grp.h>
#include <pthread.h>
#include <pwd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
Include dependency graph for thread.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef pthread_t Thread
 
typedef pthread_attr_t ThreadAttr
 
typedef void *(* ThreadStartRoutine) (void *arg)
 

Functions

int thread_create (Thread *thread, ThreadStartRoutine start_routine, void *data)
 
int thread_create_attr (Thread *thread, ThreadAttr *attr, ThreadStartRoutine start_routine, void *data)
 
int thread_join (Thread tid, void **retval)
 
int thread_detach (Thread tid)
 
void thread_exit (void *retval)
 
pthread_t thread_self ()
 
int thread_attr_init (ThreadAttr *attr)
 
int thread_attr_destroy (ThreadAttr *attr)
 
void sleep_ms (int ms)
 
int get_pid ()
 
unsigned long get_tid ()
 
long get_ncpus ()
 
int get_ppid ()
 
unsigned int get_uid ()
 
unsigned int get_gid ()
 
char * get_username ()
 
char * get_groupname ()
 

Detailed Description

Cross-platform thread management and system information utilities.

Provides a unified interface for thread creation, synchronization, and system information queries across Windows and POSIX systems. All thread functions return 0 on success and non-zero on error for consistency with POSIX conventions.

Thread safety is documented per function. Generally, thread creation and attribute management functions are thread-safe, but individual thread attribute objects should not be modified concurrently.

Note
This library requires linking with pthread on POSIX systems (-lpthread).

Platform Limitations

Windows Return Value Limitation: On Windows, thread return values (void*) are stored as 32-bit DWORD values. If your thread returns a 64-bit pointer on 64-bit Windows, the upper 32 bits will be lost. For portable code, return values should fit in 32 bits (e.g., cast integer status codes to void*).

Thread ID Portability: The get_tid() function returns unsigned long, but pthread_t is an opaque type that may not be convertible to an integer on all platforms. Use get_tid() for logging/debugging only, not as a unique identifier for synchronization.

Thread Handle Lifetime: After calling thread_detach() on Windows, the thread handle becomes invalid and must not be used for any subsequent operations. This matches POSIX semantics where detached threads cannot be joined.

Definition in file thread.h.

Typedef Documentation

◆ Thread

typedef pthread_t Thread

Platform-specific thread handle (POSIX pthread_t).

Definition at line 78 of file thread.h.

◆ ThreadAttr

typedef pthread_attr_t ThreadAttr

Thread attribute configuration (POSIX pthread_attr_t).

Definition at line 81 of file thread.h.

◆ ThreadStartRoutine

typedef void *(* ThreadStartRoutine) (void *arg)

Thread start routine function pointer type.

Parameters
argUser-provided argument passed to the thread.
Returns
Thread exit value (can be retrieved via thread_join).
Note
On Windows, only the lower 32 bits of pointer return values are preserved. For portable code, return integer status codes cast to void*.
The return value should be a pointer or integer cast to void*.

Definition at line 92 of file thread.h.

Function Documentation

◆ get_gid()

unsigned int get_gid ( )

Returns the current group ID or equivalent identifier.

Returns
Group identifier as unsigned integer, or (unsigned int)-1 on error.
Note
Thread-safe: Yes.
On POSIX: Returns the real group ID (GID) via getgid().
On Windows: Returns a hash of the primary group's Security Identifier (SID). Windows SIDs are variable-length, so a 32-bit hash is computed for compatibility. The hash is consistent for the same group.

Definition at line 628 of file thread.c.

◆ get_groupname()

char * get_groupname ( )

Returns the current group name.

Returns
Pointer to static string containing group name, or NULL on error.
Note
Thread-safe: No (returns pointer to static data).
On POSIX: Uses getgrgid() which returns pointer to static data that may be overwritten by subsequent calls to getgrgid or related functions.
On Windows: Looks up the primary group name from the user token using LookupAccountSidA() with a static buffer. May be slower than POSIX version.
Caller should not modify or free the returned string.
Copy the string if you need to keep it across multiple calls or threads.
On Windows, returns the primary group from the user's access token.

Definition at line 639 of file thread.c.

◆ get_ncpus()

long get_ncpus ( )

Returns the number of available CPU cores.

Returns
Number of CPU cores, or -1 on error.
Note
Thread-safe: Yes.
Returns online processors, which may be less than total processors.
The returned value may change if CPUs are hot-plugged or taken offline.
Returns 0 is never expected - if you receive 0, treat it as an error.

Definition at line 363 of file thread.c.

◆ get_pid()

int get_pid ( )

Returns the current process ID.

Returns
Process ID as an integer, or -1 on error (rare).
Note
Thread-safe: Yes.
Process ID remains constant throughout the process lifetime.

Definition at line 338 of file thread.c.

◆ get_ppid()

int get_ppid ( )

Returns the parent process ID.

Returns
Parent process ID as an integer, or -1 on error.
Note
Thread-safe: Yes.
On POSIX: Returns the parent process ID directly via getppid().
On Windows: Uses toolhelp API to enumerate processes and find parent. This may be slightly slower and can fail if process access is restricted.
The parent process ID may change if the parent exits (POSIX: reparented to init/systemd; Windows: orphaned processes retain original parent PID).

Definition at line 617 of file thread.c.

◆ get_tid()

unsigned long get_tid ( )

Returns the current thread ID as an unsigned long.

Returns
Thread ID as unsigned long for cross-platform compatibility.
Note
Thread-safe: Yes.
On Windows, returns the thread ID. On POSIX, returns pthread_t cast to unsigned long.
Warning
pthread_t is an opaque type and may not be safely convertible to unsigned long on all platforms. Use this function for logging/debugging only, not as a reliable unique identifier for thread synchronization.

Definition at line 351 of file thread.c.

◆ get_uid()

unsigned int get_uid ( )

Returns the current user ID or equivalent identifier.

Returns
User identifier as unsigned integer, or (unsigned int)-1 on error.
Note
Thread-safe: Yes.
On POSIX: Returns the real user ID (UID) via getuid().
On Windows: Returns a hash of the user's Security Identifier (SID). Windows SIDs are variable-length, so a 32-bit hash is computed for compatibility. The hash is consistent for the same user but may not match numeric values from other Windows APIs.

Definition at line 626 of file thread.c.

◆ get_username()

char * get_username ( )

Returns the current user name.

Returns
Pointer to static string containing username, or NULL on error.
Note
Thread-safe: No (returns pointer to static data).
On POSIX: Uses getpwuid() which returns pointer to static data that may be overwritten by subsequent calls to getpwuid or related functions.
On Windows: Uses GetUserNameA() with a static buffer. The buffer may be overwritten by subsequent calls to get_username().
Caller should not modify or free the returned string.
Copy the string if you need to keep it across multiple calls or threads.

Definition at line 630 of file thread.c.

◆ sleep_ms()

void sleep_ms ( int  ms)

Suspends execution of the calling thread for specified milliseconds.

Parameters
msNumber of milliseconds to sleep. Must be non-negative and <= INT_MAX.
Note
Thread-safe: Yes.
Other threads continue to run during sleep.
Actual sleep time may be longer due to system scheduling.
If ms <= 0, the function returns immediately without sleeping.
On POSIX systems, sleep is interruptible by signals but will continue for the remaining time after handling EINTR.

Definition at line 310 of file thread.c.

References sleep_ms().

Referenced by sleep_ms().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_attr_destroy()

int thread_attr_destroy ( ThreadAttr attr)

Destroys thread attributes and releases associated resources.

Parameters
attrPointer to initialized thread attributes. Must not be NULL.
Returns
0 on success, EINVAL for invalid parameter, or other non-zero error code.
Note
Thread-safe: Yes (different attr objects), No (same attr object).
After destruction, the attr structure should not be used unless reinitialized.
On Windows, this zeros the structure for security but has no other effect.

Definition at line 292 of file thread.c.

References thread_attr_destroy().

Referenced by thread_attr_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_attr_init()

int thread_attr_init ( ThreadAttr attr)

Initializes thread attributes to default values.

Parameters
attrPointer to thread attributes structure. Must not be NULL.
Returns
0 on success, EINVAL for invalid parameter, or other non-zero error code.
Note
Thread-safe: Yes (different attr objects), No (same attr object).
Must call thread_attr_destroy() to release resources.
Default attributes: joinable thread, default stack size, default security.

Definition at line 272 of file thread.c.

References thread_attr_init().

Referenced by thread_attr_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_create()

int thread_create ( Thread thread,
ThreadStartRoutine  start_routine,
void *  data 
)

Creates a new thread with default attributes.

Parameters
threadPointer to store the created thread handle. Must not be NULL.
start_routineFunction to execute in the new thread. Must not be NULL.
dataArgument to pass to the start routine. Can be NULL.
Returns
0 on success, EINVAL for invalid parameters, ENOMEM for allocation failure, or other non-zero error code on failure.
Note
Thread-safe: Yes.
Created thread is joinable by default. Call thread_detach() to make it detached.
On success, the thread handle stored in *thread is valid until thread_join() or thread_detach() is called.

Definition at line 95 of file thread.c.

References thread_create().

Referenced by thread_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_create_attr()

int thread_create_attr ( Thread thread,
ThreadAttr attr,
ThreadStartRoutine  start_routine,
void *  data 
)

Creates a new thread with custom attributes.

Parameters
threadPointer to store the created thread handle. Must not be NULL.
attrPointer to initialized thread attributes. Must not be NULL.
start_routineFunction to execute in the new thread. Must not be NULL.
dataArgument to pass to the start routine. Can be NULL.
Returns
0 on success, EINVAL for invalid parameters, ENOMEM for allocation failure, or other non-zero error code on failure.
Note
Thread-safe: Yes.
The attr object can be destroyed immediately after this call returns.

Definition at line 140 of file thread.c.

References thread_create_attr().

Referenced by thread_create_attr().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_detach()

int thread_detach ( Thread  tid)

Detaches a thread, allowing system to reclaim resources when it terminates.

Parameters
tidThread handle to detach. Must be a valid handle from thread_create().
Returns
0 on success, EINVAL for invalid handle, or other non-zero error code on failure.
Note
Thread-safe: Yes.
After detaching, the thread handle becomes invalid and must not be used for any operations, including join. This applies to both Windows and POSIX.
After detaching, the thread cannot be joined - calling thread_join() on a detached thread results in undefined behavior.
The thread continues to run after detachment and will clean up automatically when it exits.

Definition at line 240 of file thread.c.

References thread_detach().

Referenced by thread_detach().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_exit()

void thread_exit ( void *  retval)

Terminates the calling thread and returns a value to the caller.

Parameters
retvalThe return value for the thread. On POSIX, this is a void pointer. On Windows, this should be cast from a DWORD exit code.
Note
On Windows, only the lower 32 bits of the pointer are used as the exit code.
This function does not return.

Definition at line 231 of file thread.c.

References thread_exit().

Referenced by thread_exit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_join()

int thread_join ( Thread  tid,
void **  retval 
)

Waits for a thread to terminate and retrieves its exit value.

Parameters
tidThread handle to wait for. Must be a valid handle from thread_create().
retvalPointer to store thread's return value. Can be NULL if not needed.
Returns
0 on success, EINVAL for invalid handle, or other non-zero error code on failure.
Note
Thread-safe: Yes, but each thread can only be joined once.
On Windows, closes the thread handle automatically after join. On POSIX, the thread resources are freed but the pthread_t value may still be compared.
Joining a detached thread results in undefined behavior.
On Windows, only the lower 32 bits of pointer return values are preserved.

Definition at line 184 of file thread.c.

References thread_join().

Referenced by thread_join(), and threadpool_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ thread_self()

pthread_t thread_self ( )

Returns the current thread's handle (POSIX-specific).

Returns
Current thread handle as pthread_t.
Note
Thread-safe: Yes.
This returns the pthread_t handle, not a numeric ID.
pthread_t is an opaque type - use pthread_equal() to compare threads.

Definition at line 267 of file thread.c.

References thread_self().

Referenced by thread_self().

Here is the call graph for this function:
Here is the caller graph for this function: