SyncWaitlist

Exports type syncwlist_t which implements a list of syncevent_t to support more than one waiting syncthread_t.

         ╭─────────╮
         | dlist_t | // double linked list
         ├─────────┤ // only used as dummy in implementation
     ┌───┼ last    |
     |   ╰─────────╯
     |              ┌──────────────────────┬┐
     |   ┌──────────or─────────┐           ||
╭────↓───↓──────╮      ╭───────↓─────────╮ ||
| syncwlist_t   |      | wlistentry_t    | ||
├───────────────┤      ├─────────────────┤ ||
| next         ─┼─────▸| next           ─┼─┘|
| prev         ─┼─────▸| prev           ─┼──┘
╰───────────────╯      | syncevent_t     |
                       ╰─────────────────╯
invariant:
for all wlistentry_t x, y :
(x.next==y) <==> (y.prev==x)

for all syncwlist_t w; wlistentry_t x, y :
(w.next==x) <==> (x.prev==w)
(w.prev==y) <==> (y.next==w)
Summary
SyncWaitlistExports type syncwlist_t which implements a list of syncevent_t to support more than one waiting syncthread_t.
CopyrightThis program is free software.
Files
C-kern/api/task/syncwlist.hHeader file SyncWaitlist.
C-kern/task/syncwlist.cImplementation file SyncWaitlist impl.
Types
struct syncwlist_tExport syncwlist_t into global namespace.
struct syncwlist_iterator_tExport syncwlist_iterator_t into global namespace.
Functions
test
unittest_task_syncwlistTest syncwlist_t functionality.
syncwlist_iterator_tOffers iteration over content of syncwlist_t.
lifetime
syncwlist_iterator_FREEStatic initializer.
initfirst_syncwlistiteratorInitializes an iterator for syncwlist_t.
free_syncwlistiteratorFrees an iterator of syncwlist_t.
iterate
next_syncwlistiteratorReturns next contained event.
syncwlist_tImplements a double linked list of syncevent_t and stores them in a syncqueue_t.
lifetime
syncwlist_FREEStatic initializer.
init_syncwlistInitializes wlist to an empty list.
initmove_syncwlistInitializes destwlist with content of scrwlist and clears srcwlist.
free_syncwlistMarks all listed nodes as free and removes them from the queue.
query
isempty_syncwlistReturns true if wlist contains no elements.
isfree_syncwlistReturns true if wlist equals syncwlist_FREE.
len_syncwlistReturns the number of inserted events.
queue_syncwlistReturns the queue of the first node.
last_syncwlistReturns pointer to last contained syncevent_t.
foreach-support
iteratortype_syncwlistDeclaration to associate syncwlist_iterator_t with syncwlist_t.
iteratedtype_syncwlistDeclaration to associate syncevent_t with syncwlist_t.
update
insert_syncwlistAllocates new wlist node and inserts it into wlist.
remove_syncwlistRemoves the first node in wlist.
removeempty_syncwlistRemoves the last node if its syncevent_t has not waiting thread.
transferfirst_syncwlistTransfers the first node from fromwlist to towlist.
transferall_syncwlistTransfers all nodes from fromwlist to towlist.
inline implementation
syncwlist_iterator_t
free_syncwlistiteratorImplements syncwlist_iterator_t.free_syncwlistiterator.
syncwlist_t
isempty_syncwlistImplements syncwlist_t.isempty_syncwlist.
len_syncwlistImplements syncwlist_t.len_syncwlist.
queue_syncwlistImplements syncwlist_t.queue_syncwlist.

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/syncwlist.h

Header file SyncWaitlist.

C-kern/task/syncwlist.c

Implementation file SyncWaitlist impl.

Types

struct syncwlist_t

typedef struct syncwlist_t syncwlist_t

Export syncwlist_t into global namespace.

struct syncwlist_iterator_t

typedef struct syncwlist_iterator_t syncwlist_iterator_t

Export syncwlist_iterator_t into global namespace.

Functions

Summary

test

unittest_task_syncwlist

int unittest_task_syncwlist(void)

Test syncwlist_t functionality.

syncwlist_iterator_t

struct syncwlist_iterator_t

Offers iteration over content of syncwlist_t.  Does not support removal operation (<remove_syncwlist>) of any element.  The reason is that calling <remove_syncwlist> moves a single node in the queue to fill the gap which may be the next node returned by this iterator.

Summary
lifetime
syncwlist_iterator_FREEStatic initializer.
initfirst_syncwlistiteratorInitializes an iterator for syncwlist_t.
free_syncwlistiteratorFrees an iterator of syncwlist_t.
iterate
next_syncwlistiteratorReturns next contained event.

lifetime

syncwlist_iterator_FREE

#define syncwlist_iterator_FREE { 0, 0 }

Static initializer.

initfirst_syncwlistiterator

int initfirst_syncwlistiterator(/*out*/syncwlist_iterator_t *iter,
syncwlist_t *wlist)

Initializes an iterator for syncwlist_t.

free_syncwlistiterator

int free_syncwlistiterator(syncwlist_iterator_t *iter)

Frees an iterator of syncwlist_t.  This is a no-op.

iterate

next_syncwlistiterator

bool next_syncwlistiterator(syncwlist_iterator_t *iter,
/*out*/struct syncevent_t **event)

Returns next contained event.  The first call after initfirst_syncwlistiterator returns the first contained event if the list is not empty.

Returns

trueevent contains a pointer to the next valid syncevent_t in syncwlist_t.
falseThere is no next event.  The last element was already returned or the list is empty.

syncwlist_t

struct syncwlist_t

Implements a double linked list of syncevent_t and stores them in a syncqueue_t.  Every syncevent_t can be connected to a waiting syncthread_t.  The nr of syncevent_t stored in the list is held in variable nrnodes.

Invariant

Some functions expect a pointer to syncqueue_t as a parameter.  This pointer should always point to the same queue and only nodes of list type syncwlist_t should be stored in this queue.  If a node is removed from a syncwlist_t the last node in the queue is copied to the removed node and then the last node is removed instead.

Summary
lifetime
syncwlist_FREEStatic initializer.
init_syncwlistInitializes wlist to an empty list.
initmove_syncwlistInitializes destwlist with content of scrwlist and clears srcwlist.
free_syncwlistMarks all listed nodes as free and removes them from the queue.
query
isempty_syncwlistReturns true if wlist contains no elements.
isfree_syncwlistReturns true if wlist equals syncwlist_FREE.
len_syncwlistReturns the number of inserted events.
queue_syncwlistReturns the queue of the first node.
last_syncwlistReturns pointer to last contained syncevent_t.
foreach-support
iteratortype_syncwlistDeclaration to associate syncwlist_iterator_t with syncwlist_t.
iteratedtype_syncwlistDeclaration to associate syncevent_t with syncwlist_t.
update
insert_syncwlistAllocates new wlist node and inserts it into wlist.
remove_syncwlistRemoves the first node in wlist.
removeempty_syncwlistRemoves the last node if its syncevent_t has not waiting thread.
transferfirst_syncwlistTransfers the first node from fromwlist to towlist.
transferall_syncwlistTransfers all nodes from fromwlist to towlist.

lifetime

syncwlist_FREE

#define syncwlist_FREE { 0, 0, 0 }

Static initializer.

init_syncwlist

void init_syncwlist(/*out*/syncwlist_t *wlist)

Initializes wlist to an empty list.

initmove_syncwlist

void initmove_syncwlist(/*out*/syncwlist_t *destwlist,
syncwlist_t *srcwlist)

Initializes destwlist with content of scrwlist and clears srcwlist.  After the call destwilist contains all elements of srcwlist and srcwlist is set to the empty list (init_syncwlist).

free_syncwlist

int free_syncwlist(syncwlist_t *wlist,
struct syncqueue_t *queue)

Marks all listed nodes as free and removes them from the queue.  Waiting syncwait_t referenced by any stored syncevent_t are not changed.  After this operation all referenced syncwait_t contain invalid syncwait_t.event.  Therefore make sure that wlist is empty befroe calling free.

query

isempty_syncwlist

bool isempty_syncwlist(const syncwlist_t *wlist)

Returns true if wlist contains no elements.

isfree_syncwlist

bool isfree_syncwlist(const syncwlist_t *wlist)

Returns true if wlist equals syncwlist_FREE.

len_syncwlist

size_t len_syncwlist(const syncwlist_t *wlist)

Returns the number of inserted events.

queue_syncwlist

struct syncqueue_t * queue_syncwlist(const syncwlist_t *wlist)

Returns the queue of the first node.  If the list is empty 0 is returned.  Parameter queue is used to determine the pagesize of the queue.  Do not forget to include type syncqueue_t if you call this function - it is implemented as macro.

last_syncwlist

struct syncevent_t * last_syncwlist(const syncwlist_t *wlist)

Returns pointer to last contained syncevent_t.  In case list is empty 0 is returned.

foreach-support

iteratortype_syncwlist

typedef syncwlist_iterator_t iteratortype_syncwlist

Declaration to associate syncwlist_iterator_t with syncwlist_t.

iteratedtype_syncwlist

typedef struct syncevent_t * iteratedtype_syncwlist

Declaration to associate syncevent_t with syncwlist_t.

update

insert_syncwlist

int insert_syncwlist(syncwlist_t *wlist,
struct syncqueue_t *queue,
/*out*/struct syncevent_t **newevent)

Allocates new wlist node and inserts it into wlist.  The memory is allocated from queue and the new node is inserted as last element into wlist.  The syncevent_t member of the node is initialized to <syncevent_FREE> and a reference to it is returned in newevent.  The function returns ENOMEM in case of out of memory.

remove_syncwlist

int remove_syncwlist(syncwlist_t *wlist,
struct syncqueue_t *queue,
/*out*/struct syncevent_t *removedevent)

Removes the first node in wlist.  The node is also removed from queue.  The error ENODATA (no error log) is returned in case wlist is empty.  The content of the removed syncevent_t is copied into removedevent without accessing or changing the referenced syncwait_t.  After successful return the referenced syncwait_t contains an invalid reference to a removed syncevent_t.

removeempty_syncwlist

int removeempty_syncwlist(syncwlist_t *wlist,
struct syncqueue_t *queue)

Removes the last node if its syncevent_t has not waiting thread.

transferfirst_syncwlist

int transferfirst_syncwlist(syncwlist_t *towlist,
syncwlist_t *fromwlist)

Transfers the first node from fromwlist to towlist.  The first node of fromwlist is removed and inserted as last into towlist.  In case fromwlist is empty no error is returned and nothing is done.

transferall_syncwlist

int transferall_syncwlist(syncwlist_t *towlist,
syncwlist_t *fromwlist)

Transfers all nodes from fromwlist to towlist.  All nodes from fromwlist are removed and appended to towlist starting at first node of fromwlist.  This function is much faster than repeatedly calling transferfirst_syncwlist until fromwlist is empty.  In case fromwlist is empty no error is returned and nothing is done.

syncwlist_iterator_t

free_syncwlistiterator

#define free_syncwlistiterator(
   iter
) (*(iter) = (syncwlist_iterator_t) syncwlist_iterator_FREE, 0)

Implements syncwlist_iterator_t.free_syncwlistiterator.

syncwlist_t

isempty_syncwlist

#define isempty_syncwlist(wlist) (0 == (wlist)->nrnodes)

Implements syncwlist_t.isempty_syncwlist.

len_syncwlist

#define len_syncwlist(wlist) ((size_t)(wlist)->nrnodes)

Implements syncwlist_t.len_syncwlist.

queue_syncwlist

#define queue_syncwlist(
   wlist
) ( __extension__ ({ syncwlist_t * _wl = (wlist) ; syncqueue_t * _qu = 0 ; if (_wl->nrnodes) { _qu = queuefromaddr_syncqueue( _wl->next) ; } _qu ; }))

Implements syncwlist_t.queue_syncwlist.

struct syncwlist_t
Implements a double linked list of syncevent_t and stores them in a syncqueue_t.
struct syncevent_t
Event type stores a pointer to a single waiting syncwait_t.
struct syncthread_t
A simple function context which is executed in a cooperative way.
Exports type syncwlist_t which implements a list of syncevent_t to support more than one waiting syncthread_t.
Implements SyncWaitlist.
typedef struct syncwlist_t syncwlist_t
Export syncwlist_t into global namespace.
typedef struct syncwlist_iterator_t syncwlist_iterator_t
Export syncwlist_iterator_t into global namespace.
struct syncwlist_iterator_t
Offers iteration over content of syncwlist_t.
int unittest_task_syncwlist(void)
Test syncwlist_t functionality.
#define syncwlist_iterator_FREE { 0, 0 }
Static initializer.
int initfirst_syncwlistiterator(/*out*/syncwlist_iterator_t *iter,
syncwlist_t *wlist)
Initializes an iterator for syncwlist_t.
int free_syncwlistiterator(syncwlist_iterator_t *iter)
Frees an iterator of syncwlist_t.
bool next_syncwlistiterator(syncwlist_iterator_t *iter,
/*out*/struct syncevent_t **event)
Returns next contained event.
struct syncqueue_t
Internal type to store zero or more syncthread_t + additional information.
#define syncwlist_FREE { 0, 0, 0 }
Static initializer.
void init_syncwlist(/*out*/syncwlist_t *wlist)
Initializes wlist to an empty list.
void initmove_syncwlist(/*out*/syncwlist_t *destwlist,
syncwlist_t *srcwlist)
Initializes destwlist with content of scrwlist and clears srcwlist.
int free_syncwlist(syncwlist_t *wlist,
struct syncqueue_t *queue)
Marks all listed nodes as free and removes them from the queue.
bool isempty_syncwlist(const syncwlist_t *wlist)
Returns true if wlist contains no elements.
bool isfree_syncwlist(const syncwlist_t *wlist)
Returns true if wlist equals syncwlist_FREE.
size_t len_syncwlist(const syncwlist_t *wlist)
Returns the number of inserted events.
struct syncqueue_t * queue_syncwlist(const syncwlist_t *wlist)
Returns the queue of the first node.
struct syncevent_t * last_syncwlist(const syncwlist_t *wlist)
Returns pointer to last contained syncevent_t.
typedef syncwlist_iterator_t iteratortype_syncwlist
Declaration to associate syncwlist_iterator_t with syncwlist_t.
typedef struct syncevent_t * iteratedtype_syncwlist
Declaration to associate syncevent_t with syncwlist_t.
int insert_syncwlist(syncwlist_t *wlist,
struct syncqueue_t *queue,
/*out*/struct syncevent_t **newevent)
Allocates new wlist node and inserts it into wlist.
int remove_syncwlist(syncwlist_t *wlist,
struct syncqueue_t *queue,
/*out*/struct syncevent_t *removedevent)
Removes the first node in wlist.
int removeempty_syncwlist(syncwlist_t *wlist,
struct syncqueue_t *queue)
Removes the last node if its syncevent_t has not waiting thread.
int transferfirst_syncwlist(syncwlist_t *towlist,
syncwlist_t *fromwlist)
Transfers the first node from fromwlist to towlist.
int transferall_syncwlist(syncwlist_t *towlist,
syncwlist_t *fromwlist)
Transfers all nodes from fromwlist to towlist.
#define free_syncwlistiterator(
   iter
) (*(iter) = (syncwlist_iterator_t) syncwlist_iterator_FREE, 0)
Implements syncwlist_iterator_t.free_syncwlistiterator.
#define isempty_syncwlist(wlist) (0 == (wlist)->nrnodes)
Implements syncwlist_t.isempty_syncwlist.
#define len_syncwlist(wlist) ((size_t)(wlist)->nrnodes)
Implements syncwlist_t.len_syncwlist.
#define queue_syncwlist(
   wlist
) ( __extension__ ({ syncwlist_t * _wl = (wlist) ; syncqueue_t * _qu = 0 ; if (_wl->nrnodes) { _qu = queuefromaddr_syncqueue( _wl->next) ; } _qu ; }))
Implements syncwlist_t.queue_syncwlist.
struct syncwait_t
Describes a syncthread_t waiting for a syncevent_t.
syncevent_t * event
A pointer to type syncevent_t the syncthread is waiting for.
Close