libGimbal 0.1.0
C17-Based Extended Standard Library and Cross-Language Runtime Framework
Loading...
Searching...
No Matches
gimbal_thread.h
Go to the documentation of this file.
1/*! \file
2 * \brief GblThread and lowest-level concurrency managment
3 * \ingroup core
4 *
5 * This file contains the API and public structures for GblThread, the lowest-level
6 * construct for concurrent task execution, directly mapping to an OS-level thread.
7 * The API is backed by either C11 threads, POSIX pthreads, or Win32 threads,
8 * depending on the platform.
9 *
10 * \todo
11 * - properties
12 * - GblThread_setCallback() has to store within GblBox field
13 * - GblThread_setClosure() has to store within GblBox field WITH DTOR
14 * - GblArrayMap for underlying structure doesn't make sensse, use GblArrayList
15 * - need code for adding and removing to/from vector
16 * - checking for auto invocation upon constructed won't work--hasn't been set yet
17 *
18 * \author 2023 Falco Girgis
19 * \copyright MIT License
20 */
21#ifndef GIMBAL_THREAD_H
22#define GIMBAL_THREAD_H
23
24#include "../meta/instances/gimbal_object.h"
25#include "../meta/signals/gimbal_signal.h"
26#include "../meta/signals/gimbal_closure.h"
29#include "../allocators/gimbal_scope_allocator.h"
30#include <signal.h>
31
32/*! \name Type System
33 * \brief Type UUID and cast operators
34 * @{
35 */
36#define GBL_THREAD_TYPE (GBL_TYPEID(GblThread)) //!< Type UUID for GblThread
37#define GBL_THREAD(self) (GBL_CAST(GblThread, self)) //!< Function-style GblInstance cast
38#define GBL_THREAD_CLASS(klass) (GBL_CLASS_CAST(GblThread, klass)) //!< Function-style GblClass cast
39#define GBL_THREAD_GET_CLASS(self) (GBL_CLASSOF(GblThread, self)) //!< Get GblThreadClass from GblInstance
40//! @}
41
42#define GBL_SELF_TYPE GblThread
43
45
48
49//! Function callback type to be used as the main thread's callback with \ref GblThread_setCallback().
50typedef GBL_RESULT (*GblThreadFn) (GBL_SELF);
51//! Iterator function type to be used with \ref GblThread_foreach()
52typedef GblBool (*GblThreadIterFn)(GBL_SELF, void* pClosure);
53//! Represents a CPU affinity bitmask, with each bit being affinity to a single core
54typedef uintptr_t GblThreadAffinity;
55
56//! Priority levels for GblThread
63
64//! Lifetime states for a GblThread
67 GBL_THREAD_STATE_INITIALIZING, //!< Initializing/Constructing
68 GBL_THREAD_STATE_READY, //!< Ready/Waiting
69 GBL_THREAD_STATE_RUNNING, //!< Running/Executing
70 GBL_THREAD_STATE_FINISHED //!< Finished/Completed
71};
72\
73/*! \struct GblThreadClass
74 * \extends GblObjectClass
75 * \brief GblClass VTable structure for GblThread
76 *
77 * GblThreadClass is the class providing the virtual-table for
78 * GblThread. Its methods provide the logic that will be executed
79 * on the other thread.
80 *
81 * \sa GblThread
82 */
83GBL_CLASS_DERIVE(GblThread, GblObject)
84 //! Main execution entry point for a given thread, calls callback + closure then signals
85 GblThreadFn pFnRun;
86 //! Standard C signal handler for a given thread
87 GBL_RESULT (*pFnSignal)(GBL_SELF, int signal);
89
90/*! \struct GblThread
91 * \extends GblObject
92 * \ingroup core
93 * \brief Object representing a thread, its local storage, and logic
94 *
95 * GblThread encapsulates an operating system thread, its local storage,
96 * and the logic that is run within it.
97 *
98 * \sa GblThreadClass
99 */
101 GblCallRecord returnStatus; //!< Return information from a completed thread
102 volatile sig_atomic_t signalStatus; //!< Pending signal state for a given thread
103 GBL_THREAD_STATE state; //!< Current state for a given thread MAKE ME ATOMIC
105
106//! \cond
107GBL_PROPERTIES(GblThread,
108// (name, GBL_GENERIC, (READ, WRITE, OVERRIDE), GBL_STRING_TYPE),
109 (result, GBL_GENERIC, (READ ), GBL_ENUM_TYPE),
110 (state, GBL_GENERIC, (READ ), GBL_ENUM_TYPE),
111 (signal, GBL_GENERIC, (READ ), GBL_ENUM_TYPE),
112 (joined, GBL_GENERIC, (READ ), GBL_BOOL_TYPE),
113 (priority, GBL_GENERIC, ( WRITE ), GBL_ENUM_TYPE),
114 (affinity, GBL_GENERIC, ( WRITE ), GBL_FLAGS_TYPE),
115 (closure, GBL_GENERIC, (READ, WRITE ), GBL_CLOSURE_TYPE),
116 (callback, GBL_GENERIC, (READ, WRITE ), GBL_FUNCTION_TYPE)
117)
118
119GBL_SIGNALS(GblThread,
120 (started, (GBL_INSTANCE_TYPE, pReceiver)),
121 (finished, (GBL_INSTANCE_TYPE, pReceiver), (GBL_ENUM_TYPE, result)),
122 (signaled, (GBL_INSTANCE_TYPE, pReceiver), (GBL_ENUM_TYPE, signal))
123)
124//! \endcond
125
126/*! \name Static Methods
127 * \brief Searching, iterating, counting, etc.
128 * @{
129 */
130//! Returns the GblType UUID associated with GblThread
132//! Returns the current number of live threads (not necessarily all active)
134//! Searches (linearly) for a thread with the string name given by \p pName
135GBL_EXPORT GblThread* GblThread_find (const char* pName) GBL_NOEXCEPT;
136//! Iterates over all live threads, passing each thread and \p pCl back to the \p pIt callback
138 void* pCl/*=NULL*/) GBL_NOEXCEPT;
139//! @}
140
141/*! \name Parent Thread Methods
142 * \relatesalso GblThread
143 * \brief Methods to be called from a parent thread
144 * @{
145 */
146//! Creates a GblThread instance with the given callback and userdata and optionally starts its execution immediately
147GBL_EXPORT GblThread* GblThread_create (GblThreadFn pCallback,
148 void* pUserdata/*=NULL*/,
149 GblBool autoStart/*=0*/) GBL_NOEXCEPT;
150//! Returns a new reference to an existing thread, incrementing its reference count by 1
152//! Decrements the reference count of a GblThread instance, deleting it if it's the last one
154//! Returns GBL_TRUE if the given thread has been joined with its parent and is done executing, GBL_FALSE otherwise
156//! Returns the string name assigned to the given thread
158//! Sets the string name \p pName to be the name of the given thread
159GBL_EXPORT GBL_RESULT GblThread_setName (GBL_SELF, const char* pName) GBL_NOEXCEPT;
160//! Returns the closure assigned to the given thread, or NULL if there isn't one
162//! Assigns the closure of the given thread to \p pClosure, freeing the previous closure if there was one
164//! Returns the C callback function assigned to the given thread, or NULL if there isn't one
166//! Assigns the C callback function of the given thread to \p pCb, which will be executed with the thread
168//! Sets the priority of the given thread to \p priority
171//! Sets the CPU affinity of the given thread to \p affinity
174//! Immediately starts a thread which has not yet joined or finished executing
176//! Blocks execution of the current thread, awaiting the completion of the given thread
178//! Performs a non-blocking wait on the given thread, spinning on a timeout
180 const GblTimeSpec* pTimeout*/)GBL_NOEXCEPT;
181//! @}
182
183/*! \name Child Thread Methods
184 * \relatesalso GblThread
185 * \brief Methods to be called from the spawned child thread
186 * @{
187 */
188//! Returns a pointer to the GblThread instance associatedw with the current thread
190//! Suspends execution of the current thread, allowing other threads to execute temporarily
192//! Sleeps the current thread for \p nsec nanoseconds, returning the remaining time optionally within \p pRemainder
193GBL_EXPORT GBL_RESULT GblThread_nanoSleep (uint64_t nsec,
194 uint64_t* pRemainder/*=NULL*/) GBL_NOEXCEPT;
195//! Ends execution of the currently executing thread, returning \p result and storing the given source context
196GBL_EXPORT GBL_RESULT GblThread_exit (GBL_RESULT result,
197 const char* pMessage/*=NULL*/,
198 const char* pFile /*=NULL*/,
199 const char* pFunc /*=NULL*/,
200 size_t line /*=0*/) GBL_NOEXCEPT;
201//! @}
202
203/*! \name Function Overload Macros
204 * \brief Macros providing default arguments for methods
205 * @{
206 */
207//! Provides default argument handling for GblThread_create()
208#define GblThread_create(...) GBL_VA_OVERLOAD_CALL_ARGC(GblThread_create_, __VA_ARGS__)
209//! Provides default argument handling for GblThread_exit()
210#define GblThread_exit(...) GBL_VA_OVERLOAD_CALL_ARGC(GblThread_exit_, __VA_ARGS__)
211//! Provides default argument handling for GblThread_nanoSleep()
212#define GblThread_nanoSleep(...) GBL_VA_OVERLOAD_CALL_ARGC(GblThread_nanoSleep_, __VA_ARGS__)
213//! Provides default argument handling for GblThread_foreach()
214#define GblThread_foreach(...) GBL_VA_OVERLOAD_CALL_ARGC(GblThread_foreach_, __VA_ARGS__)
215//! @}
216
218
219///\cond
220#define GblThread_create__3(cb, ud, start) ((GblThread_create)(cb, ud, start))
221#define GblThread_create__2(cb, ud) (GblThread_create__3(cb, ud, GBL_TRUE))
222#define GblThread_create__1(cb) (GblThread_create__2(cb, GBL_NULL))
223
224#define GblThread_exit__2(result, msg)
225 (GblThread_exit(result, msg, __FILE__, __func__, __LINE__))
226#define GblThread_exit__1(result)
227 (GblThread_exit(result, GBL_NULL, __FILE__, __func__, __LINE__))
228
229#define GblThread_nanoSleep__2(nsec, pRem)
230 ((GblThread_nanoSleep)(nsec, pRem))
231#define GblThread_nanoSleep__1(nsec)
232 (GblThread_nanoSleep__2(nsec, GBL_NULL))
233
234#define GblThread_foreach__2(it, closure)
235 ((GblThread_foreach)(it, closure))
236#define GblThread_foreach__1(it)
237 (GblThread_foreach__2(it, GBL_NULL))
238///\endcond
239
240#undef GBL_SELF_TYPE
241
242#endif // GIMBAL_THREAD_H
#define GBL_CLOSURE_TYPE
Type UUID for GblClosure.
#define GBL_NULL
#define GBL_NOEXCEPT
#define GBL_DECLS_BEGIN
#define GBL_FORWARD_DECLARE_STRUCT(S)
#define GBL_TYPEID(instanceStruct)
#define GBL_INSTANCE_DERIVE(derivedInstance, baseInstance)
#define GBL_DECLARE_ENUM(E)
#define GBL_CLASS_DERIVE(...)
#define GBL_INSTANCE_END
#define GBL_EXPORT
#define GBL_CLASS_END
#define GBL_ENUM_TYPE
Type UUID of GblEnumClass.
Definition gimbal_enum.h:22
#define GBL_FLAGS_TYPE
GblType UUID for flags.
#define GBL_VA_OVERLOAD_CALL_ARGC(BASE,...)
#define GBL_FUNCTION_TYPE
#define GBL_BOOL_TYPE
Builtin ID for boolean GblVariant type.
#define GBL_PROPERTIES(object,...)
Declares a list of properties for the given object/instance structure.
#define GBL_SIGNALS(instanceStruct,...)
Declares a list of signals to be associated with the given instanceStruct.
GBL_THREAD_PRIORITY
@ GBL_THREAD_PRIORITY_MEDIUM
Medium.
@ GBL_THREAD_PRIORITY_LOW
Lowest.
@ GBL_THREAD_PRIORITY_HIGH
High.
@ GBL_THREAD_PRIORITY_REAL_TIME
Highest.
GBL_THREAD_STATE
@ GBL_THREAD_STATE_RUNNING
Running/Executing.
@ GBL_THREAD_STATE_FINISHED
Finished/Completed.
@ GBL_THREAD_STATE_INITIALIZING
Initializing/Constructing.
@ GBL_THREAD_STATE_UNKNOWN
Unknown.
@ GBL_THREAD_STATE_READY
Ready/Waiting.
GblThread * GblThread_find(const char *pName)
Searches (linearly) for a thread with the string name given by pName.
#define GblThread_foreach(...)
Provides default argument handling for GblThread_foreach()
GblType GblThread_type(void)
Returns the GblType UUID associated with GblThread.
size_t GblThread_count(void)
Returns the current number of live threads (not necessarily all active)
uintptr_t GblThreadAffinity
Represents a CPU affinity bitmask, with each bit being affinity to a single core.
GblBool GblThread_foreach(GblThreadIterFn pIt, void *pCl)
Iterates over all live threads, passing each thread and pCl back to the pIt callback.
#define GBL_TRUE
uint8_t GblBool
Basic boolean type, standardized to sizeof(char)
uint16_t GblRefCount
Type able to hold a reference counter across the codebase.
uintptr_t GblType
Meta Type UUID.
Definition gimbal_type.h:52
GblThreadFn pFnRun
Main execution entry point for a given thread, calls callback + closure then signals.
Object representing a thread, its local storage, and logic.
GBL_RESULT GblThread_setPriority(GblThread *pSelf, GBL_THREAD_PRIORITY priority)
Sets the priority of the given thread to priority.
GBL_RESULT GblThread_setAffinity(GblThread *pSelf, GblThreadAffinity affinity)
Sets the CPU affinity of the given thread to affinity.
GBL_RESULT GblThread_join(GblThread *pSelf)
Blocks execution of the current thread, awaiting the completion of the given thread.
GblThread * GblThread_ref(const GblThread *pSelf)
Returns a new reference to an existing thread, incrementing its reference count by 1.
GBL_RESULT GblThread_spinWait(GblThread *pSelf)
Performs a non-blocking wait on the given thread, spinning on a timeout.
const char * GblThread_name(const GblThread *pSelf)
Returns the string name assigned to the given thread.
GBL_RESULT GblThread_yield(void)
Suspends execution of the current thread, allowing other threads to execute temporarily.
GblThreadFn GblThread_callback(const GblThread *pSelf)
Returns the C callback function assigned to the given thread, or NULL if there isn't one.
void GblThread_setCallback(GblThread *pSelf, GblThreadFn pCb)
Assigns the C callback function of the given thread to pCb, which will be executed with the thread.
GBL_RESULT GblThread_setName(GblThread *pSelf, const char *pName)
Sets the string name pName to be the name of the given thread.
GBL_RESULT GblThread_start(GblThread *pSelf)
Immediately starts a thread which has not yet joined or finished executing.
volatile sig_atomic_t signalStatus
Pending signal state for a given thread.
GBL_THREAD_STATE state
Current state for a given thread MAKE ME ATOMIC.
GblBool GblThread_isJoined(const GblThread *pSelf)
Returns GBL_TRUE if the given thread has been joined with its parent and is done executing,...
void GblThread_setClosure(GblThread *pSelf, GblClosure *pClosure)
Assigns the closure of the given thread to pClosure, freeing the previous closure if there was one.
GblRefCount GblThread_unref(GblThread *pSelf)
Decrements the reference count of a GblThread instance, deleting it if it's the last one.
GblCallRecord returnStatus
Return information from a completed thread.
GblThread * GblThread_current(void)
Returns a pointer to the GblThread instance associatedw with the current thread.
GblClosure * GblThread_closure(const GblThread *pSelf)
Returns the closure assigned to the given thread, or NULL if there isn't one.