Exports the type syncwait_t which extends syncthread_t with additional information to be able to wait for a syncevent_t.
╭────────────╮ ╭─────────────╮ | syncwait_t ├──────┤ syncevent_t | ╰────────────╯1 1╰─────────────╯
You need to include type syncthread_t before including this file.
This program is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
© 2013 Jörg Seebohn
Header file SyncWait.
Implementation file SyncWait impl.
typedef struct syncwait_t syncwait_t
Export syncwait_t into global namespace.
typedef struct syncevent_t syncevent_t
Export syncevent_t into global namespace.
test | |
unittest_task_syncwait | Test syncwait_t functionality. |
int unittest_task_syncwait( void )
Test syncwait_t functionality.
struct syncevent_t
Event type stores a pointer to a single waiting syncwait_t. If the event occurs you can get the waiting thread with waiting_syncevent and call it or move into another queue (see syncrun_t).
lifetime | |
syncevent_FREE | Static initializer. |
syncevent_INIT | Static initializer. |
initmove_syncevent | Moves initialized srcsyncevent to destsyncevent. |
initmovesafe_syncevent | Moves initialized or free srcsyncevent to destsyncevent. |
query | |
isfree_syncevent | Returns true if syncevent equals to syncevent_FREE. |
iswaiting_syncevent | Returns true if there is already a waiting thread. |
waiting_syncevent | Returns the single thread which waits for this event. |
#define syncevent_INIT( waiting ) { waiting }
Static initializer. The event supports a single waiting syncthread_t and is initialized with a pointer to syncwait_t.
void initmove_syncevent( /*out*/syncevent_t * destsyncevent, const syncevent_t * srcsyncevent )
Moves initialized srcsyncevent to destsyncevent. srcsyncevent is not changed. Before calling this function make sure <iswaiting_syncevent>(srcsyncevent) returns true. Do not access srcsyncevent after this operation - it is considered in an invalid, uninitialized state.
void initmovesafe_syncevent( /*out*/syncevent_t * destsyncevent, const syncevent_t * srcsyncevent )
Moves initialized or free srcsyncevent to destsyncevent. srcsyncevent is not changed. Do not access srcsyncevent after this operation - it is considered in an invalid, uninitialized state.
bool isfree_syncevent( const syncevent_t * syncevent )
Returns true if syncevent equals to syncevent_FREE.
struct syncwait_t
Describes a syncthread_t waiting for a syncevent_t.
The syncwait_t points to syncevent_t and vice versa. The bidirectional link helps to move both types of objects in memory without breaking the connection. The movement is done to compact memory.
Use initmove_syncevent and initmove_syncwait to move initialized objects of both types in memory.
Use update_syncwait if you want to assign a new syncevent_t to an already initialized syncwait_t.
Freeing of objects is not implemented so it is possible to remove either syncevent_t from the queue and then syncwait_t or vice versa without any access to the other object. Both objects do no allocate any additional resources.
thread | Stores the syncthread_t which is waiting. |
event | A pointer to type syncevent_t the syncthread is waiting for. |
continuelabel | The address where execution should continue after the thread is woken up. |
lifetime | |
syncwait_FREE | Static initializer. |
init_syncwait | Initializes syncwait and registers itself at event. |
initmove_syncwait | Moves initialized (!) |
query | |
thread_syncwait | Returns pointer to syncwait->thread (see syncwait_t.thread). |
event_syncwait | Returns value syncwait->event (see syncwait_t.event). |
continuelabel_syncwait | Returns pointer to syncwait->continuelabel (see syncwait_t.continuelabel). |
update | |
update_syncwait | Changes event and continuelabel in syncwait_t. |
syncthread_t thread
Stores the syncthread_t which is waiting.
syncevent_t * event
A pointer to type syncevent_t the syncthread is waiting for.
void init_syncwait( /*out*/syncwait_t * syncwait, const syncthread_t * thread, syncevent_t * event, void * continuelabel )
Initializes syncwait and registers itself at event. The content of event is overwritten - so make sure it is either empty or undefined.
void initmove_syncwait( /*out*/syncwait_t * destsyncwait, const syncwait_t * srcsyncwait )
Moves initialized (!) srcsyncwait to destsyncwait and srcsyncwait is not changed. Do not access srcsyncwait after this operation - it is considered in an invalid, uninitialized state.
syncthread_t * thread_syncwait( syncwait_t * syncwait )
Returns pointer to syncwait->thread (see syncwait_t.thread).
syncevent_t * event_syncwait( const syncwait_t * syncwait )
Returns value syncwait->event (see syncwait_t.event).
void * continuelabel_syncwait( const syncwait_t * syncwait )
Returns pointer to syncwait->continuelabel (see syncwait_t.continuelabel).
void update_syncwait( syncwait_t * syncwait, syncevent_t * event, void * continuelabel )
Changes event and continuelabel in syncwait_t. The old reference to syncevent_t os overwritten but the referenced old syncevent_t is not cleared. This function assumes that the old syncevent_t no longer exists. The event is set as new reference and the referenced syncevent_t is updated to point to syncwait.
syncevent_t | |
initmove_syncevent | Implements syncevent_t.initmove_syncevent. |
initmovesafe_syncevent | Implements <syncwait_t.initmovesafe_syncevent>. |
isfree_syncevent | Implements syncevent_t.isfree_syncevent. |
iswaiting_syncevent | Implements syncevent_t.iswaiting_syncevent. |
waiting_syncevent | Implements syncevent_t.waiting_syncevent. |
syncwait_t | |
init_syncwait | Implements syncwait_t.init_syncwait. |
continuelabel_syncwait | Implements syncwait_t.continuelabel_syncwait. |
initmove_syncwait | Implements syncwait_t.initmove_syncwait. |
thread_syncwait | Implements syncwait_t.thread_syncwait. |
update_syncwait | Implements syncwait_t.update_syncwait. |
event_syncwait | Implements syncwait_t.event_syncwait. |
#define initmove_syncevent( destsyncevent, srcsyncevent ) do { typeof(destsyncevent) _dest = (destsyncevent) ; *_dest = *(srcsyncevent) ; _dest->waiting->event = _dest ; } while(0)
Implements syncevent_t.initmove_syncevent.
#define isfree_syncevent( syncevent ) (0 == (syncevent)->waiting)
Implements syncevent_t.isfree_syncevent.
#define iswaiting_syncevent( syncevent ) (0 != (syncevent)->waiting)
Implements syncevent_t.iswaiting_syncevent.
#define waiting_syncevent( syncevent ) ((syncevent)->waiting)
Implements syncevent_t.waiting_syncevent.
#define init_syncwait( syncwait, thread, _event, continuelabel ) do { typeof(syncwait) _sw = (syncwait) ; *_sw = (syncwait_t) { *(thread), (_event), (continuelabel) } ; _sw->event->waiting = _sw ; } while(0)
Implements syncwait_t.init_syncwait.
#define continuelabel_syncwait( syncwait ) ((syncwait)->continuelabel)
Implements syncwait_t.continuelabel_syncwait.
#define initmove_syncwait( destsyncwait, srcsyncwait ) do { typeof(destsyncwait) _dest = (destsyncwait) ; *_dest = *(srcsyncwait) ; _dest->event->waiting = _dest ; } while(0)
Implements syncwait_t.initmove_syncwait.
#define thread_syncwait( syncwait ) (&(syncwait)->thread)
Implements syncwait_t.thread_syncwait.
#define update_syncwait( syncwait, _event, _continuelabel ) do { typeof(syncwait) _sw = (syncwait) ; _sw->event = (_event) ; _sw->continuelabel = (_continuelabel) ; _sw->event->waiting = _sw ; } while(0)
Implements syncwait_t.update_syncwait.
#define event_syncwait( syncwait ) ((syncwait)->event)
Implements syncwait_t.event_syncwait.
Describes a syncthread_t waiting for a syncevent_t.
struct syncwait_t
A simple function context which is executed in a cooperative way.
struct syncthread_t
Event type stores a pointer to a single waiting syncwait_t.
struct syncevent_t
Export syncwait_t into global namespace.
typedef struct syncwait_t syncwait_t
Export syncevent_t into global namespace.
typedef struct syncevent_t syncevent_t
Test syncwait_t functionality.
int unittest_task_syncwait( void )
Static initializer.
#define syncevent_FREE { 0 }
Static initializer.
#define syncevent_INIT( waiting ) { waiting }
Moves initialized srcsyncevent to destsyncevent.
void initmove_syncevent( /*out*/syncevent_t * destsyncevent, const syncevent_t * srcsyncevent )
Moves initialized or free srcsyncevent to destsyncevent.
void initmovesafe_syncevent( /*out*/syncevent_t * destsyncevent, const syncevent_t * srcsyncevent )
Returns true if syncevent equals to syncevent_FREE.
bool isfree_syncevent( const syncevent_t * syncevent )
Returns true if there is already a waiting thread.
bool iswaiting_syncevent( const syncevent_t * syncevent )
Returns the single thread which waits for this event.
syncwait_t * waiting_syncevent( const syncevent_t * syncevent )
Stores the syncthread_t which is waiting.
syncthread_t thread
A pointer to type syncevent_t the syncthread is waiting for.
syncevent_t * event
The address where execution should continue after the thread is woken up.
void * continuelabel
Static initializer.
#define syncwait_FREE { syncthread_FREE, 0, 0 }
Initializes syncwait and registers itself at event.
void init_syncwait( /*out*/syncwait_t * syncwait, const syncthread_t * thread, syncevent_t * event, void * continuelabel )
Moves initialized (!)
void initmove_syncwait( /*out*/syncwait_t * destsyncwait, const syncwait_t * srcsyncwait )
Returns pointer to syncwait->thread (see syncwait_t.thread).
syncthread_t * thread_syncwait( syncwait_t * syncwait )
Returns value syncwait->event (see syncwait_t.event).
syncevent_t * event_syncwait( const syncwait_t * syncwait )
Returns pointer to syncwait->continuelabel (see syncwait_t.continuelabel).
void * continuelabel_syncwait( const syncwait_t * syncwait )
Changes event and continuelabel in syncwait_t.
void update_syncwait( syncwait_t * syncwait, syncevent_t * event, void * continuelabel )
Implements syncevent_t.initmove_syncevent.
#define initmove_syncevent( destsyncevent, srcsyncevent ) do { typeof(destsyncevent) _dest = (destsyncevent) ; *_dest = *(srcsyncevent) ; _dest->waiting->event = _dest ; } while(0)
Implements syncwait_t.initmovesafe_syncevent.
#define initmovesafe_syncevent( destsyncevent, srcsyncevent ) do { typeof(destsyncevent) _dest = (destsyncevent) ; *_dest = *(srcsyncevent) ; if (_dest->waiting) { _dest->waiting->event = _dest ; } } while(0)
Implements syncevent_t.isfree_syncevent.
#define isfree_syncevent( syncevent ) (0 == (syncevent)->waiting)
Implements syncevent_t.iswaiting_syncevent.
#define iswaiting_syncevent( syncevent ) (0 != (syncevent)->waiting)
Implements syncevent_t.waiting_syncevent.
#define waiting_syncevent( syncevent ) ((syncevent)->waiting)
Implements syncwait_t.init_syncwait.
#define init_syncwait( syncwait, thread, _event, continuelabel ) do { typeof(syncwait) _sw = (syncwait) ; *_sw = (syncwait_t) { *(thread), (_event), (continuelabel) } ; _sw->event->waiting = _sw ; } while(0)
Implements syncwait_t.continuelabel_syncwait.
#define continuelabel_syncwait( syncwait ) ((syncwait)->continuelabel)
Implements syncwait_t.initmove_syncwait.
#define initmove_syncwait( destsyncwait, srcsyncwait ) do { typeof(destsyncwait) _dest = (destsyncwait) ; *_dest = *(srcsyncwait) ; _dest->event->waiting = _dest ; } while(0)
Implements syncwait_t.thread_syncwait.
#define thread_syncwait( syncwait ) (&(syncwait)->thread)
Implements syncwait_t.update_syncwait.
#define update_syncwait( syncwait, _event, _continuelabel ) do { typeof(syncwait) _sw = (syncwait) ; _sw->event = (_event) ; _sw->continuelabel = (_continuelabel) ; _sw->event->waiting = _sw ; } while(0)
Implements syncwait_t.event_syncwait.
#define event_syncwait( syncwait ) ((syncwait)->event)
Manages a set of syncthread_t.
struct syncrun_t