SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk::pthread Namespace Reference

Classes

class  PthreadTask
struct  KeyEntry

Typedefs

using ThreadCtrl = pthread_stk_ctrl_t

Functions

static IKernel * ToKernel (stk_kernel_t *k)
template<typename T>
static T LoadAcquire (T *p)
template<typename T>
static void StoreRelease (T *p, T v)
template<typename T, typename Mem>
static T * EnsureObject (void **slot, Mem &mem)
static sync::Mutex * HandleOf (pthread_mutex_t *o)
static sync::Mutex * HandleOf (pthread_once_t *o)
static sync::ConditionVariable * HandleOf (pthread_cond_t *o)
static sync::RWMutex * HandleOf (pthread_rwlock_t *o)
static hw::SpinLock * HandleOf (pthread_spinlock_t *o)
static sync::Barrier * HandleOf (pthread_barrier_t *o)
static void RunKeyDestructors (ThreadCtrl *ctrl)
 STK_BLOCKPOOL_STORAGE_DECL (s_PthreadStackStorage, STK_C_PTHREAD_MAX_THREADS, kDefaultStackBytes)
static stk_blockpool_t * EnsureStackPool ()
static void ReleaseThreadResources (ThreadCtrl *ctrl)
static void WaitForTaskExit (ThreadCtrl *ctrl)
static void ReaperEntry (void *arg)
static void EnsureReaper ()
static void EnqueueReap (ThreadCtrl *ctrl)
static ThreadCtrl * DequeueReap ()
static void MaybeReap (ThreadCtrl *ctrl)
static ThreadCtrl * AcquireThreadSlot ()
static bool AllocateStack (ThreadCtrl *ctrl, const pthread_attr_t *attr, std::size_t stack_bytes)
static Timeout TimespecToRelativeTimeout (const struct timespec *abstime)
static sync::Mutex * EnsureMutex (pthread_mutex_t *m)
static bool IsMutexOwner (const sync::Mutex *m)
static bool IsValidMutexType (int type)
static int PreLockCheck (const pthread_mutex_t *pm, const sync::Mutex *m, int errorcheck_code)
static sync::ConditionVariable * EnsureCond (pthread_cond_t *c)
static sync::RWMutex * EnsureRWLock (pthread_rwlock_t *rw)
static sync::Mutex * EnsureOnceMutex (pthread_once_t *o)
static ThreadCtrl * CurrentCtrl ()
static ThreadCtrl * CurrentCtrlOrAdopt ()
static bool IsKeyUsed (pthread_key_t key)

Variables

constexpr std::size_t kDefaultStackBytes
constexpr int kOnceRunning = 1
constexpr int kOnceDone = 2
static ThreadCtrl s_Threads [STK_C_PTHREAD_MAX_THREADS]
static stk_kernel_t * s_BoundKernel = nullptr
static stk_blockpool_t * s_StackPool = nullptr
static ThreadCtrl * s_ReapQueue [STK_C_PTHREAD_MAX_THREADS]
static std::size_t s_ReapHead = 0U
static std::size_t s_ReapCount = 0U
static sync::Semaphore * s_ReapSem = nullptr
struct { 
   uint8_t   stk::pthread::data [sizeof(sync::Semaphore)] 
} s_ReapSemBuf
static stk_task_t * s_ReaperTask = nullptr
static stk_word_t s_ReaperStack [STK_C_PTHREAD_REAPER_STACK_WORDS]
static KeyEntry s_Keys [STK_C_PTHREAD_KEYS_MAX]

Typedef Documentation

◆ ThreadCtrl

Function Documentation

◆ AcquireThreadSlot()

ThreadCtrl * stk::pthread::AcquireThreadSlot ( )
static

Definition at line 406 of file stk_c_pthread.cpp.

407{
408 ThreadCtrl *result = nullptr;
409
410 {
411 const CsLock cs_;
412
413 for (std::size_t i = 0U; (result == nullptr) && (i < STK_C_PTHREAD_MAX_THREADS); ++i)
414 {
415 if (!s_Threads[i].busy)
416 {
417 s_Threads[i].Reset();
418 s_Threads[i].busy = true;
419 result = &s_Threads[i];
420 }
421 }
422 }
423
424 return result;
425}
stk::hw::CriticalSection::ScopedLock CsLock
#define STK_C_PTHREAD_MAX_THREADS
Maximum number of concurrently-alive pthread_t's (default: 8).
static ThreadCtrl s_Threads[STK_C_PTHREAD_MAX_THREADS]
pthread_stk_ctrl_t ThreadCtrl

References s_Threads, and STK_C_PTHREAD_MAX_THREADS.

Referenced by CurrentCtrlOrAdopt(), and pthread_create().

Here is the caller graph for this function:

◆ AllocateStack()

bool stk::pthread::AllocateStack ( ThreadCtrl * ctrl,
const pthread_attr_t * attr,
std::size_t stack_bytes )
static

Definition at line 483 of file stk_c_pthread.cpp.

484{
485 if ((attr != nullptr) && (attr->__ext_stack != nullptr))
486 {
487 ctrl->stack = attr->__ext_stack;
488 ctrl->stack_owned = false;
489 ctrl->stack_from_pool = false;
490 }
491 else
492 {
493 void *blk = nullptr;
494
495 if (stack_bytes == kDefaultStackBytes)
496 {
497 stk_blockpool_t *const pool = EnsureStackPool();
498 if (pool != nullptr)
499 {
500 blk = stk_blockpool_try_alloc(pool);
501 }
502 }
503
504 if (blk != nullptr)
505 {
506 ctrl->stack = static_cast<stk_word_t *>(blk);
507 ctrl->stack_owned = true;
508 ctrl->stack_from_pool = true;
509 }
510 else
511 {
512 ctrl->stack = static_cast<stk_word_t *>(malloc(stack_bytes));
513 ctrl->stack_owned = true;
514 ctrl->stack_from_pool = false;
515 }
516 }
517
518 return (ctrl->stack != nullptr);
519}
void * malloc(size_t size)
uintptr_t stk_word_t
CPU register type.
Definition stk_c.h:99
void * stk_blockpool_try_alloc(stk_blockpool_t *pool)
Non-blocking allocation attempt.
static stk_blockpool_t * EnsureStackPool()
constexpr std::size_t kDefaultStackBytes
stk_word_t * __ext_stack
Caller-supplied stack, or NULL.

References pthread_attr_t::__ext_stack, EnsureStackPool(), kDefaultStackBytes, malloc(), pthread_stk_ctrl_t::stack, pthread_stk_ctrl_t::stack_from_pool, pthread_stk_ctrl_t::stack_owned, and stk_blockpool_try_alloc().

Referenced by pthread_create().

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

◆ CurrentCtrl()

ThreadCtrl * stk::pthread::CurrentCtrl ( )
static

Definition at line 645 of file stk_c_pthread.cpp.

646{
647 return hw::GetTlsPtr<ThreadCtrl>();
648}

Referenced by CurrentCtrlOrAdopt(), pthread_exit(), pthread_getspecific(), and pthread_join().

Here is the caller graph for this function:

◆ CurrentCtrlOrAdopt()

ThreadCtrl * stk::pthread::CurrentCtrlOrAdopt ( )
static

Definition at line 657 of file stk_c_pthread.cpp.

658{
659 ThreadCtrl *ctrl = CurrentCtrl();
660 if (ctrl == nullptr)
661 {
662 ctrl = AcquireThreadSlot();
663 if (ctrl != nullptr)
664 {
665 ctrl->adopted = true;
666 ctrl->detached = true; // not joinable, never handed to the reaper
667 hw::SetTlsPtr(static_cast<void *>(ctrl));
668 }
669 }
670
671 return ctrl;
672}
static ThreadCtrl * AcquireThreadSlot()
static ThreadCtrl * CurrentCtrl()

References AcquireThreadSlot(), pthread_stk_ctrl_t::adopted, CurrentCtrl(), and pthread_stk_ctrl_t::detached.

Referenced by pthread_self(), and pthread_setspecific().

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

◆ DequeueReap()

ThreadCtrl * stk::pthread::DequeueReap ( )
static

Definition at line 345 of file stk_c_pthread.cpp.

346{
347 ThreadCtrl *result = nullptr;
348
349 {
350 const CsLock cs_;
351
352 if (s_ReapCount > 0U)
353 {
354 result = s_ReapQueue[s_ReapHead];
356 --s_ReapCount;
357 }
358 }
359
360 return result;
361}
static std::size_t s_ReapHead
static ThreadCtrl * s_ReapQueue[STK_C_PTHREAD_MAX_THREADS]
static std::size_t s_ReapCount

References s_ReapCount, s_ReapHead, s_ReapQueue, and STK_C_PTHREAD_MAX_THREADS.

Referenced by ReaperEntry().

Here is the caller graph for this function:

◆ EnqueueReap()

void stk::pthread::EnqueueReap ( ThreadCtrl * ctrl)
static

Definition at line 330 of file stk_c_pthread.cpp.

331{
332 STK_C_ASSERT(s_ReaperTask != nullptr);
333
334 const CsLock cs_;
335
338 {
339 const std::size_t tail = (s_ReapHead + s_ReapCount) % STK_C_PTHREAD_MAX_THREADS;
340 s_ReapQueue[tail] = ctrl;
341 ++s_ReapCount;
342 }
343}
#define STK_C_ASSERT(e)
Assertion macro used inside STK C bindings.
Definition stk_c.h:80
static stk_task_t * s_ReaperTask

References s_ReapCount, s_ReaperTask, s_ReapHead, s_ReapQueue, STK_C_ASSERT, and STK_C_PTHREAD_MAX_THREADS.

Referenced by MaybeReap().

Here is the caller graph for this function:

◆ EnsureCond()

sync::ConditionVariable * stk::pthread::EnsureCond ( pthread_cond_t * c)
static

Definition at line 624 of file stk_c_pthread.cpp.

625{
627}
static T * EnsureObject(void **slot, Mem &mem)
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.

References pthread_cond_t::__handle, pthread_cond_t::__mem, and EnsureObject().

Referenced by pthread_cond_broadcast(), pthread_cond_signal(), pthread_cond_timedwait(), and pthread_cond_wait().

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

◆ EnsureMutex()

sync::Mutex * stk::pthread::EnsureMutex ( pthread_mutex_t * m)
static

Definition at line 583 of file stk_c_pthread.cpp.

584{
586}
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.

References pthread_mutex_t::__handle, pthread_mutex_t::__mem, and EnsureObject().

Referenced by pthread_mutex_lock(), pthread_mutex_timedlock(), and pthread_mutex_trylock().

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

◆ EnsureObject()

template<typename T, typename Mem>
T * stk::pthread::EnsureObject ( void ** slot,
Mem & mem )
static

Definition at line 226 of file stk_c_pthread.cpp.

227{
228 void *h = LoadAcquire(slot);
229 if (h == nullptr)
230 {
231 const CsLock cs_;
232
233 h = *slot; // re-check under the lock
234 if (h == nullptr)
235 {
236 h = ConstructIn<T>(mem);
237 StoreRelease(slot, h);
238 }
239 }
240
241 return static_cast<T *>(h);
242}
static T * ConstructIn(Mem &mem, Args &&... args)
Construct object T in-place inside a C memory container.
Definition stk_c.h:2198
static T LoadAcquire(T *p)
static void StoreRelease(T *p, T v)

References stk::ConstructIn(), LoadAcquire(), and StoreRelease().

Referenced by EnsureCond(), EnsureMutex(), EnsureOnceMutex(), and EnsureRWLock().

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

◆ EnsureOnceMutex()

sync::Mutex * stk::pthread::EnsureOnceMutex ( pthread_once_t * o)
static

Definition at line 634 of file stk_c_pthread.cpp.

635{
637}
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.

References pthread_once_t::__handle, pthread_once_t::__mem, and EnsureObject().

Referenced by pthread_once().

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

◆ EnsureReaper()

void stk::pthread::EnsureReaper ( )
static

Definition at line 309 of file stk_c_pthread.cpp.

310{
311 if (s_ReaperTask == nullptr)
312 {
313 STK_C_ASSERT(s_BoundKernel != nullptr);
314
315 if (s_ReapSem == nullptr)
316 {
318 }
319
322 if (s_ReaperTask != nullptr)
323 {
324 stk_task_set_name(s_ReaperTask, "pthread_reaper");
326 }
327 }
328}
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.
Definition stk_c.cpp:567
void stk_task_set_name(stk_task_t *tsk, const char *tname)
Assign human-readable task name (for tracing/debugging).
Definition stk_c.cpp:595
void stk_kernel_add_task(stk_kernel_t *k, stk_task_t *tsk)
Add task to non-HRT kernel (static or dynamic).
Definition stk_c.cpp:428
#define STK_C_PTHREAD_REAPER_STACK_WORDS
Stack size (in stk_word_t units) for the internal reaper task that reclaims detached-thread resources...
static stk_word_t s_ReaperStack[STK_C_PTHREAD_REAPER_STACK_WORDS]
static stk_kernel_t * s_BoundKernel
static sync::Semaphore * s_ReapSem
static void ReaperEntry(void *arg)
static struct stk::pthread::@154260026337266142101324335010026147170101120162 s_ReapSemBuf

References stk::ConstructIn(), ReaperEntry(), s_BoundKernel, s_ReaperStack, s_ReaperTask, s_ReapSem, s_ReapSemBuf, STK_C_ASSERT, STK_C_PTHREAD_REAPER_STACK_WORDS, stk_kernel_add_task(), stk_task_create_user(), and stk_task_set_name().

Referenced by stk_pthread_bind_kernel().

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

◆ EnsureRWLock()

sync::RWMutex * stk::pthread::EnsureRWLock ( pthread_rwlock_t * rw)
static

Definition at line 629 of file stk_c_pthread.cpp.

630{
632}
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.

References pthread_rwlock_t::__handle, pthread_rwlock_t::__mem, and EnsureObject().

Referenced by pthread_rwlock_rdlock(), pthread_rwlock_timedrdlock(), pthread_rwlock_timedwrlock(), pthread_rwlock_tryrdlock(), pthread_rwlock_trywrlock(), and pthread_rwlock_wrlock().

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

◆ EnsureStackPool()

stk_blockpool_t * stk::pthread::EnsureStackPool ( )
static

Definition at line 268 of file stk_c_pthread.cpp.

269{
271 if (pool == nullptr)
272 {
273 const CsLock cs_;
274
275 pool = s_StackPool;
276 if (pool == nullptr)
277 {
281 reinterpret_cast<uint8_t *>(s_PthreadStackStorage),
282 sizeof(s_PthreadStackStorage),
283 "pthread_stacks");
285 }
286 }
287
288 return pool;
289}
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.
static stk_blockpool_t * s_StackPool

References kDefaultStackBytes, LoadAcquire(), s_StackPool, stk_blockpool_create_static(), STK_C_PTHREAD_MAX_THREADS, and StoreRelease().

Referenced by AllocateStack().

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

◆ HandleOf() [1/6]

sync::Barrier * stk::pthread::HandleOf ( pthread_barrier_t * o)
inlinestatic

Definition at line 250 of file stk_c_pthread.cpp.

250{ return static_cast<sync::Barrier *>(o->__handle); }
Cyclic barrier that blocks a fixed-size group of tasks until all of them have arrived.
void * __handle
Object constructed in __mem, or NULL if not yet constructed.

References pthread_barrier_t::__handle.

◆ HandleOf() [2/6]

sync::ConditionVariable * stk::pthread::HandleOf ( pthread_cond_t * o)
inlinestatic

Definition at line 247 of file stk_c_pthread.cpp.

247{ return static_cast<sync::ConditionVariable *>(o->__handle); }
Condition Variable primitive for signaling between tasks based on specific predicates.
Definition stk_sync_cv.h:68

References pthread_cond_t::__handle.

◆ HandleOf() [3/6]

sync::Mutex * stk::pthread::HandleOf ( pthread_mutex_t * o)
inlinestatic

Definition at line 245 of file stk_c_pthread.cpp.

245{ return static_cast<sync::Mutex *>(o->__handle); }
Recursive mutex primitive that allows the same thread to acquire the lock multiple times.

References pthread_mutex_t::__handle.

Referenced by pthread_barrier_destroy(), pthread_barrier_wait(), pthread_cond_destroy(), pthread_cond_timedwait(), pthread_cond_wait(), pthread_mutex_destroy(), pthread_mutex_unlock(), pthread_rwlock_destroy(), pthread_rwlock_unlock(), pthread_spin_destroy(), pthread_spin_lock(), pthread_spin_trylock(), and pthread_spin_unlock().

Here is the caller graph for this function:

◆ HandleOf() [4/6]

sync::Mutex * stk::pthread::HandleOf ( pthread_once_t * o)
inlinestatic

Definition at line 246 of file stk_c_pthread.cpp.

246{ return static_cast<sync::Mutex *>(o->__handle); }

References pthread_once_t::__handle.

◆ HandleOf() [5/6]

sync::RWMutex * stk::pthread::HandleOf ( pthread_rwlock_t * o)
inlinestatic

Definition at line 248 of file stk_c_pthread.cpp.

248{ return static_cast<sync::RWMutex *>(o->__handle); }
Reader-Writer Lock synchronization primitive for non-recursive shared and exclusive access.

References pthread_rwlock_t::__handle.

◆ HandleOf() [6/6]

hw::SpinLock * stk::pthread::HandleOf ( pthread_spinlock_t * o)
inlinestatic

Definition at line 249 of file stk_c_pthread.cpp.

249{ return static_cast<hw::SpinLock *>(o->__handle); }
Atomic busy-wait lock used as the global cross-core synchronisation primitive inside CriticalSection.
Definition stk_arch.h:570
void * __handle
Object constructed in __mem, or NULL if not yet constructed.

References pthread_spinlock_t::__handle.

◆ IsKeyUsed()

bool stk::pthread::IsKeyUsed ( pthread_key_t key)
inlinestatic

Definition at line 687 of file stk_c_pthread.cpp.

688{
689 return (key < STK_C_PTHREAD_KEYS_MAX) && s_Keys[key].used;
690}
#define STK_C_PTHREAD_KEYS_MAX
Maximum number of concurrently-alive pthread_key_t's (default: 8).
static KeyEntry s_Keys[STK_C_PTHREAD_KEYS_MAX]

References s_Keys, and STK_C_PTHREAD_KEYS_MAX.

Referenced by pthread_getspecific(), and pthread_setspecific().

Here is the caller graph for this function:

◆ IsMutexOwner()

bool stk::pthread::IsMutexOwner ( const sync::Mutex * m)
inlinestatic

Definition at line 588 of file stk_c_pthread.cpp.

589{
590 return (m->GetOwner() == IKernelService::GetInstance()->GetTid());
591}
static IKernelService * GetInstance()
Get CPU-local instance of the kernel service.
TId GetOwner() const
Get owner of the mutex.

References stk::IKernelService::GetInstance(), and stk::sync::Mutex::GetOwner().

Referenced by PreLockCheck(), pthread_cond_timedwait(), pthread_cond_wait(), pthread_mutex_unlock(), and pthread_once().

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

◆ IsValidMutexType()

bool stk::pthread::IsValidMutexType ( int type)
inlinestatic

Definition at line 593 of file stk_c_pthread.cpp.

594{
595 return (type == PTHREAD_MUTEX_NORMAL) ||
596 (type == PTHREAD_MUTEX_ERRORCHECK) ||
597 (type == PTHREAD_MUTEX_RECURSIVE);
598}
#define PTHREAD_MUTEX_RECURSIVE
#define PTHREAD_MUTEX_NORMAL
#define PTHREAD_MUTEX_ERRORCHECK

References PTHREAD_MUTEX_ERRORCHECK, PTHREAD_MUTEX_NORMAL, and PTHREAD_MUTEX_RECURSIVE.

Referenced by pthread_mutex_init(), and pthread_mutexattr_settype().

Here is the caller graph for this function:

◆ LoadAcquire()

template<typename T>
T stk::pthread::LoadAcquire ( T * p)
inlinestatic

Definition at line 219 of file stk_c_pthread.cpp.

219{ return *static_cast<volatile T *>(p); }

Referenced by EnsureObject(), EnsureStackPool(), and pthread_once().

Here is the caller graph for this function:

◆ MaybeReap()

void stk::pthread::MaybeReap ( ThreadCtrl * ctrl)
static

Definition at line 382 of file stk_c_pthread.cpp.

383{
384 bool do_reap = false;
385
386 {
387 const CsLock cs_;
388
389 if (ctrl->finished && ctrl->detached && !ctrl->reclaimed)
390 {
391 ctrl->reclaimed = true;
392 do_reap = true;
393 }
394 }
395
396 if (do_reap)
397 {
398 EnqueueReap(ctrl);
399 s_ReapSem->Signal();
400 }
401}
static void EnqueueReap(ThreadCtrl *ctrl)

References pthread_stk_ctrl_t::detached, EnqueueReap(), pthread_stk_ctrl_t::finished, pthread_stk_ctrl_t::reclaimed, and s_ReapSem.

Referenced by pthread_detach(), pthread_exit(), and stk::pthread::PthreadTask::Run().

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

◆ PreLockCheck()

int stk::pthread::PreLockCheck ( const pthread_mutex_t * pm,
const sync::Mutex * m,
int errorcheck_code )
static

Definition at line 605 of file stk_c_pthread.cpp.

606{
607 int result = 0;
608
609 if (IsMutexOwner(m))
610 {
612 {
613 result = errorcheck_code;
614 }
615 else
616 {
617 result = (m->GetRecursionCount() >= sync::Mutex::RECURSION_MAX) ? EAGAIN : 0;
618 }
619 }
620
621 return result;
622}
static bool IsMutexOwner(const sync::Mutex *m)
static const uint16_t RECURSION_MAX
maximum nesting depth
uint16_t GetRecursionCount() const
Get current recursion depth.
int __type
PTHREAD_MUTEX_* type; 0 (NORMAL) when statically initialized.

References pthread_mutex_t::__type, stk::sync::Mutex::GetRecursionCount(), IsMutexOwner(), PTHREAD_MUTEX_ERRORCHECK, and stk::sync::Mutex::RECURSION_MAX.

Referenced by pthread_mutex_lock(), pthread_mutex_timedlock(), and pthread_mutex_trylock().

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

◆ ReaperEntry()

void stk::pthread::ReaperEntry ( void * arg)
static

Definition at line 363 of file stk_c_pthread.cpp.

364{
365 for (;;)
366 {
367 STK_C_ASSERT(s_ReapSem != nullptr);
368 (void)s_ReapSem->Wait(); // WAIT_INFINITE
369
370 ThreadCtrl *const ctrl = DequeueReap();
371 if (ctrl != nullptr)
372 {
373 WaitForTaskExit(ctrl);
375 }
376 }
377}
static void ReleaseThreadResources(ThreadCtrl *ctrl)
static void WaitForTaskExit(ThreadCtrl *ctrl)
static ThreadCtrl * DequeueReap()

References DequeueReap(), ReleaseThreadResources(), s_ReapSem, STK_C_ASSERT, and WaitForTaskExit().

Referenced by EnsureReaper().

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

◆ ReleaseThreadResources()

void stk::pthread::ReleaseThreadResources ( ThreadCtrl * ctrl)
static

Definition at line 453 of file stk_c_pthread.cpp.

454{
455 if (ctrl->done_event != nullptr)
456 {
457 ctrl->done_event->~Event();
458 ctrl->done_event = nullptr;
459 }
460
461 if (ctrl->stack_owned && (ctrl->stack != nullptr))
462 {
463 if (ctrl->stack_from_pool)
464 {
466 }
467 else
468 {
469 free(ctrl->stack);
470 }
471 }
472 ctrl->stack = nullptr;
473
474 {
475 const CsLock cs_;
476
477 ctrl->busy = false;
478 }
479}
void free(void *ptr)
bool stk_blockpool_free(stk_blockpool_t *pool, void *ptr)
Return a previously allocated block to the pool.
~Event()
Destructor.
stk::sync::Event * done_event

References pthread_stk_ctrl_t::busy, pthread_stk_ctrl_t::done_event, free(), s_StackPool, pthread_stk_ctrl_t::stack, pthread_stk_ctrl_t::stack_from_pool, pthread_stk_ctrl_t::stack_owned, stk_blockpool_free(), and stk::sync::Event::~Event().

Referenced by pthread_join(), and ReaperEntry().

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

◆ RunKeyDestructors()

void stk::pthread::RunKeyDestructors ( ThreadCtrl * ctrl)
static

Definition at line 699 of file stk_c_pthread.cpp.

700{
701 bool more = true;
702
703 for (int iter = 0; more && (iter < PTHREAD_DESTRUCTOR_ITERATIONS); ++iter)
704 {
705 bool any_ran = false;
706
707 for (std::size_t i = 0U; i < STK_C_PTHREAD_KEYS_MAX; ++i)
708 {
709 void *const value = ctrl->tsd[i];
710
711 if (value != nullptr)
712 {
713 void (*destructor)(void *) = nullptr;
714 {
715 const CsLock cs_;
716
717 if (s_Keys[i].used)
718 {
719 destructor = s_Keys[i].destructor;
720 }
721 }
722
723 ctrl->tsd[i] = nullptr; // clear before calling, per POSIX
724 if (destructor != nullptr)
725 {
726 destructor(value);
727 any_ran = true;
728 }
729 }
730 }
731
732 more = any_ran;
733 }
734}
#define PTHREAD_DESTRUCTOR_ITERATIONS
Maximum number of passes over a finishing thread's keys made while destructors keep setting new non-N...
void * tsd[STK_C_PTHREAD_KEYS_MAX]

References PTHREAD_DESTRUCTOR_ITERATIONS, s_Keys, STK_C_PTHREAD_KEYS_MAX, and pthread_stk_ctrl_t::tsd.

Referenced by pthread_exit(), and stk::pthread::PthreadTask::Run().

Here is the caller graph for this function:

◆ STK_BLOCKPOOL_STORAGE_DECL()

stk::pthread::STK_BLOCKPOOL_STORAGE_DECL ( s_PthreadStackStorage ,
STK_C_PTHREAD_MAX_THREADS ,
kDefaultStackBytes  )

◆ StoreRelease()

template<typename T>
void stk::pthread::StoreRelease ( T * p,
T v )
inlinestatic

Definition at line 220 of file stk_c_pthread.cpp.

220{ *static_cast<volatile T *>(p) = v; }

Referenced by EnsureObject(), EnsureStackPool(), and pthread_once().

Here is the caller graph for this function:

◆ TimespecToRelativeTimeout()

Timeout stk::pthread::TimespecToRelativeTimeout ( const struct timespec * abstime)
static

Definition at line 563 of file stk_c_pthread.cpp.

564{
565 const stk_time_t now_ms = static_cast<stk_time_t>(GetTimeNowMs());
566 const stk_time_t target_ms = (static_cast<stk_time_t>(abstime->tv_sec) * 1000LL) +
567 (static_cast<stk_time_t>(abstime->tv_nsec) / 1000000LL);
568
569 stk_time_t rel_ms = target_ms - now_ms;
570 if (rel_ms < 0LL)
571 {
572 rel_ms = 0LL;
573 }
574 else
575 if (rel_ms > static_cast<stk_time_t>(INT32_MAX))
576 {
577 rel_ms = static_cast<stk_time_t>(INT32_MAX);
578 }
579
580 return GetTicksFromMsClampedToTimeout(static_cast<Timeout>(rel_ms));
581}
int64_t stk_time_t
Time value.
Definition stk_c.h:113
static Time GetTimeNowMs()
Get current time in milliseconds since kernel start.
Definition stk_helper.h:445
int32_t Timeout
Timeout time (ticks).
Definition stk_common.h:154
static Timeout GetTicksFromMsClampedToTimeout(Timeout ms)
Convert milliseconds to ticks and clamp the result to a Timeout type.
Definition stk_helper.h:419

References stk::GetTicksFromMsClampedToTimeout(), and stk::GetTimeNowMs().

Referenced by pthread_cond_timedwait(), pthread_mutex_timedlock(), pthread_rwlock_timedrdlock(), and pthread_rwlock_timedwrlock().

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

◆ ToKernel()

IKernel * stk::pthread::ToKernel ( stk_kernel_t * k)
inlinestatic

Definition at line 189 of file stk_c_pthread.cpp.

190{
191 return reinterpret_cast<IKernel *>(reinterpret_cast<void *>(k));
192}
Interface for the implementation of the kernel of the scheduler. It supports Soft and Hard Real-Time ...

Referenced by pthread_create(), and pthread_exit().

Here is the caller graph for this function:

◆ WaitForTaskExit()

void stk::pthread::WaitForTaskExit ( ThreadCtrl * ctrl)
static

Definition at line 434 of file stk_c_pthread.cpp.

435{
436 bool exited = false;
437
438 while (!exited)
439 {
440 {
441 const CsLock cs_;
442
443 exited = ctrl->exited;
444 }
445
446 if (!exited)
447 {
448 SleepMs(1);
449 }
450 }
451}
static void SleepMs(Timeout ms)
Put calling process into a sleep state.
Definition stk_helper.h:492

References pthread_stk_ctrl_t::exited, and stk::SleepMs().

Referenced by pthread_join(), and ReaperEntry().

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

Variable Documentation

◆ data

uint8_t stk::pthread::data[sizeof(sync::Semaphore)]

Definition at line 300 of file stk_c_pthread.cpp.

◆ kDefaultStackBytes

std::size_t stk::pthread::kDefaultStackBytes
constexpr
Initial value:
=
static_cast<std::size_t>(STK_C_PTHREAD_DEFAULT_STACK_WORDS) * sizeof(stk_word_t)
#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 ...

Definition at line 175 of file stk_c_pthread.cpp.

Referenced by AllocateStack(), EnsureStackPool(), pthread_attr_getstacksize(), pthread_create(), and STK_BLOCKPOOL_STORAGE_DECL().

◆ kOnceDone

int stk::pthread::kOnceDone = 2
constexpr

Definition at line 180 of file stk_c_pthread.cpp.

Referenced by pthread_once().

◆ kOnceRunning

int stk::pthread::kOnceRunning = 1
constexpr

Definition at line 179 of file stk_c_pthread.cpp.

Referenced by pthread_once().

◆ s_BoundKernel

stk_kernel_t* stk::pthread::s_BoundKernel = nullptr
static

◆ s_Keys

KeyEntry stk::pthread::s_Keys[STK_C_PTHREAD_KEYS_MAX]
static

◆ s_ReapCount

std::size_t stk::pthread::s_ReapCount = 0U
static

Definition at line 296 of file stk_c_pthread.cpp.

Referenced by DequeueReap(), and EnqueueReap().

◆ s_ReaperStack

stk_word_t stk::pthread::s_ReaperStack[STK_C_PTHREAD_REAPER_STACK_WORDS]
static

Definition at line 303 of file stk_c_pthread.cpp.

Referenced by EnsureReaper().

◆ s_ReaperTask

stk_task_t* stk::pthread::s_ReaperTask = nullptr
static

Definition at line 302 of file stk_c_pthread.cpp.

Referenced by EnqueueReap(), and EnsureReaper().

◆ s_ReapHead

std::size_t stk::pthread::s_ReapHead = 0U
static

Definition at line 295 of file stk_c_pthread.cpp.

Referenced by DequeueReap(), and EnqueueReap().

◆ s_ReapQueue

ThreadCtrl* stk::pthread::s_ReapQueue[STK_C_PTHREAD_MAX_THREADS]
static

Definition at line 294 of file stk_c_pthread.cpp.

Referenced by DequeueReap(), and EnqueueReap().

◆ s_ReapSem

sync::Semaphore* stk::pthread::s_ReapSem = nullptr
static

Definition at line 298 of file stk_c_pthread.cpp.

Referenced by EnsureReaper(), MaybeReap(), and ReaperEntry().

◆ [struct]

struct { ... } stk::pthread::s_ReapSemBuf

Referenced by EnsureReaper().

◆ s_StackPool

stk_blockpool_t* stk::pthread::s_StackPool = nullptr
static

Definition at line 266 of file stk_c_pthread.cpp.

Referenced by EnsureStackPool(), and ReleaseThreadResources().

◆ s_Threads

ThreadCtrl stk::pthread::s_Threads[STK_C_PTHREAD_MAX_THREADS]
static

Definition at line 182 of file stk_c_pthread.cpp.

Referenced by AcquireThreadSlot().