SyncQueue

Adapts type queue_t for use in syncrun_t.

Includes

You need to include types queue_t and dlist_t before calling the inline functions.

Summary
SyncQueueAdapts type queue_t for use in syncrun_t.
CopyrightThis program is free software.
Files
C-kern/api/task/syncqueue.hHeader file SyncQueue.
C-kern/task/syncqueue.cImplementation file SyncQueue impl.
Types
struct syncqueue_tExport syncqueue_t into global namespace.
Functions
test
unittest_task_syncqueueTest syncqueue_t functionality.
syncqueue_tInternal type to store zero or more syncthread_t + additional information.
lastThis variables makes syncqueue_t convertible to type queue_t.
nrelementsNumber of stored elements.
lifetime
syncqueue_FREEStatic initializer.
syncqueue_INITStatic initializer.
init_syncqueueInitializes syncqueue.
free_syncqueueFrees all allocated memory pages and clears syncqueue.
query
isfree_syncqueueReturns true if syncqueue is equal to syncqueue_FREE.
len_syncqueueReturns the number of elements stored in the queue.
queuefromaddr_syncqueueSee queuefromaddr_queue.
update
insert_syncqueueAdd new element of type IDNAME to end of queue (last).
insert2_syncqueueAdd new element to end of queue (last).
remove_syncqueueRemoves elem of type IDNAME from the queue by overwriting it with the last.
removefirst_syncqueueRemoves an element from the queue by freeing syncqueue memory.
removelast_syncqueueRemoves an element from the queue by freeing syncqueue memory.
addtofreelist_syncqueueAdds elem to freelist.
compact_syncqueueMoves elements from the end of queue to elements stored in freelist.
compact2_syncqueueCalled from macro compact_syncqueue.
inline implementation
Macros
insert_syncqueueImplements syncqueue_t.insert_syncqueue.
insert2_syncqueueImplements syncqueue_t.insert2_syncqueue.
addtofreelist_syncqueueImplements syncqueue_t.addtofreelist_syncqueue.
compact_syncqueueImplements syncqueue_t.compact_syncqueue.
init_syncqueueImplements syncqueue_t.init_syncqueue.
len_syncqueueImplements syncqueue_t.len_syncqueue.
queuefromaddr_syncqueueImplements syncqueue_t.queuefromaddr_syncqueue.
remove_syncqueueImplements syncqueue_t.remove_syncqueue.
removefirst_syncqueueImplements syncqueue_t.removefirst_syncqueue.
removelast_syncqueueImplements syncqueue_t.removelast_syncqueue.

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

Header file SyncQueue.

C-kern/task/syncqueue.c

Implementation file SyncQueue impl.

Types

struct syncqueue_t

typedef struct syncqueue_t syncqueue_t

Export syncqueue_t into global namespace.

Functions

Summary

test

unittest_task_syncqueue

int unittest_task_syncqueue(void)

Test syncqueue_t functionality.

syncqueue_t

struct syncqueue_t

Internal type to store zero or more syncthread_t + additional information.  This object uses queue_t to implement its functionality.

Extension of queue_t

Use genericcast_queue to cast pointer to syncqueue_t into pointer to queue_t if you want to read the content of the queue.  Use only functions of this interface if you want to update the content.

List of Extensions

  • The queue counts the number of stored elements.
  • It offers functionality to remove any element int the queue by overwriting it with the last and remove the last instead.
  • It offers functionality to remember nodes which should be removed in a linked list and allows to compact the queue after it has been iterated over.
Summary
lastThis variables makes syncqueue_t convertible to type queue_t.
nrelementsNumber of stored elements.
lifetime
syncqueue_FREEStatic initializer.
syncqueue_INITStatic initializer.
init_syncqueueInitializes syncqueue.
free_syncqueueFrees all allocated memory pages and clears syncqueue.
query
isfree_syncqueueReturns true if syncqueue is equal to syncqueue_FREE.
len_syncqueueReturns the number of elements stored in the queue.
queuefromaddr_syncqueueSee queuefromaddr_queue.
update
insert_syncqueueAdd new element of type IDNAME to end of queue (last).
insert2_syncqueueAdd new element to end of queue (last).
remove_syncqueueRemoves elem of type IDNAME from the queue by overwriting it with the last.
removefirst_syncqueueRemoves an element from the queue by freeing syncqueue memory.
removelast_syncqueueRemoves an element from the queue by freeing syncqueue memory.
addtofreelist_syncqueueAdds elem to freelist.
compact_syncqueueMoves elements from the end of queue to elements stored in freelist.
compact2_syncqueueCalled from macro compact_syncqueue.

last

struct dlist_node_t * last

This variables makes syncqueue_t convertible to type queue_t.

nrelements

size_t nrelements

Number of stored elements.

lifetime

syncqueue_FREE

#define syncqueue_FREE syncqueue_INIT

Static initializer.

syncqueue_INIT

#define syncqueue_INIT { 0, 0 }

Static initializer.

init_syncqueue

void init_syncqueue(/*out*/syncqueue_t *syncqueue)

Initializes syncqueue.

free_syncqueue

int free_syncqueue(syncqueue_t *syncqueue)

Frees all allocated memory pages and clears syncqueue.  For contained elements no free operation is called.

query

isfree_syncqueue

bool isfree_syncqueue(const syncqueue_t *syncqueue)

Returns true if syncqueue is equal to syncqueue_FREE.

len_syncqueue

size_t len_syncqueue(const syncqueue_t *syncqueue)

Returns the number of elements stored in the queue.

queuefromaddr_syncqueue

syncqueue_t * queuefromaddr_syncqueue(void *nodeaddr)

See queuefromaddr_queue.

update

insert_syncqueue

int insert_syncqueue(syncqueue_t *syncqueue,
IDNAME **newelem)

Add new element of type IDNAME to end of queue (last).  In case of no memory ENOMEM is returned and nothing is done.

insert2_syncqueue

int insert2_syncqueue(syncqueue_t *syncqueue,
uint8_t elemsize,
IDNAME **newelem)

Add new element to end of queue (last).  The type is determined by second parameter elem_t and its size with parameter elemsize.  The initialization function init_elem is called for the newly allocated element which is returned in out parameter newaddr.  In case of no memory ENOMEM is returned and nothing is done.

Precondition

  • elemsize >= sizeof(elem_t)

remove_syncqueue

int remove_syncqueue(syncqueue_t *syncqueue,
IDNAME *elem,
void (*initmove_elem)(IDNAME * dest, IDNAME * src))

Removes elem of type IDNAME from the queue by overwriting it with the last.  The parameter elem must be a pointer to type elem_t.  The type of the element must be given as second paramter.  The function initmove_elem is called with src set to the last element and dest set to elem.  If elem points to the last element in the queue function initmove_elem is not called.

removefirst_syncqueue

int removefirst_syncqueue(syncqueue_t *syncqueue,
uint16_t elemsize)

Removes an element from the queue by freeing syncqueue memory.  Parameter elemsize must be the size of the memory at the begin of syncqueue which is removed.  No free function is called for the removed object.

removelast_syncqueue

int removelast_syncqueue(syncqueue_t *syncqueue,
uint16_t elemsize)

Removes an element from the queue by freeing syncqueue memory.  Parameter elemsize must be the size of the memory at the end of syncqueue which is removed.  No free function is called for the removed object.

addtofreelist_syncqueue

void addtofreelist_syncqueue(syncqueue_t *syncqueue,
struct dlist_t *freelist,
IDNAME *elem)

Adds elem to freelist.  The function is implemented as macro and the pointer elem has to point to an element of size > sizeof(dlist_node_t).

Precondition

  • sizeof(*elem) >= sizeof(dlist_node_t)
  • Elements must be added to freelist in the order from first to last in queue (unchecked).

compact_syncqueue

int compact_syncqueue(syncqueue_t *syncqueue,
IDNAME elem_t,
struct dlist_t *freelist,
void (*initmove_elem)(void * dest, void * src))

Moves elements from the end of queue to elements stored in freelist.  For every moved element function initmove_elem is called.  If an element in freelist equals to the last element function initmove_elem is not called.

compact2_syncqueue

int compact2_syncqueue(syncqueue_t *syncqueue,
uint16_t elemsize,
struct dlist_t *freelist,
void (*initmove_elem)(void * dest, void * src))

Called from macro compact_syncqueue.  Do not call this function directly.  Use the macro to ensure type safety.

Macros

insert_syncqueue

#define insert_syncqueue(
   syncqueue,
   newelem
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; typeof(**(newelem)) ** _elem = (newelem) ; int _err = insertlast_queue( genericcast_queue(_sq), (void**)_elem, sizeof(**_elem)) ; _sq->nrelements += (_err == 0) ; _err ; }))

Implements syncqueue_t.insert_syncqueue.

insert2_syncqueue

#define insert2_syncqueue(
   syncqueue,
   elemsize,
   newelem
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; typeof(**(newelem)) ** _elem = (newelem) ; int _err = insertlast_queue( genericcast_queue(_sq), (void**)_elem, elemsize) ; _sq->nrelements += (_err == 0) ; _err ; }))

Implements syncqueue_t.insert2_syncqueue.

addtofreelist_syncqueue

#define addtofreelist_syncqueue(
   syncqueue,
   freelist,
   elem
) do { static_assert( sizeof(*(elem)) >= sizeof(dlist_node_t), "Check that element can hold a dlist_node_t") ; insertfirst_dlist( freelist, (dlist_node_t*)elem) ; } while (0)

Implements syncqueue_t.addtofreelist_syncqueue.

compact_syncqueue

#define compact_syncqueue(
   syncqueue,
   elem_t,
   freelist,
   initmove_elem
) ( __extension__ ({ void (*_im) (elem_t * dest, elem_t * src) ; _im = (initmove_elem) ; compact2_syncqueue( (syncqueue), sizeof(elem_t), (freelist), (void(*)(void*,void*))_im) ; }))

Implements syncqueue_t.compact_syncqueue.

init_syncqueue

#define init_syncqueue(
   syncqueue
) ((void)(*(syncqueue) = (syncqueue_t) syncqueue_INIT))

Implements syncqueue_t.init_syncqueue.

len_syncqueue

#define len_syncqueue(syncqueue) ((syncqueue)->nrelements)

Implements syncqueue_t.len_syncqueue.

queuefromaddr_syncqueue

#define queuefromaddr_syncqueue(
   nodeaddr
) ((syncqueue_t*)queuefromaddr_queue(nodeaddr))

Implements syncqueue_t.queuefromaddr_syncqueue.

remove_syncqueue

#define remove_syncqueue(
   syncqueue,
   elem,
   initmove_elem
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; typeof(elem) _elem = (elem) ; typeof(elem) _lastentry = last_queue( genericcast_queue(_sq), sizeof(*_elem)) ; if (_lastentry && _lastentry != _elem) { (initmove_elem)(_elem, _lastentry) ; } int _err = removelast_queue( genericcast_queue(_sq), sizeof(*_elem)) ; _sq->nrelements -= (_err == 0) ; _err ; }))

Implements syncqueue_t.remove_syncqueue.

removefirst_syncqueue

#define removefirst_syncqueue(
   syncqueue,
   elemsize
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; int _err = removefirst_queue( genericcast_queue(_sq), elemsize) ; _sq->nrelements -= (_err == 0) ; _err ; }))

Implements syncqueue_t.removefirst_syncqueue.

removelast_syncqueue

#define removelast_syncqueue(
   syncqueue,
   elemsize
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; int _err = removelast_queue( genericcast_queue(_sq), elemsize) ; _sq->nrelements -= (_err == 0) ; _err ; }))

Implements syncqueue_t.removelast_syncqueue.

struct syncrun_t
Manages a set of syncthread_t.
Adapts type queue_t for use in syncrun_t.
Implements SyncQueue.
typedef struct syncqueue_t syncqueue_t
Export syncqueue_t into global namespace.
struct syncqueue_t
Internal type to store zero or more syncthread_t + additional information.
int unittest_task_syncqueue(void)
Test syncqueue_t functionality.
struct syncthread_t
A simple function context which is executed in a cooperative way.
struct dlist_node_t * last
This variables makes syncqueue_t convertible to type queue_t.
size_t nrelements
Number of stored elements.
#define syncqueue_FREE syncqueue_INIT
Static initializer.
#define syncqueue_INIT { 0, 0 }
Static initializer.
void init_syncqueue(/*out*/syncqueue_t *syncqueue)
Initializes syncqueue.
int free_syncqueue(syncqueue_t *syncqueue)
Frees all allocated memory pages and clears syncqueue.
bool isfree_syncqueue(const syncqueue_t *syncqueue)
Returns true if syncqueue is equal to syncqueue_FREE.
size_t len_syncqueue(const syncqueue_t *syncqueue)
Returns the number of elements stored in the queue.
syncqueue_t * queuefromaddr_syncqueue(void *nodeaddr)
See queuefromaddr_queue.
#define queuefromaddr_queue(
   nodeaddr
) (((queue_page_t*)((uintptr_t)(nodeaddr) & ~((uintptr_t)pagesizeinbytes_queue()-1u)))->queue)
Implements queue_t.queuefromaddr_queue.
int insert_syncqueue(syncqueue_t *syncqueue,
IDNAME **newelem)
Add new element of type IDNAME to end of queue (last).
int insert2_syncqueue(syncqueue_t *syncqueue,
uint8_t elemsize,
IDNAME **newelem)
Add new element to end of queue (last).
int remove_syncqueue(syncqueue_t *syncqueue,
IDNAME *elem,
void (*initmove_elem)(IDNAME * dest, IDNAME * src))
Removes elem of type IDNAME from the queue by overwriting it with the last.
int removefirst_syncqueue(syncqueue_t *syncqueue,
uint16_t elemsize)
Removes an element from the queue by freeing syncqueue memory.
int removelast_syncqueue(syncqueue_t *syncqueue,
uint16_t elemsize)
Removes an element from the queue by freeing syncqueue memory.
void addtofreelist_syncqueue(syncqueue_t *syncqueue,
struct dlist_t *freelist,
IDNAME *elem)
Adds elem to freelist.
int compact_syncqueue(syncqueue_t *syncqueue,
IDNAME elem_t,
struct dlist_t *freelist,
void (*initmove_elem)(void * dest, void * src))
Moves elements from the end of queue to elements stored in freelist.
int compact2_syncqueue(syncqueue_t *syncqueue,
uint16_t elemsize,
struct dlist_t *freelist,
void (*initmove_elem)(void * dest, void * src))
Called from macro compact_syncqueue.
#define insert_syncqueue(
   syncqueue,
   newelem
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; typeof(**(newelem)) ** _elem = (newelem) ; int _err = insertlast_queue( genericcast_queue(_sq), (void**)_elem, sizeof(**_elem)) ; _sq->nrelements += (_err == 0) ; _err ; }))
Implements syncqueue_t.insert_syncqueue.
#define insert2_syncqueue(
   syncqueue,
   elemsize,
   newelem
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; typeof(**(newelem)) ** _elem = (newelem) ; int _err = insertlast_queue( genericcast_queue(_sq), (void**)_elem, elemsize) ; _sq->nrelements += (_err == 0) ; _err ; }))
Implements syncqueue_t.insert2_syncqueue.
#define addtofreelist_syncqueue(
   syncqueue,
   freelist,
   elem
) do { static_assert( sizeof(*(elem)) >= sizeof(dlist_node_t), "Check that element can hold a dlist_node_t") ; insertfirst_dlist( freelist, (dlist_node_t*)elem) ; } while (0)
Implements syncqueue_t.addtofreelist_syncqueue.
#define compact_syncqueue(
   syncqueue,
   elem_t,
   freelist,
   initmove_elem
) ( __extension__ ({ void (*_im) (elem_t * dest, elem_t * src) ; _im = (initmove_elem) ; compact2_syncqueue( (syncqueue), sizeof(elem_t), (freelist), (void(*)(void*,void*))_im) ; }))
Implements syncqueue_t.compact_syncqueue.
#define init_syncqueue(
   syncqueue
) ((void)(*(syncqueue) = (syncqueue_t) syncqueue_INIT))
Implements syncqueue_t.init_syncqueue.
#define len_syncqueue(syncqueue) ((syncqueue)->nrelements)
Implements syncqueue_t.len_syncqueue.
#define queuefromaddr_syncqueue(
   nodeaddr
) ((syncqueue_t*)queuefromaddr_queue(nodeaddr))
Implements syncqueue_t.queuefromaddr_syncqueue.
#define remove_syncqueue(
   syncqueue,
   elem,
   initmove_elem
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; typeof(elem) _elem = (elem) ; typeof(elem) _lastentry = last_queue( genericcast_queue(_sq), sizeof(*_elem)) ; if (_lastentry && _lastentry != _elem) { (initmove_elem)(_elem, _lastentry) ; } int _err = removelast_queue( genericcast_queue(_sq), sizeof(*_elem)) ; _sq->nrelements -= (_err == 0) ; _err ; }))
Implements syncqueue_t.remove_syncqueue.
#define removefirst_syncqueue(
   syncqueue,
   elemsize
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; int _err = removefirst_queue( genericcast_queue(_sq), elemsize) ; _sq->nrelements -= (_err == 0) ; _err ; }))
Implements syncqueue_t.removefirst_syncqueue.
#define removelast_syncqueue(
   syncqueue,
   elemsize
) ( __extension__ ({ syncqueue_t * _sq = (syncqueue) ; int _err = removelast_queue( genericcast_queue(_sq), elemsize) ; _sq->nrelements -= (_err == 0) ; _err ; }))
Implements syncqueue_t.removelast_syncqueue.
struct dlist_t
Double linked circular list.
#define genericcast_queue(
   queue
) ( __extension__ ({ static_assert( sizeof((queue)->last) == sizeof(((queue_t*)0)->last) && offsetof(typeof(*(queue)), last) == offsetof(queue_t, last) && (typeof((queue)->last))0 == (struct dlist_node_t*)0, "ensure compatible structure" ) ; (queue_t*) (queue) ; }))
Implements queue_t.genericcast_queue.
Close