23 #error "stk_c_pthread.cpp requires STK_TLS (pthread_self()/pthread_getspecific() are built on the per-task TLS slot)."
49extern "C" void *
malloc(std::size_t size);
50extern "C" void free(
void *ptr);
154 void *(*start_routine)(
void *);
191 return reinterpret_cast<IKernel *
>(
reinterpret_cast<void *
>(k));
199#if defined(__GNUC__) || defined(__clang__)
200template <
typename T>
static inline T
LoadAcquire(T *p) {
return __atomic_load_n(p, __ATOMIC_ACQUIRE); }
201template <
typename T>
static inline void StoreRelease(T *p, T v) { __atomic_store_n(p, v, __ATOMIC_RELEASE); }
202#elif defined(__ICCARM__)
206template <
typename T>
static inline T
LoadAcquire(T *p)
208 const T v = *
static_cast<volatile T *
>(p);
212template <
typename T>
static inline void StoreRelease(T *p, T v)
215 *
static_cast<volatile T *
>(p) = v;
219template <
typename T>
static inline T
LoadAcquire(T *p) {
return *
static_cast<volatile T *
>(p); }
220template <
typename T>
static inline void StoreRelease(T *p, T v) { *
static_cast<volatile T *
>(p) = v; }
225template <
typename T,
typename Mem>
241 return static_cast<T *
>(h);
281 reinterpret_cast<uint8_t *
>(s_PthreadStackStorage),
282 sizeof(s_PthreadStackStorage),
384 bool do_reap =
false;
472 ctrl->
stack =
nullptr;
485 if ((attr !=
nullptr) && (attr->
__ext_stack !=
nullptr))
518 return (ctrl->
stack !=
nullptr);
528 hw::SetTlsPtr(
static_cast<void *
>(ctrl));
567 (
static_cast<stk_time_t>(abstime->tv_nsec) / 1000000LL);
575 if (rel_ms >
static_cast<stk_time_t>(INT32_MAX))
613 result = errorcheck_code;
647 return hw::GetTlsPtr<ThreadCtrl>();
667 hw::SetTlsPtr(
static_cast<void *
>(ctrl));
705 bool any_ran =
false;
709 void *
const value = ctrl->
tsd[i];
711 if (value !=
nullptr)
713 void (*destructor)(
void *) =
nullptr;
719 destructor =
s_Keys[i].destructor;
723 ctrl->
tsd[i] =
nullptr;
724 if (destructor !=
nullptr)
779 return (attr !=
nullptr) ? 0 : EINVAL;
786 if ((attr !=
nullptr) && (stacksize != 0U))
799 if ((attr !=
nullptr) && (stacksize !=
nullptr))
812 if ((attr !=
nullptr) && (stackaddr !=
nullptr) && (stacksize >=
sizeof(
stk_word_t)))
814 if ((
reinterpret_cast<uintptr_t
>(stackaddr) &
STK_ALIGN_MASK) == 0U)
829 if ((attr !=
nullptr) && (stackaddr !=
nullptr) && (stacksize !=
nullptr))
843 if ((attr !=
nullptr) &&
857 if ((attr !=
nullptr) && (detachstate !=
nullptr))
870 if ((attr !=
nullptr) &&
884 if ((attr !=
nullptr) && (mode !=
nullptr))
897 void *(*start_routine)(
void *),
void *arg)
905 if ((
s_BoundKernel ==
nullptr) || (thread ==
nullptr) || (start_routine ==
nullptr))
919 const size_t stack_bytes = ((attr !=
nullptr) && (attr->
__stack_bytes != 0U)) ?
921 const uint32_t stack_words =
990 if (retval !=
nullptr)
1008 if (ctrl ==
nullptr)
1042 if (ctrl !=
nullptr)
1080 return (t1 == t2) ? 1 : 0;
1094 int result = EINVAL;
1096 if (attr !=
nullptr)
1107 return (attr !=
nullptr) ? 0 : EINVAL;
1112 int result = EINVAL;
1125 int result = EINVAL;
1127 if ((attr !=
nullptr) && (type !=
nullptr))
1138 int result = EINVAL;
1140 if (mutex !=
nullptr)
1157 int result = EINVAL;
1159 if (mutex !=
nullptr)
1174 int result = EINVAL;
1176 if (mutex !=
nullptr)
1192 int result = EINVAL;
1194 if (mutex !=
nullptr)
1201 result = m->
TryLock() ? 0 : EBUSY;
1210 int result = EINVAL;
1212 if ((mutex !=
nullptr) && (mutex->
__handle !=
nullptr))
1232 int result = EINVAL;
1234 if ((mutex !=
nullptr) && (abstime !=
nullptr))
1253 int result = EINVAL;
1255 if (attr !=
nullptr)
1266 return (attr !=
nullptr) ? 0 : EINVAL;
1271 int result = EINVAL;
1273 if (cond !=
nullptr)
1284 int result = EINVAL;
1286 if (cond !=
nullptr)
1290 HandleOf(cond)->~ConditionVariable();
1303 if ((cond ==
nullptr) || (mutex ==
nullptr) || (mutex->
__handle ==
nullptr))
1323 if ((cond ==
nullptr) || (mutex ==
nullptr) || (mutex->
__handle ==
nullptr) || (abstime ==
nullptr))
1334 result = signaled ? 0 : ETIMEDOUT;
1342 int result = EINVAL;
1344 if (cond !=
nullptr)
1355 int result = EINVAL;
1357 if (cond !=
nullptr)
1371 int result = EINVAL;
1373 if (attr !=
nullptr)
1384 return (attr !=
nullptr) ? 0 : EINVAL;
1389 int result = EINVAL;
1391 if (rwlock !=
nullptr)
1403 int result = EINVAL;
1405 if (rwlock !=
nullptr)
1420 int result = EINVAL;
1422 if (rwlock !=
nullptr)
1433 int result = EINVAL;
1435 if (rwlock !=
nullptr)
1445 int result = EINVAL;
1447 if ((rwlock !=
nullptr) && (abstime !=
nullptr))
1450 result = locked ? 0 : ETIMEDOUT;
1458 int result = EINVAL;
1460 if (rwlock !=
nullptr)
1472 int result = EINVAL;
1474 if (rwlock !=
nullptr)
1492 int result = EINVAL;
1494 if ((rwlock !=
nullptr) && (abstime !=
nullptr))
1512 int result = EINVAL;
1514 if ((rwlock !=
nullptr) && (rwlock->
__handle !=
nullptr))
1540 int result = EINVAL;
1542 if (lock !=
nullptr)
1560 int result = EINVAL;
1562 if (lock !=
nullptr)
1577 int result = EINVAL;
1579 if ((lock !=
nullptr) && (lock->
__handle !=
nullptr))
1590 int result = EINVAL;
1592 if ((lock !=
nullptr) && (lock->
__handle !=
nullptr))
1602 int result = EINVAL;
1604 if ((lock !=
nullptr) && (lock->
__handle !=
nullptr))
1618 int result = EINVAL;
1620 if (attr !=
nullptr)
1631 return (attr !=
nullptr) ? 0 : EINVAL;
1637 int result = EINVAL;
1639 if ((barrier !=
nullptr) && (count != 0U))
1650 int result = EINVAL;
1652 if (barrier !=
nullptr)
1667 int result = EINVAL;
1669 if ((barrier !=
nullptr) && (barrier->
__handle !=
nullptr))
1684 if ((once_control ==
nullptr) || (init_routine ==
nullptr))
1730 int result = EINVAL;
1743 s_Keys[i].destructor = destructor;
1755 int result = EINVAL;
1763 s_Keys[key].used =
false;
1764 s_Keys[key].destructor =
nullptr;
1774 int result = EINVAL;
1780 if (ctrl ==
nullptr)
1786 ctrl->
tsd[key] =
const_cast<void *
>(value);
1796 void *result =
nullptr;
1802 if (ctrl !=
nullptr)
1804 result = ctrl->
tsd[key];
static void __stk_dmb()
Hardware memory barrier: ensures visibility across cores and bus masters.
Top-level STK include. Provides the Kernel class template and all built-in task-switching strategies.
#define STK_VIRT_DTOR
Makes destructors virtual and compliant to strict rules if STK_STRICT_COMPLIANCY=0.
Collection of synchronization primitives (stk::sync namespace).
C language binding/interface for SuperTinyKernel RTOS.
C language binding for stk::memory::BlockMemoryPool.
void * malloc(size_t size)
A minimal, POSIX-named pthreads-style API for STK. The public interface needs only stk_c....
stk::hw::CriticalSection::ScopedLock CsLock
void * malloc(std::size_t size)
stk_task_t * stk_task_create_user(stk_task_entry_t entry, void *arg, stk_word_t *stack, uint32_t stack_size)
Create user-mode task.
void stk_task_set_name(stk_task_t *tsk, const char *tname)
Assign human-readable task name (for tracing/debugging).
struct stk_kernel_t stk_kernel_t
Opaque handle to a kernel instance.
#define STK_ALIGN_MASK
Alignment mask.
void stk_kernel_add_task(stk_kernel_t *k, stk_task_t *tsk)
Add task to non-HRT kernel (static or dynamic).
uintptr_t stk_word_t
CPU register type.
#define STK_C_ASSERT(e)
Assertion macro used inside STK C bindings.
int64_t stk_time_t
Time value.
bool stk_blockpool_free(stk_blockpool_t *pool, void *ptr)
Return a previously allocated block to the pool.
void * stk_blockpool_try_alloc(stk_blockpool_t *pool)
Non-blocking allocation attempt.
stk_blockpool_t * stk_blockpool_create_static(size_t capacity, size_t raw_block_size, uint8_t *storage, size_t storage_size, const char *name)
Create a block pool backed by caller-supplied (external) storage.
#define STK_BLOCKPOOL_STORAGE_DECL(name, capacity, raw_block_size)
Declare a correctly sized and aligned external storage array.
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
Try to acquire the write lock without blocking.
int pthread_condattr_destroy(pthread_condattr_t *attr)
Destroy a condition variable attributes object (no-op).
int pthread_attr_init(pthread_attr_t *attr)
Initialize a thread attributes object with default values (default stack size, no external stack,...
int pthread_mutex_lock(pthread_mutex_t *mutex)
Lock a mutex, blocking until it becomes available.
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *)
Initialize a read-write lock.
int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abstime)
Acquire the write lock with an absolute deadline.
int pthread_once(pthread_once_t *once_control, void(*init_routine)(void))
Call init_routine exactly once for a given once_control, no matter how many threads call pthread_once...
#define PTHREAD_DESTRUCTOR_ITERATIONS
Maximum number of passes over a finishing thread's keys made while destructors keep setting new non-N...
int pthread_cond_signal(pthread_cond_t *cond)
Wake one thread waiting on cond (no effect if none is waiting).
int pthread_setspecific(pthread_key_t key, const void *value)
Set the calling thread's value for key.
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
Destroy a mutex attributes object (no-op; no owned resources).
void pthread_exit(void *retval)
Terminate the calling thread.
int pthread_mutex_trylock(pthread_mutex_t *mutex)
Try to lock a mutex without blocking.
int pthread_join(pthread_t thread, void **retval)
Block until the given joinable thread finishes, then reclaim its resources.
#define PTHREAD_MUTEX_DEFAULT
#define PTHREAD_CREATE_PRIVILEGED_NP
int pthread_condattr_init(pthread_condattr_t *attr)
Initialize a condition variable attributes object (no settable properties).
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
Get the current detach-state setting.
#define PTHREAD_CREATE_DETACHED
int pthread_spin_unlock(pthread_spinlock_t *lock)
Release a spinlock held by the calling thread.
int pthread_mutex_destroy(pthread_mutex_t *mutex)
Destroy a mutex, releasing the underlying STK mutex object.
#define STK_C_PTHREAD_DEFAULT_STACK_WORDS
Default per-thread stack size in stk_word_t units, used when pthread_attr_t does not specify a stack ...
#define PTHREAD_PROCESS_PRIVATE
#define STK_C_PTHREAD_KEYS_MAX
Maximum number of concurrently-alive pthread_key_t's (default: 8).
int pthread_attr_destroy(pthread_attr_t *attr)
Destroy a thread attributes object (no-op; no owned resources).
pthread_t pthread_self(void)
Return the calling thread's own handle.
int pthread_spin_lock(pthread_spinlock_t *lock)
Acquire the spinlock, spinning until available.
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
Acquire the lock for exclusive writing. Blocks until available.
int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime)
Lock with an absolute deadline.
#define PTHREAD_MUTEX_RECURSIVE
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Initialize a mutex.
#define STK_C_PTHREAD_REAPER_STACK_WORDS
Stack size (in stk_word_t units) for the internal reaper task that reclaims detached-thread resources...
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
Destroy a read-write lock attributes object (no-op).
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
Destroy a read-write lock, releasing the underlying STK object.
int pthread_detach(pthread_t thread)
Mark a thread as detached.
unsigned int pthread_key_t
A thread-specific data key.
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
Release a read or write hold, whichever the calling thread holds.
int pthread_attr_setprivileged_np(pthread_attr_t *attr, int mode)
Non-portable: select the STK access mode of threads created with attr.
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type)
Get the mutex type stored in attr.
struct pthread_stk_ctrl_t * pthread_t
Opaque thread handle.
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
Set the requested stack size in bytes.
#define PTHREAD_BARRIER_SERIAL_THREAD
Returned by pthread_barrier_wait() to exactly one arbitrary caller per round; all others receive 0....
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
Set the mutex type.
int pthread_barrier_wait(pthread_barrier_t *barrier)
Block until count threads have called this function, then release them all together; the barrier rese...
int pthread_attr_getprivileged_np(const pthread_attr_t *attr, int *mode)
Non-portable: get the access mode set in attr.
int pthread_spin_destroy(pthread_spinlock_t *lock)
Destroy a spinlock.
void stk_pthread_bind_kernel(stk_kernel_t *kernel)
Bind the STK kernel instance that pthread_create() will add new threads to.
int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *, unsigned int count)
Initialize a barrier for count participating threads.
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Atomically unlock mutex and wait for a signal; re-locks mutex before returning.
int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize)
Supply an external, caller-owned stack buffer for the thread.
int pthread_mutex_unlock(pthread_mutex_t *mutex)
Unlock a mutex held by the calling thread.
int pthread_equal(pthread_t t1, pthread_t t2)
Compare two thread handles for equality.
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
Initialize a read-write lock attributes object (no settable properties).
int pthread_barrierattr_init(pthread_barrierattr_t *attr)
Initialize a barrier attributes object (no settable properties).
int pthread_cond_destroy(pthread_cond_t *cond)
Destroy a condition variable, releasing the underlying STK object.
int pthread_spin_init(pthread_spinlock_t *lock, int pshared)
Initialize a spinlock.
#define PTHREAD_MUTEX_NORMAL
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
Try to acquire the read lock without blocking.
#define PTHREAD_MUTEX_ERRORCHECK
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
As pthread_cond_wait(), with an absolute deadline.
int pthread_barrierattr_destroy(pthread_barrierattr_t *attr)
Destroy a barrier attributes object (no-op).
#define STK_C_PTHREAD_MAX_THREADS
Maximum number of concurrently-alive pthread_t's (default: 8).
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
Acquire the lock for shared reading. Blocks until available.
int pthread_spin_trylock(pthread_spinlock_t *lock)
Try to acquire the spinlock without blocking.
void * pthread_getspecific(pthread_key_t key)
Get the calling thread's value for key.
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *)
Initialize a condition variable.
int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abstime)
Acquire the read lock with an absolute deadline.
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
Get the stack size in bytes that threads created with attr will use.
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
Create and start a new thread.
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
Set PTHREAD_CREATE_JOINABLE or PTHREAD_CREATE_DETACHED.
int pthread_barrier_destroy(pthread_barrier_t *barrier)
Destroy a barrier, releasing the underlying STK barrier object.
int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize)
Get the previously-set external stack (stackaddr is NULL if none set).
#define PTHREAD_CREATE_USER_NP
int pthread_key_delete(pthread_key_t key)
Free a thread-specific data key.
int pthread_yield(void)
Voluntarily give up the CPU to another ready task (cooperative yield), then resume once rescheduled.
int pthread_key_create(pthread_key_t *key, void(*destructor)(void *))
Allocate a new thread-specific data key.
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
Initialize a mutex attributes object with default values (PTHREAD_MUTEX_DEFAULT).
#define PTHREAD_CREATE_JOINABLE
int pthread_cond_broadcast(pthread_cond_t *cond)
Wake all threads waiting on cond (no effect if none is waiting).
Namespace of STK package.
uintptr_t Word
Native processor word type.
static void Yield()
Notify scheduler to switch to the next runnable task.
static T * ConstructIn(Mem &mem, Args &&... args)
Construct object T in-place inside a C memory container.
static void Sleep(Timeout tick_count)
Put calling process into a sleep state.
static void SleepMs(Timeout ms)
Put calling process into a sleep state.
EAccessMode
Hardware access modes by the task.
@ ACCESS_USER
Unprivileged access mode (access to some hardware is restricted, see CPU manual for details)....
@ ACCESS_PRIVILEGED
Privileged access mode (access to hardware is fully unrestricted).
static Time GetTimeNowMs()
Get current time in milliseconds since kernel start.
int32_t Timeout
Timeout time (ticks).
static constexpr Weight DEFAULT_WEIGHT
Weight value: default weight of value (1) (see SwitchStrategySmoothWeightedRoundRobin).
static constexpr Timeout WAIT_INFINITE
Timeout value: block indefinitely until the synchronization object is signaled.
static Timeout GetTicksFromMsClampedToTimeout(Timeout ms)
Convert milliseconds to ticks and clamp the result to a Timeout type.
static KeyEntry s_Keys[STK_C_PTHREAD_KEYS_MAX]
static void RunKeyDestructors(ThreadCtrl *ctrl)
static T LoadAcquire(T *p)
static void ReleaseThreadResources(ThreadCtrl *ctrl)
static void MaybeReap(ThreadCtrl *ctrl)
static sync::ConditionVariable * EnsureCond(pthread_cond_t *c)
static ThreadCtrl s_Threads[STK_C_PTHREAD_MAX_THREADS]
static ThreadCtrl * CurrentCtrlOrAdopt()
static sync::Mutex * EnsureMutex(pthread_mutex_t *m)
static ThreadCtrl * AcquireThreadSlot()
static stk_word_t s_ReaperStack[STK_C_PTHREAD_REAPER_STACK_WORDS]
static stk_kernel_t * s_BoundKernel
static bool IsMutexOwner(const sync::Mutex *m)
static void EnsureReaper()
static std::size_t s_ReapHead
static sync::Mutex * HandleOf(pthread_mutex_t *o)
static stk_blockpool_t * EnsureStackPool()
static ThreadCtrl * CurrentCtrl()
static sync::Semaphore * s_ReapSem
constexpr int kOnceRunning
pthread_stk_ctrl_t ThreadCtrl
static ThreadCtrl * s_ReapQueue[STK_C_PTHREAD_MAX_THREADS]
uint8_t data[sizeof(sync::Semaphore)]
static void ReaperEntry(void *arg)
static T * EnsureObject(void **slot, Mem &mem)
static Timeout TimespecToRelativeTimeout(const struct timespec *abstime)
static void WaitForTaskExit(ThreadCtrl *ctrl)
static void EnqueueReap(ThreadCtrl *ctrl)
static void StoreRelease(T *p, T v)
static std::size_t s_ReapCount
static int PreLockCheck(const pthread_mutex_t *pm, const sync::Mutex *m, int errorcheck_code)
constexpr std::size_t kDefaultStackBytes
static bool AllocateStack(ThreadCtrl *ctrl, const pthread_attr_t *attr, std::size_t stack_bytes)
static sync::Mutex * EnsureOnceMutex(pthread_once_t *o)
static bool IsValidMutexType(int type)
static stk_task_t * s_ReaperTask
static struct stk::pthread::@154260026337266142101324335010026147170101120162 s_ReapSemBuf
static ThreadCtrl * DequeueReap()
static sync::RWMutex * EnsureRWLock(pthread_rwlock_t *rw)
static stk_blockpool_t * s_StackPool
static IKernel * ToKernel(stk_kernel_t *k)
static bool IsKeyUsed(pthread_key_t key)
RAII instance that enters the critical section on construction and exits it on destruction.
Atomic busy-wait lock used as the global cross-core synchronisation primitive inside CriticalSection.
Interface for a user task.
Interface for the implementation of the kernel of the scheduler. It supports Soft and Hard Real-Time ...
virtual void AddTask(ITask *user_task)=0
Add user task.
virtual void ScheduleTaskRemoval(ITask *user_task)=0
Schedule task removal from scheduling (exit).
static IKernelService * GetInstance()
Get CPU-local instance of the kernel service.
Cyclic barrier that blocks a fixed-size group of tasks until all of them have arrived.
Condition Variable primitive for signaling between tasks based on specific predicates.
void NotifyOne()
Wake one waiting task.
bool Wait(IMutex &mutex, Timeout timeout_ticks=WAIT_INFINITE)
Wait for a signal.
void NotifyAll()
Wake all waiting tasks.
Binary synchronization event (signaled / non-signaled) primitive.
bool Set()
Set event to signaled state.
bool Wait(Timeout timeout_ticks=WAIT_INFINITE)
Wait until event becomes signaled or the timeout expires.
Recursive mutex primitive that allows the same thread to acquire the lock multiple times.
bool TimedLock(Timeout timeout_ticks)
Acquire lock.
bool TryLock()
Acquire the lock.
TId GetOwner() const
Get owner of the mutex.
void Unlock() override
Release lock.
void Lock() override
Acquire lock.
static const uint16_t RECURSION_MAX
maximum nesting depth
uint16_t GetRecursionCount() const
Get current recursion depth.
Reader-Writer Lock synchronization primitive for non-recursive shared and exclusive access.
void Lock() override
Acquire the lock for exclusive writing (IMutex interface).
bool TimedReadLock(Timeout timeout_ticks)
Acquire the lock for shared reading with a timeout.
void ReadLock()
Acquire the lock for shared reading.
bool TryReadLock()
Attempt to acquire the lock for shared reading without blocking.
Counting semaphore primitive for resource management and signaling.
Thread creation attributes.
size_t __stack_bytes
0 = use STK_C_PTHREAD_DEFAULT_STACK_WORDS.
int __detachstate
PTHREAD_CREATE_JOINABLE / _DETACHED.
stk_word_t * __ext_stack
Caller-supplied stack, or NULL.
int __privileged
PTHREAD_CREATE_USER_NP (default) / _PRIVILEGED_NP.
int __type
PTHREAD_MUTEX_NORMAL / DEFAULT / RECURSIVE / ERRORCHECK.
int __type
PTHREAD_MUTEX_* type; 0 (NORMAL) when statically initialized.
stk_mutex_mem_t __mem
In-place storage for the STK mutex object.
void * __handle
Object constructed in __mem, or NULL if not yet constructed.
Condition variable attributes (currently no settable properties).
int __reserved
Unused (no settable properties); reserved for future use.
A pthread condition variable.
void * __handle
Object constructed in __mem, or NULL if not yet constructed.
stk_cv_mem_t __mem
In-place storage for the STK condition variable object.
Read-write lock attributes (currently no settable properties).
int __reserved
Unused (no settable properties); reserved for future use.
A pthread read-write lock.
volatile bool __wrlocked
True while held for writing; selects Unlock() vs ReadUnlock() on release.
void * __handle
Object constructed in __mem, or NULL if not yet constructed.
stk_rwmutex_mem_t __mem
In-place storage for the STK rwmutex object.
struct pthread_spinlock_t::@072117035232205037233337242056154122155161307376 __mem
In-place storage for the STK spinlock object.
void * __handle
Object constructed in __mem, or NULL if not yet constructed.
Barrier attributes (currently no settable properties).
int __reserved
Unused (no settable properties); reserved for future use.
stk_barrier_mem_t __mem
In-place storage for the STK barrier object.
void * __handle
Object constructed in __mem, or NULL if not yet constructed.
A pthread_once() control object.
stk_mutex_mem_t __mem
In-place storage for the guard mutex.
void * __handle
Guard mutex constructed in __mem, or NULL if not yet constructed.
int __state
0 = not started, 1 = running, 2 = done.
const Word * GetStack() const override
Get pointer to the stack memory.
EAccessMode GetAccessMode() const override
Get pointer to the stack memory.
void Run() override
Entry point of the user task.
size_t GetStackSize() const override
Get number of elements of the stack memory array.
void Initialize(pthread_stk_ctrl_t *ctrl, stk_word_t *stack, size_t stack_size, EAccessMode mode)
int32_t GetWeight() const override
Get static base weight of the task.
pthread_stk_ctrl_t * m_ctrl
STK_NONCOPYABLE_CLASS(PthreadTask)
const char * GetTraceName() const override
Get task trace name set by application.
STK_VIRT_DTOR ~PthreadTask()=default
Destructor.
void OnExit() override
Called by the kernel before removal from the scheduling (see stk::KERNEL_DYNAMIC).
struct pthread_stk_ctrl_t::@024110347346021317207143067073371172206260032255 done_event_buf
uint8_t data[sizeof(stk::sync::Event)]
void * tsd[STK_C_PTHREAD_KEYS_MAX]
void *(* start_routine)(void *)
stk::sync::Event * done_event
stk::pthread::PthreadTask task
void(* destructor)(void *)