SyncWait

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╰─────────────╯

Includes

You need to include type syncthread_t before including this file.

Summary
SyncWaitExports the type syncwait_t which extends syncthread_t with additional information to be able to wait for a syncevent_t.
CopyrightThis program is free software.
Files
C-kern/api/task/syncwait.hHeader file SyncWait.
C-kern/task/syncwait.cImplementation file SyncWait impl.
Types
struct syncwait_tExport syncwait_t into global namespace.
struct syncevent_tExport syncevent_t into global namespace.
Functions
test
unittest_task_syncwaitTest syncwait_t functionality.
syncevent_tEvent type stores a pointer to a single waiting syncwait_t.
lifetime
syncevent_FREEStatic initializer.
syncevent_INITStatic initializer.
initmove_synceventMoves initialized srcsyncevent to destsyncevent.
initmovesafe_synceventMoves initialized or free srcsyncevent to destsyncevent.
query
isfree_synceventReturns true if syncevent equals to syncevent_FREE.
iswaiting_synceventReturns true if there is already a waiting thread.
waiting_synceventReturns the single thread which waits for this event.
syncwait_tDescribes a syncthread_t waiting for a syncevent_t.
threadStores the syncthread_t which is waiting.
eventA pointer to type syncevent_t the syncthread is waiting for.
continuelabelThe address where execution should continue after the thread is woken up.
lifetime
syncwait_FREEStatic initializer.
init_syncwaitInitializes syncwait and registers itself at event.
initmove_syncwaitMoves initialized (!)
query
thread_syncwaitReturns pointer to syncwait->thread (see syncwait_t.thread).
event_syncwaitReturns value syncwait->event (see syncwait_t.event).
continuelabel_syncwaitReturns pointer to syncwait->continuelabel (see syncwait_t.continuelabel).
update
update_syncwaitChanges event and continuelabel in syncwait_t.
inline implementation
syncevent_t
initmove_synceventImplements syncevent_t.initmove_syncevent.
initmovesafe_synceventImplements <syncwait_t.initmovesafe_syncevent>.
isfree_synceventImplements syncevent_t.isfree_syncevent.
iswaiting_synceventImplements syncevent_t.iswaiting_syncevent.
waiting_synceventImplements syncevent_t.waiting_syncevent.
syncwait_t
init_syncwaitImplements syncwait_t.init_syncwait.
continuelabel_syncwaitImplements syncwait_t.continuelabel_syncwait.
initmove_syncwaitImplements syncwait_t.initmove_syncwait.
thread_syncwaitImplements syncwait_t.thread_syncwait.
update_syncwaitImplements syncwait_t.update_syncwait.
event_syncwaitImplements syncwait_t.event_syncwait.

Copyright

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.

Author

© 2013 Jörg Seebohn

Files

C-kern/api/task/syncwait.h

Header file SyncWait.

C-kern/task/syncwait.c

Implementation file SyncWait impl.

Types

struct syncwait_t

typedef struct syncwait_t syncwait_t

Export syncwait_t into global namespace.

struct syncevent_t

typedef struct syncevent_t syncevent_t

Export syncevent_t into global namespace.

Functions

Summary

test

unittest_task_syncwait

int unittest_task_syncwait(void)

Test syncwait_t functionality.

syncevent_t

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).

Summary
lifetime
syncevent_FREEStatic initializer.
syncevent_INITStatic initializer.
initmove_synceventMoves initialized srcsyncevent to destsyncevent.
initmovesafe_synceventMoves initialized or free srcsyncevent to destsyncevent.
query
isfree_synceventReturns true if syncevent equals to syncevent_FREE.
iswaiting_synceventReturns true if there is already a waiting thread.
waiting_synceventReturns the single thread which waits for this event.

lifetime

syncevent_FREE

#define syncevent_FREE { 0 }

Static initializer.

syncevent_INIT

#define syncevent_INIT(waiting) { waiting }

Static initializer.  The event supports a single waiting syncthread_t and is initialized with a pointer to syncwait_t.

initmove_syncevent

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.

initmovesafe_syncevent

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.

query

isfree_syncevent

bool isfree_syncevent(const syncevent_t *syncevent)

Returns true if syncevent equals to syncevent_FREE.

iswaiting_syncevent

bool iswaiting_syncevent(const syncevent_t *syncevent)

Returns true if there is already a waiting thread.

waiting_syncevent

syncwait_t * waiting_syncevent(const syncevent_t *syncevent)

Returns the single thread which waits for this event.

syncwait_t

struct syncwait_t

Describes a syncthread_t waiting for a syncevent_t.

Bidirectional Link And Memory Compaction

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.

Summary
threadStores the syncthread_t which is waiting.
eventA pointer to type syncevent_t the syncthread is waiting for.
continuelabelThe address where execution should continue after the thread is woken up.
lifetime
syncwait_FREEStatic initializer.
init_syncwaitInitializes syncwait and registers itself at event.
initmove_syncwaitMoves initialized (!)
query
thread_syncwaitReturns pointer to syncwait->thread (see syncwait_t.thread).
event_syncwaitReturns value syncwait->event (see syncwait_t.event).
continuelabel_syncwaitReturns pointer to syncwait->continuelabel (see syncwait_t.continuelabel).
update
update_syncwaitChanges event and continuelabel in syncwait_t.

thread

syncthread_t thread

Stores the syncthread_t which is waiting.

event

syncevent_t * event

A pointer to type syncevent_t the syncthread is waiting for.

continuelabel

void * continuelabel

The address where execution should continue after the thread is woken up.

lifetime

syncwait_FREE

#define syncwait_FREE { syncthread_FREE, 0, 0 }

Static initializer.

init_syncwait

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.

Precondition

  • This function assumes that the pointer argument event is not NULL.

initmove_syncwait

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.

Precondition

  • This function assumes that srcsyncwait is initialized.

query

thread_syncwait

syncthread_t * thread_syncwait(syncwait_t *syncwait)

Returns pointer to syncwait->thread (see syncwait_t.thread).

event_syncwait

syncevent_t * event_syncwait(const syncwait_t *syncwait)

Returns value syncwait->event (see syncwait_t.event).

continuelabel_syncwait

void * continuelabel_syncwait(const syncwait_t *syncwait)

Returns pointer to syncwait->continuelabel (see syncwait_t.continuelabel).

update

update_syncwait

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.

Precondition

  • This function assumes that <iswaiting_syncevent>(event) returns true.

syncevent_t

initmove_syncevent

#define initmove_syncevent(
   destsyncevent,
   srcsyncevent
) do { typeof(destsyncevent) _dest = (destsyncevent) ; *_dest = *(srcsyncevent) ; _dest->waiting->event = _dest ; } while(0)

Implements syncevent_t.initmove_syncevent.

initmovesafe_syncevent

#define initmovesafe_syncevent(
   destsyncevent,
   srcsyncevent
) do { typeof(destsyncevent) _dest = (destsyncevent) ; *_dest = *(srcsyncevent) ; if (_dest->waiting) { _dest->waiting->event = _dest ; } } while(0)

Implements <syncwait_t.initmovesafe_syncevent>.

isfree_syncevent

#define isfree_syncevent(syncevent) (0 == (syncevent)->waiting)

Implements syncevent_t.isfree_syncevent.

iswaiting_syncevent

#define iswaiting_syncevent(syncevent) (0 != (syncevent)->waiting)

Implements syncevent_t.iswaiting_syncevent.

waiting_syncevent

#define waiting_syncevent(syncevent) ((syncevent)->waiting)

Implements syncevent_t.waiting_syncevent.

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.init_syncwait.

continuelabel_syncwait

#define continuelabel_syncwait(syncwait) ((syncwait)->continuelabel)

Implements syncwait_t.continuelabel_syncwait.

initmove_syncwait

#define initmove_syncwait(
   destsyncwait,
   srcsyncwait
) do { typeof(destsyncwait) _dest = (destsyncwait) ; *_dest = *(srcsyncwait) ; _dest->event->waiting = _dest ; } while(0)

Implements syncwait_t.initmove_syncwait.

thread_syncwait

#define thread_syncwait(syncwait) (&(syncwait)->thread)

Implements syncwait_t.thread_syncwait.

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.update_syncwait.

event_syncwait

#define event_syncwait(syncwait) ((syncwait)->event)

Implements syncwait_t.event_syncwait.

struct syncwait_t
Describes a syncthread_t waiting for a syncevent_t.
struct syncthread_t
A simple function context which is executed in a cooperative way.
struct syncevent_t
Event type stores a pointer to a single waiting syncwait_t.
Exports the type syncwait_t which extends syncthread_t with additional information to be able to wait for a syncevent_t.
Implements SyncWait.
typedef struct syncwait_t syncwait_t
Export syncwait_t into global namespace.
typedef struct syncevent_t syncevent_t
Export syncevent_t into global namespace.
int unittest_task_syncwait(void)
Test syncwait_t functionality.
#define syncevent_FREE { 0 }
Static initializer.
#define syncevent_INIT(waiting) { waiting }
Static initializer.
void initmove_syncevent(/*out*/syncevent_t *destsyncevent,
const syncevent_t *srcsyncevent)
Moves initialized srcsyncevent to destsyncevent.
void initmovesafe_syncevent(/*out*/syncevent_t *destsyncevent,
const syncevent_t *srcsyncevent)
Moves initialized or free srcsyncevent to destsyncevent.
bool isfree_syncevent(const syncevent_t *syncevent)
Returns true if syncevent equals to syncevent_FREE.
bool iswaiting_syncevent(const syncevent_t *syncevent)
Returns true if there is already a waiting thread.
syncwait_t * waiting_syncevent(const syncevent_t *syncevent)
Returns the single thread which waits for this event.
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 * continuelabel
The address where execution should continue after the thread is woken up.
#define syncwait_FREE { syncthread_FREE, 0, 0 }
Static initializer.
void init_syncwait(/*out*/syncwait_t *syncwait,
const syncthread_t *thread,
syncevent_t *event,
void *continuelabel)
Initializes syncwait and registers itself at event.
void initmove_syncwait(/*out*/syncwait_t *destsyncwait,
const syncwait_t *srcsyncwait)
Moves initialized (!)
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.
#define initmove_syncevent(
   destsyncevent,
   srcsyncevent
) do { typeof(destsyncevent) _dest = (destsyncevent) ; *_dest = *(srcsyncevent) ; _dest->waiting->event = _dest ; } while(0)
Implements syncevent_t.initmove_syncevent.
#define initmovesafe_syncevent(
   destsyncevent,
   srcsyncevent
) do { typeof(destsyncevent) _dest = (destsyncevent) ; *_dest = *(srcsyncevent) ; if (_dest->waiting) { _dest->waiting->event = _dest ; } } while(0)
Implements syncwait_t.initmovesafe_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.
struct syncrun_t
Manages a set of syncthread_t.
Close