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"
28#include "../allocators/gimbal_scope_allocator.h"
29#include <signal.h>
30
31/*! \name Type System
32 * \brief Type UUID and cast operators
33 * @{
34 */
35#define GBL_THREAD_TYPE (GBL_TYPEID(GblThread)) //!< Type UUID for GblThread
36#define GBL_THREAD(self) (GBL_CAST(GblThread, self)) //!< Function-style GblInstance cast
37#define GBL_THREAD_CLASS(klass) (GBL_CLASS_CAST(GblThread, klass)) //!< Function-style GblClass cast
38#define GBL_THREAD_GET_CLASS(self) (GBL_CLASSOF(GblThread, self)) //!< Get GblThreadClass from GblInstance
39//! @}
40
41#define GBL_SELF_TYPE GblThread
42
44
47
48//! Function callback type to be used as the main thread's callback with \ref GblThread_setCallback().
49typedef GBL_RESULT (*GblThreadFn) (GBL_SELF);
50//! Iterator function type to be used with \ref GblThread_foreach()
51typedef GblBool (*GblThreadIterFn)(GBL_SELF, void* pClosure);
52//! Represents a CPU affinity bitmask, with each bit being affinity to a single core
53typedef uintptr_t GblThreadAffinity;
54
55//! Priority levels for GblThread
61};
62
63//! Lifetime states for a GblThread
66 GBL_THREAD_STATE_INITIALIZING, //!< Initializing/Constructing
67 GBL_THREAD_STATE_READY, //!< Ready/Waiting
68 GBL_THREAD_STATE_RUNNING, //!< Running/Executing
69 GBL_THREAD_STATE_FINISHED //!< Finished/Completed
70};
71\
72/*! \struct GblThreadClass
73 * \extends GblObjectClass
74 * \brief GblClass VTable structure for GblThread
75 *
76 * GblThreadClass is the class providing the virtual-table for
77 * GblThread. Its methods provide the logic that will be executed
78 * on the other thread.
79 *
80 * \sa GblThread
81 */
82GBL_CLASS_DERIVE(GblThread, GblObject)
83 //! Main execution entry point for a given thread, calls callback + closure then signals
84 GblThreadFn pFnRun;
85 //! Standard C signal handler for a given thread
86 GBL_RESULT (*pFnSignal)(GBL_SELF, int signal);
88
89/*! \struct GblThread
90 * \extends GblObject
91 * \ingroup core
92 * \brief Object representing a thread, its local storage, and logic
93 *
94 * GblThread encapsulates an operating system thread, its local storage,
95 * and the logic that is run within it.
96 *
97 * \sa GblThreadClass
98 */
100 GblCallRecord returnStatus; //!< Return information from a completed thread
101 volatile sig_atomic_t signalStatus; //!< Pending signal state for a given thread
102 GBL_THREAD_STATE state; //!< Current state for a given thread MAKE ME ATOMIC
104
105//! \cond
106GBL_PROPERTIES(GblThread,
107// (name, GBL_GENERIC, (READ, WRITE, OVERRIDE), GBL_STRING_TYPE),
108 (result, GBL_GENERIC, (READ ), GBL_ENUM_TYPE),
109 (state, GBL_GENERIC, (READ ), GBL_ENUM_TYPE),
110 (signal, GBL_GENERIC, (READ ), GBL_ENUM_TYPE),
111 (joined, GBL_GENERIC, (READ ), GBL_BOOL_TYPE),
112 (priority, GBL_GENERIC, ( WRITE ), GBL_ENUM_TYPE),
113 (affinity, GBL_GENERIC, ( WRITE ), GBL_FLAGS_TYPE),
114 (closure, GBL_GENERIC, (READ, WRITE ), GBL_CLOSURE_TYPE),
115 (callback, GBL_GENERIC, (READ, WRITE ), GBL_FUNCTION_TYPE)
116)
117
118GBL_SIGNALS(GblThread,
119 (started, (GBL_INSTANCE_TYPE, pReceiver)),
120 (finished, (GBL_INSTANCE_TYPE, pReceiver), (GBL_ENUM_TYPE, result)),
121 (signaled, (GBL_INSTANCE_TYPE, pReceiver), (GBL_ENUM_TYPE, signal))
122)
123//! \endcond
124
125/*! \name Static Methods
126 * \brief Searching, iterating, counting, etc.
127 * @{
128 */
129//! Returns the GblType UUID associated with GblThread
131//! Returns the current number of live threads (not necessarily all active)
133//! Searches (linearly) for a thread with the string name given by \p pName
134GBL_EXPORT GblThread* GblThread_find (const char* pName) GBL_NOEXCEPT;
135//! Iterates over all live threads, passing each thread and \p pCl back to the \p pIt callback
137 void* pCl/*=NULL*/) GBL_NOEXCEPT;
138//! @}
139
140/*! \name Parent Thread Methods
141 * \relatesalso GblThread
142 * \brief Methods to be called from a parent thread
143 * @{
144 */
145//! Creates a GblThread instance with the given callback and userdata and optionally starts its execution immediately
146GBL_EXPORT GblThread* GblThread_create (GblThreadFn pCallback,
147 void* pUserdata/*=NULL*/,
148 GblBool autoStart/*=0*/) GBL_NOEXCEPT;
149//! Returns a new reference to an existing thread, incrementing its reference count by 1
151//! Decrements the reference count of a GblThread instance, deleting it if it's the last one
153//! Returns GBL_TRUE if the given thread has been joined with its parent and is done executing, GBL_FALSE otherwise
155//! Returns the string name assigned to the given thread
157//! Sets the string name \p pName to be the name of the given thread
158GBL_EXPORT GBL_RESULT GblThread_setName (GBL_SELF, const char* pName) GBL_NOEXCEPT;
159//! Returns the closure assigned to the given thread, or NULL if there isn't one
161//! Assigns the closure of the given thread to \p pClosure, freeing the previous closure if there was one
163//! Returns the C callback function assigned to the given thread, or NULL if there isn't one
165//! Assigns the C callback function of the given thread to \p pCb, which will be executed with the thread
167//! Sets the priority of the given thread to \p priority
170//! Sets the CPU affinity of the given thread to \p affinity
173//! Immediately starts a thread which has not yet joined or finished executing
175//! Blocks execution of the current thread, awaiting the completion of the given thread
177//! Performs a non-blocking wait on the given thread, spinning on a timeout
179 const GblTimeSpec* pTimeout*/)GBL_NOEXCEPT;
180//! @}
181
182/*! \name Child Thread Methods
183 * \relatesalso GblThread
184 * \brief Methods to be called from the spawned child thread
185 * @{
186 */
187//! Returns a pointer to the GblThread instance associatedw with the current thread
189//! Suspends execution of the current thread, allowing other threads to execute temporarily
191//! Sleeps the current thread for \p nsec nanoseconds, returning the remaining time optionally within \p pRemainder
192GBL_EXPORT GBL_RESULT GblThread_nanoSleep (uint64_t nsec,
193 uint64_t* pRemainder/*=NULL*/) GBL_NOEXCEPT;
194//! Ends execution of the currently executing thread, returning \p result and storing the given source context
195GBL_EXPORT GBL_RESULT GblThread_exit (GBL_RESULT result,
196 const char* pMessage/*=NULL*/,
197 const char* pFile /*=NULL*/,
198 const char* pFunc /*=NULL*/,
199 size_t line /*=0*/) GBL_NOEXCEPT;
200//! @}
201
202/*! \name Function Overload Macros
203 * \brief Macros providing default arguments for methods
204 * @{
205 */
206//! Provides default argument handling for GblThread_create()
207#define GblThread_create(...) GBL_VA_OVERLOAD_CALL_ARGC(GblThread_create_, __VA_ARGS__)
208//! Provides default argument handling for GblThread_exit()
209#define GblThread_exit(...) GBL_VA_OVERLOAD_CALL_ARGC(GblThread_exit_, __VA_ARGS__)
210//! Provides default argument handling for GblThread_nanoSleep()
211#define GblThread_nanoSleep(...) GBL_VA_OVERLOAD_CALL_ARGC(GblThread_nanoSleep_, __VA_ARGS__)
212//! Provides default argument handling for GblThread_foreach()
213#define GblThread_foreach(...) GBL_VA_OVERLOAD_CALL_ARGC(GblThread_foreach_, __VA_ARGS__)
214//! @}
215
217
218///\cond
219#define GblThread_create__3(cb, ud, start) ((GblThread_create)(cb, ud, start))
220#define GblThread_create__2(cb, ud) (GblThread_create__3(cb, ud, GBL_TRUE))
221#define GblThread_create__1(cb) (GblThread_create__2(cb, GBL_NULL))
222
223#define GblThread_exit__2(result, msg)
224 (GblThread_exit(result, msg, __FILE__, __func__, __LINE__))
225#define GblThread_exit__1(result)
226 (GblThread_exit(result, GBL_NULL, __FILE__, __func__, __LINE__))
227
228#define GblThread_nanoSleep__2(nsec, pRem)
229 ((GblThread_nanoSleep)(nsec, pRem))
230#define GblThread_nanoSleep__1(nsec)
231 (GblThread_nanoSleep__2(nsec, GBL_NULL))
232
233#define GblThread_foreach__2(it, closure)
234 ((GblThread_foreach)(it, closure))
235#define GblThread_foreach__1(it)
236 (GblThread_foreach__2(it, GBL_NULL))
237///\endcond
238
239#undef GBL_SELF_TYPE
240
241#endif // GIMBAL_THREAD_H
#define GBL_CLASS_CAST(cType, klass)
#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_CLASSOF(cType, self)
#define GBL_CAST(cType, self)
#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,...)
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.
#define GblThread_nanoSleep(...)
#define GblThread_exit(...)
GblThread * GblThread_find(const char *pName)
Searches (linearly) for a thread with the string name given by pName.
#define GblThread_create(...)
#define 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:51
Captures a result, its stringified message, and a source context.
GblThreadFn pFnRun
Main execution entry point for a given thread, calls callback + closure then signals.
Object representing a thread, its local storage, and logic.
#define GblThread_nanoSleep(...)
Sleeps the current thread for nsec nanoseconds, returning the remaining time optionally within pRemai...
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.
#define GblThread_exit(...)
Ends execution of the currently executing thread, returning result and storing the given source conte...
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.
#define GblThread_create(...)
Creates a GblThread instance with the given callback and userdata and optionally starts its execution...
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.