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::SyncObjectBase Class Reference

Default, storage-owning implementation of ISyncObject. More...

#include <stk_helper.h>

Inheritance diagram for stk::SyncObjectBase:
Collaboration diagram for stk::SyncObjectBase:

Public Types

typedef DLHeadType ListHeadType
 List head type for ISyncObject elements.
typedef DLEntryType ListEntryType
 List entry type of ISyncObject elements.
enum  
 A tag for type-safe casts done by CastListEntryToParent. More...
typedef DListEntry< ISyncObject, TClosedLoop > DLEntryType
 Convenience alias for this entry type. Used to avoid repeating the full template spelling.
typedef DListHead< ISyncObject, TClosedLoop > DLHeadType
 Convenience alias for the corresponding list head type.

Public Member Functions

void AddWaitObject (IWaitObject *wobj) override
 Called by kernel when a new task starts waiting on this event.
void RemoveWaitObject (IWaitObject *wobj) override
 Called by kernel when a waiting task is being removed (timeout expired, wait aborted, task terminated etc.).
const IWaitObject::ListHeadTypeGetWaitList () const override
 Get list of tasks blocked on this object.
virtual bool Tick (Timeout elapsed_ticks)
 Called by kernel on every system tick to handle timeout logic of waiting tasks.
Weight FindWeightHigherThan (Weight comp) const
 Find higher weight within linked wait objects.
DLHeadTypeGetHead ()
 Get the list head this entry currently belongs to.
DLEntryTypeGetNext ()
 Get the next entry in the list.
DLEntryTypeGetPrev ()
 Get the previous entry in the list.
bool IsLinked () const
 Check whether this entry is currently a member of any list.
 operator ISyncObject * ()
 Implicit conversion to a mutable pointer to the host object (T).
 operator const ISyncObject * () const
 Implicit conversion to a const pointer to the host object (T).

Static Public Member Functions

static void AddWaitObject (IWaitObject::ListHeadType &wlist, IWaitObject *wobj)
 Called by kernel when a new task starts waiting on this event.
static void RemoveWaitObject (IWaitObject::ListHeadType &wlist, IWaitObject *wobj)
 Called by kernel when a waiting task is being removed (timeout expired, wait aborted, task terminated etc.).
static void WakeOne (IWaitObject::ListHeadType &wlist)
 Wake the first task in the wait list (FIFO order).
static void WakeAll (IWaitObject::ListHeadType &wlist)
 Wake all tasks currently in the wait list.

Protected Member Functions

 SyncObjectBase ()
 Constructor.
 ~SyncObjectBase ()=default
 Destructor.
void WakeOne () override
 Wake the first task in the wait list (FIFO order).
void WakeAll () override
 Wake all tasks currently in the wait list.
IWaitObject::ListHeadTypeGetWaitList () override
 Get list of tasks blocked on this object.

Protected Attributes

IWaitObject::ListHeadType m_wait_list
 Tasks blocked on this object.

Private Member Functions

void Link (DLHeadType *head, DLEntryType *next, DLEntryType *prev)
 Wire this entry into a list between prev and next.
void Unlink ()
 Remove this entry from its current list.

Private Attributes

DLHeadTypem_head
 Owning list head, or NULL when the entry is not linked.
DLEntryTypem_next
 Next entry in the list, or NULL (open list boundary) / first entry (closed loop).
DLEntryTypem_prev
 Previous entry in the list, or NULL (open list boundary) / last entry (closed loop).

Friends

class IKernelService

Detailed Description

Default, storage-owning implementation of ISyncObject.

Owns the intrusive wait list (m_wait_list) and provides the standard add/remove/wake bookkeeping used by all built-in synchronization primitives (Mutex, Event, Semaphore, ConditionVariable, ...). m_wait_list is protected rather than private: primitives that privately inherit this class are permitted to touch it directly on the hot path (see e.g. Mutex::Unlock) instead of going through the virtual GetWaitList() accessor.

Note
Not every ISyncObject need derive from this class - an implementation with a different storage strategy (e.g. a cross-domain TrustZone wrapper) may implement ISyncObject directly instead.
On ARM TrustZone Non-Secure builds (_STK_CORTEX_M_TRUSTZONE_NON_SECURE), derives from tz::nsec::NsSyncObject instead of ISyncObject directly. Unlike ITask, ISyncObject has no explicit deregistration call, so NsSyncObject's destructor is the only mechanism that frees the Secure-side proxy pool slot for a dynamically-allocated sync object - without it, destroying sync objects at runtime would permanently exhaust the pool.
See also
tz::nsec::NsSyncObject

Definition at line 242 of file stk_helper.h.

Member Typedef Documentation

◆ DLEntryType

typedef DListEntry<ISyncObject, TClosedLoop> stk::util::DListEntry< ISyncObject, TClosedLoop >::DLEntryType
inherited

Convenience alias for this entry type. Used to avoid repeating the full template spelling.

Definition at line 75 of file stk_linked_list.h.

◆ DLHeadType

typedef DListHead<ISyncObject, TClosedLoop> stk::util::DListEntry< ISyncObject, TClosedLoop >::DLHeadType
inherited

Convenience alias for the corresponding list head type.

Definition at line 80 of file stk_linked_list.h.

◆ ListEntryType

List entry type of ISyncObject elements.

Definition at line 577 of file stk_common.h.

◆ ListHeadType

List head type for ISyncObject elements.

Definition at line 572 of file stk_common.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
inherited

A tag for type-safe casts done by CastListEntryToParent.

See also
CastListEntryToParent.

Definition at line 70 of file stk_linked_list.h.

70{ DLEntryTag = 1 };
Intrusive doubly-linked list node. Embed this as a base class in any object (T) that needs to partici...

Constructor & Destructor Documentation

◆ SyncObjectBase()

stk::SyncObjectBase::SyncObjectBase ( )
inlineexplicitprotected

Constructor.

Note
Can not be standalone object, must be inherited by the implementation.

Definition at line 271 of file stk_helper.h.

271 : m_wait_list()
272 {}
IWaitObject::ListHeadType m_wait_list
Tasks blocked on this object.
Definition stk_helper.h:294

References m_wait_list.

◆ ~SyncObjectBase()

stk::SyncObjectBase::~SyncObjectBase ( )
protecteddefault

Destructor.

Note
Protected by design. Prevents unsafe polymorphic delete.

Member Function Documentation

◆ AddWaitObject() [1/2]

void stk::ISyncObject::AddWaitObject ( IWaitObject::ListHeadType & wlist,
IWaitObject * wobj )
inlinestaticinherited

Called by kernel when a new task starts waiting on this event.

Parameters
[in]wobjWait object representing blocked task.
Note
Utility for AddWaitObject and ARM TrustZone support.

Definition at line 583 of file stk_common.h.

584 {
585 STK_ASSERT(wobj->GetHead() == nullptr);
586 wlist.LinkBack(wobj);
587 }
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:516

References stk::util::DListEntry< T, TClosedLoop >::GetHead(), stk::util::DListHead< T, TClosedLoop >::LinkBack(), and STK_ASSERT.

Referenced by stk::SyncObjectBase::AddWaitObject(), and stk::Kernel< TMode, TSize, TStrategy, TPlatform >::KernelTask::WaitObject::SetupWait().

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

◆ AddWaitObject() [2/2]

void stk::SyncObjectBase::AddWaitObject ( IWaitObject * wobj)
inlineoverridevirtual

Called by kernel when a new task starts waiting on this event.

Parameters
[in]wobjWait object representing blocked task.
Note
Must be called inside the critical section (see hw::CriticalSection, sync::ScopedCrticalSection).

Implements stk::ISyncObject.

Definition at line 252 of file stk_helper.h.

253 {
255 }
static void AddWaitObject(IWaitObject::ListHeadType &wlist, IWaitObject *wobj)
Called by kernel when a new task starts waiting on this event.
Definition stk_common.h:583

References stk::ISyncObject::AddWaitObject(), and m_wait_list.

Here is the call graph for this function:

◆ FindWeightHigherThan()

Weight stk::ISyncObject::FindWeightHigherThan ( Weight comp) const
inlineinherited

Find higher weight within linked wait objects.

Implementation of ISyncObject::Tick, see ISyncObject. Placed here as it depends on GetUserTaskFromTid.

Parameters
[in]compWeight to compare with.
Returns
Higher weight value than comp, or NO_WEIGHT if there is no object with a higher weight.
Note
Must be called inside the critical section (see hw::CriticalSection, sync::ScopedCrticalSection).

Definition at line 333 of file stk_helper.h.

334{
335 Weight max_weight = NO_WEIGHT;
336 const IWaitObject *itr = util::DListCast::ListEntryToParent<const IWaitObject>(GetWaitList().GetFirst());
337
338 while (itr != nullptr)
339 {
340 const Weight w = GetUserTaskFromTid(itr->GetTid())->GetWeight();
341 if (w > max_weight)
342 {
343 max_weight = w;
344 }
345
347 }
348
349 return ((max_weight > comp) ? max_weight : NO_WEIGHT);
350}
static constexpr ITask * GetUserTaskFromTid(TId task_id) noexcept
Get task instance from its identifier.
Definition stk_arch.h:725
static constexpr Weight NO_WEIGHT
Weight value: weight is not set.
Definition stk_common.h:222
int32_t Weight
Weight value (aka priority).
Definition stk_common.h:173
virtual const IWaitObject::ListHeadType & GetWaitList() const =0
Get list of tasks blocked on this object.
virtual Weight GetWeight() const
Get static base weight of the task.
Definition stk_common.h:859
static __stk_forceinline TTargetType * ListEntryToParent(TSourceType *const lentry)
Safely casts an intrusive list entry to its concrete parent container object type.

References stk::util::DListEntry< T, TClosedLoop >::GetNext(), stk::IWaitObject::GetTid(), stk::GetUserTaskFromTid(), GetWaitList(), stk::ITask::GetWeight(), stk::util::DListCast::ListEntryToParent(), and stk::NO_WEIGHT.

Referenced by stk::Kernel< stk::KERNEL_DYNAMIC|stk::KERNEL_SYNC|stk::KERNEL_TICKLESS,(16U), stk::SwitchStrategyFP32, stk::PlatformDefault >::OnRestoreWeight(), and stk::sync::Mutex::Unlock().

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

◆ GetHead()

DLHeadType * stk::util::DListEntry< ISyncObject, TClosedLoop >::GetHead ( )
inlineinherited

Get the list head this entry currently belongs to.

Returns
Pointer to the owning DListHead, or NULL if the entry is not linked.

Definition at line 85 of file stk_linked_list.h.

85{ return m_head; }

◆ GetNext()

DLEntryType * stk::util::DListEntry< ISyncObject, TClosedLoop >::GetNext ( )
inlineinherited

Get the next entry in the list.

Returns
Pointer to the next DListEntry, or NULL if this is the last entry (open list) or the first entry (closed loop, where next wraps to first).
Note
In a closed loop (TClosedLoop == true) this pointer is never NULL when the entry is linked.

Definition at line 98 of file stk_linked_list.h.

98{ return m_next; }

◆ GetPrev()

DLEntryType * stk::util::DListEntry< ISyncObject, TClosedLoop >::GetPrev ( )
inlineinherited

Get the previous entry in the list.

Returns
Pointer to the previous DListEntry, or NULL if this is the first entry (open list) or the last entry (closed loop, where prev wraps to last).
Note
In a closed loop (TClosedLoop == true) this pointer is never NULL when the entry is linked.

Definition at line 114 of file stk_linked_list.h.

114{ return m_prev; }

◆ GetWaitList() [1/2]

const IWaitObject::ListHeadType & stk::SyncObjectBase::GetWaitList ( ) const
inlineoverridevirtual

Get list of tasks blocked on this object.

Note
Read-only access for diagnostics / telemetry.

Implements stk::ISyncObject.

Definition at line 262 of file stk_helper.h.

263 {
264 return m_wait_list;
265 }

References m_wait_list.

◆ GetWaitList() [2/2]

IWaitObject::ListHeadType & stk::SyncObjectBase::GetWaitList ( )
inlineoverrideprotectedvirtual

Get list of tasks blocked on this object.

Implements stk::ISyncObject.

Definition at line 289 of file stk_helper.h.

290 {
291 return m_wait_list;
292 }

References m_wait_list.

◆ IsLinked()

bool stk::util::DListEntry< ISyncObject, TClosedLoop >::IsLinked ( ) const
inlineinherited

Check whether this entry is currently a member of any list.

Returns
true if linked (m_head != NULL); false otherwise.

Definition at line 127 of file stk_linked_list.h.

127{ return (GetHead() != nullptr); }

◆ Link()

void stk::util::DListEntry< ISyncObject, TClosedLoop >::Link ( DLHeadType * head,
DLEntryType * next,
DLEntryType * prev )
inlineprivateinherited

Wire this entry into a list between prev and next.

Parameters
[in]headThe owning DListHead. Stored as a back-pointer for IsLinked() and ownership checks.
[in]nextThe entry that will follow this one, or NULL if this becomes the last entry.
[in]prevThe entry that will precede this one, or NULL if this becomes the first entry.
Note
Called exclusively by DListHead::Link(). Assumes the entry is not currently linked. Updates the neighbours' forward/back pointers to splice this entry in.

Definition at line 162 of file stk_linked_list.h.

163 {
164 m_head = head;
165 m_next = next;
166 m_prev = prev;
167
168 if (m_prev != nullptr)
169 {
170 m_prev->m_next = this;
171 }
172
173 if (m_next != nullptr)
174 {
175 m_next->m_prev = this;
176 }
177 }
DLEntryType * m_next
Next entry in the list, or NULL (open list boundary) / first entry (closed loop).
DLEntryType * m_prev
Previous entry in the list, or NULL (open list boundary) / last entry (closed loop).

◆ operator const ISyncObject *()

stk::util::DListEntry< ISyncObject, TClosedLoop >::operator const ISyncObject * ( ) const
inlineinherited

Implicit conversion to a const pointer to the host object (T).

Note
Safe because T must derive from DListEntry<T, TClosedLoop>. Eliminates the need for explicit static_cast at call sites.
MISRA deviation: [STK-DEV-004] Rule 5-2-x.

Definition at line 141 of file stk_linked_list.h.

141{ return static_cast<const T *>(this); }

◆ operator ISyncObject *()

stk::util::DListEntry< ISyncObject, TClosedLoop >::operator ISyncObject* ( )
inlineinherited

Implicit conversion to a mutable pointer to the host object (T).

Note
Safe because T must derive from DListEntry<T, TClosedLoop>. Eliminates the need for explicit static_cast at call sites.
MISRA deviation: [STK-DEV-004] Rule 5-2-x.

Definition at line 134 of file stk_linked_list.h.

134{ return static_cast<T *>(this); }

◆ RemoveWaitObject() [1/2]

void stk::ISyncObject::RemoveWaitObject ( IWaitObject::ListHeadType & wlist,
IWaitObject * wobj )
inlinestaticinherited

Called by kernel when a waiting task is being removed (timeout expired, wait aborted, task terminated etc.).

Parameters
[in]wobjWait object to remove from the wait list.
Note
Utility for AddWaitObject and ARM TrustZone support.

Definition at line 599 of file stk_common.h.

600 {
601 STK_ASSERT(wobj->GetHead() == &wlist);
602 wlist.Unlink(wobj);
603 }

References stk::util::DListEntry< T, TClosedLoop >::GetHead(), STK_ASSERT, and stk::util::DListHead< T, TClosedLoop >::Unlink().

Referenced by stk::SyncObjectBase::RemoveWaitObject().

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

◆ RemoveWaitObject() [2/2]

void stk::SyncObjectBase::RemoveWaitObject ( IWaitObject * wobj)
inlineoverridevirtual

Called by kernel when a waiting task is being removed (timeout expired, wait aborted, task terminated etc.).

Parameters
[in]wobjWait object to remove from the wait list.
Note
Must be called inside the critical section (see hw::CriticalSection, sync::ScopedCrticalSection).

Implements stk::ISyncObject.

Definition at line 257 of file stk_helper.h.

258 {
260 }
static void RemoveWaitObject(IWaitObject::ListHeadType &wlist, IWaitObject *wobj)
Called by kernel when a waiting task is being removed (timeout expired, wait aborted,...
Definition stk_common.h:599

References m_wait_list, and stk::ISyncObject::RemoveWaitObject().

Referenced by stk::sync::Event::RemoveWaitObject().

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

◆ Tick()

bool stk::ISyncObject::Tick ( Timeout elapsed_ticks)
inlinevirtualinherited

Called by kernel on every system tick to handle timeout logic of waiting tasks.

Implementation of ISyncObject::Tick, see ISyncObject. Placed here as it depends on hw namespace.

Parameters
[in]elapsed_ticksNumber of ticks elapsed between this and previous calls, in case of KERNEL_TICKLESS mode this value can be >1, for non-tickless mode it is always 1.
Returns
true if this synchronization object still has waiters with a finite timeout and requires further tick calls. false if the wait list is empty or all remaining waiters have infinite timeouts, signaling to the kernel that it may stop calling Tick() for this object until a new waiter is added.
Note
When this method returns false, the kernel unlinks this object from its active sync list. It will be re-linked automatically when the next waiter is added via AddWaitObject().
Does not need to be called inside critical section.

Definition at line 298 of file stk_helper.h.

299{
301
302 // note: ScopedCriticalSection usage
303 //
304 // Single-core: no critical section needed - Tick() runs inside the
305 // SysTick ISR which already executes with interrupts disabled, making
306 // re-entrancy impossible on the local core.
307 //
308 // Multi-core: critical section is required because the tick handler on
309 // each core may call Tick() concurrently for the same Semaphore instance,
310 // and ISyncObject::Tick() is not re-entrant.
311#if (STK_ARCH_CPU_COUNT > 1)
312 const hw::CriticalSection::ScopedLock cs_;
313#endif
314
315 IWaitObject *itr = util::DListCast::ListEntryToParent<IWaitObject>(wlist.GetFirst());
316
317 while (itr != nullptr)
318 {
319 IWaitObject *const next = util::DListCast::ListEntryToParent<IWaitObject>(itr->GetNext());
320
321 if (!itr->Tick(elapsed_ticks))
322 {
323 itr->Wake(true);
324 }
325
326 itr = next;
327 }
328
329 return !wlist.IsEmpty();
330}
DLHeadType ListHeadType
List head type for IWaitObject elements.
Definition stk_common.h:467

References stk::util::DListHead< T, TClosedLoop >::GetFirst(), stk::util::DListEntry< T, TClosedLoop >::GetNext(), GetWaitList(), stk::util::DListHead< T, TClosedLoop >::IsEmpty(), stk::util::DListCast::ListEntryToParent(), stk::IWaitObject::Tick(), and stk::IWaitObject::Wake().

Here is the call graph for this function:

◆ Unlink()

void stk::util::DListEntry< ISyncObject, TClosedLoop >::Unlink ( )
inlineprivateinherited

Remove this entry from its current list.

Note
Called exclusively by DListHead::Unlink(). Patches the neighbours' pointers to bridge over this entry, then clears m_head, m_next, and m_prev to NULL so the entry is in a clean unlinked state.
Does not update DListHead::m_count or m_first / m_last — those are the responsibility of the calling DListHead::Unlink().

Definition at line 186 of file stk_linked_list.h.

187 {
188 if (m_prev != nullptr)
189 {
191 }
192
193 if (m_next != nullptr)
194 {
196 }
197
198 m_head = nullptr;
199 m_next = nullptr;
200 m_prev = nullptr;
201 }

◆ WakeAll() [1/2]

void stk::ISyncObject::WakeAll ( IWaitObject::ListHeadType & wlist)
inlinestaticinherited

Wake all tasks currently in the wait list.

Note
Each woken task is notified with timeout=false, indicating a successful signal (not a timeout expiry).
Does nothing if no tasks are currently waiting.
Utility for AddWaitObject and ARM TrustZone support.

Definition at line 652 of file stk_common.h.

653 {
654 while (IWaitObject *const obj = util::DListCast::ListEntryToParent<IWaitObject>(wlist.GetFirst()))
655 {
656 obj->Wake(false);
657 }
658 }

References stk::util::DListHead< T, TClosedLoop >::GetFirst(), and stk::util::DListCast::ListEntryToParent().

Here is the call graph for this function:

◆ WakeAll() [2/2]

void stk::SyncObjectBase::WakeAll ( )
inlineoverrideprotectedvirtual

Wake all tasks currently in the wait list.

Note
Each woken task is notified with timeout=false, indicating a successful signal (not a timeout expiry).
Does nothing if no tasks are currently waiting.
Must be called inside the critical section (see hw::CriticalSection, sync::ScopedCrticalSection).

Implements stk::ISyncObject.

Definition at line 284 of file stk_helper.h.

285 {
286 IKernelService::GetInstance()->Wake(this, true);
287 }
virtual void Wake(ISyncObject *sobj, bool all)=0
Wake one or all tasks currently waiting on a synchronization object.
static IKernelService * GetInstance()
Get CPU-local instance of the kernel service.

References stk::IKernelService::GetInstance(), and stk::IKernelService::Wake().

Referenced by stk::sync::ConditionVariable::NotifyAll_CS(), stk::sync::Event::Pulse(), and stk::sync::Event::Set().

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

◆ WakeOne() [1/2]

void stk::ISyncObject::WakeOne ( IWaitObject::ListHeadType & wlist)
inlinestaticinherited

Wake the first task in the wait list (FIFO order).

Note
The woken task is notified with timeout=false, indicating a successful signal (not a timeout expiry).
Does nothing if no tasks are currently waiting.
Utility for AddWaitObject and ARM TrustZone support.

Definition at line 638 of file stk_common.h.

639 {
640 if (IWaitObject *const obj = util::DListCast::ListEntryToParent<IWaitObject>(wlist.GetFirst()))
641 {
642 obj->Wake(false);
643 }
644 }

References stk::util::DListHead< T, TClosedLoop >::GetFirst(), and stk::util::DListCast::ListEntryToParent().

Here is the call graph for this function:

◆ WakeOne() [2/2]

void stk::SyncObjectBase::WakeOne ( )
inlineoverrideprotectedvirtual

Wake the first task in the wait list (FIFO order).

Note
The woken task is notified with timeout=false, indicating a successful signal (not a timeout expiry).
Does nothing if no tasks are currently waiting.
Must be called inside the critical section (see hw::CriticalSection, sync::ScopedCrticalSection).

Implements stk::ISyncObject.

Definition at line 279 of file stk_helper.h.

280 {
281 IKernelService::GetInstance()->Wake(this, false);
282 }

References stk::IKernelService::GetInstance(), and stk::IKernelService::Wake().

Referenced by stk::sync::ConditionVariable::NotifyOne_CS(), stk::sync::Event::Pulse(), stk::sync::Event::Set(), and stk::sync::Semaphore::TrySignal().

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

◆ IKernelService

friend class IKernelService
friend

Definition at line 249 of file stk_helper.h.

References IKernelService.

Referenced by IKernelService, stk::sync::Mutex::TimedLock(), and stk::sync::Mutex::Unlock().

Member Data Documentation

◆ m_head

DLHeadType* stk::util::DListEntry< ISyncObject, TClosedLoop >::m_head
privateinherited

Owning list head, or NULL when the entry is not linked.

Definition at line 203 of file stk_linked_list.h.

◆ m_next

DLEntryType* stk::util::DListEntry< ISyncObject, TClosedLoop >::m_next
privateinherited

Next entry in the list, or NULL (open list boundary) / first entry (closed loop).

Definition at line 204 of file stk_linked_list.h.

◆ m_prev

DLEntryType* stk::util::DListEntry< ISyncObject, TClosedLoop >::m_prev
privateinherited

Previous entry in the list, or NULL (open list boundary) / last entry (closed loop).

Definition at line 205 of file stk_linked_list.h.

◆ m_wait_list


The documentation for this class was generated from the following file: