Adapts type queue_t for use in syncrun_t.
You need to include types queue_t and dlist_t before calling the inline functions.
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 SyncQueue.
Implementation file SyncQueue impl.
typedef struct syncqueue_t syncqueue_t
Export syncqueue_t into global namespace.
test | |
unittest_task_syncqueue | Test syncqueue_t functionality. |
int unittest_task_syncqueue( void )
Test syncqueue_t functionality.
struct syncqueue_t
Internal type to store zero or more syncthread_t + additional information. This object uses queue_t to implement its functionality.
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.
last | This variables makes syncqueue_t convertible to type queue_t. |
nrelements | Number of stored elements. |
lifetime | |
syncqueue_FREE | Static initializer. |
syncqueue_INIT | Static initializer. |
init_syncqueue | Initializes syncqueue. |
free_syncqueue | Frees all allocated memory pages and clears syncqueue. |
query | |
isfree_syncqueue | Returns true if syncqueue is equal to syncqueue_FREE. |
len_syncqueue | Returns the number of elements stored in the queue. |
queuefromaddr_syncqueue | See queuefromaddr_queue. |
update | |
insert_syncqueue | Add new element of type IDNAME to end of queue (last). |
insert2_syncqueue | Add new element to end of queue (last). |
remove_syncqueue | Removes elem of type IDNAME from the queue by overwriting it with the last. |
removefirst_syncqueue | Removes an element from the queue by freeing syncqueue memory. |
removelast_syncqueue | Removes an element from the queue by freeing syncqueue memory. |
addtofreelist_syncqueue | Adds elem to freelist. |
compact_syncqueue | Moves elements from the end of queue to elements stored in freelist. |
compact2_syncqueue | Called from macro compact_syncqueue. |
struct dlist_node_t * last
This variables makes syncqueue_t convertible to type queue_t.
bool isfree_syncqueue( const syncqueue_t * syncqueue )
Returns true if syncqueue is equal to syncqueue_FREE.
syncqueue_t * queuefromaddr_syncqueue( void * nodeaddr )
See queuefromaddr_queue.
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.
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.
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).
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.
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.
#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.
Manages a set of syncthread_t.
struct syncrun_t
Export syncqueue_t into global namespace.
typedef struct syncqueue_t syncqueue_t
Internal type to store zero or more syncthread_t + additional information.
struct syncqueue_t
Test syncqueue_t functionality.
int unittest_task_syncqueue( void )
A simple function context which is executed in a cooperative way.
struct syncthread_t
This variables makes syncqueue_t convertible to type queue_t.
struct dlist_node_t * last
Number of stored elements.
size_t nrelements
Static initializer.
#define syncqueue_FREE syncqueue_INIT
Static initializer.
#define syncqueue_INIT { 0, 0 }
Initializes syncqueue.
void init_syncqueue( /*out*/syncqueue_t * syncqueue )
Frees all allocated memory pages and clears syncqueue.
int free_syncqueue( syncqueue_t * syncqueue )
Returns true if syncqueue is equal to syncqueue_FREE.
bool isfree_syncqueue( const syncqueue_t * syncqueue )
Returns the number of elements stored in the queue.
size_t len_syncqueue( const syncqueue_t * syncqueue )
See queuefromaddr_queue.
syncqueue_t * queuefromaddr_syncqueue( void * nodeaddr )
Implements queue_t.queuefromaddr_queue.
#define queuefromaddr_queue( nodeaddr ) (((queue_page_t*)((uintptr_t)(nodeaddr) & ~((uintptr_t)pagesizeinbytes_queue()-1u)))->queue)
Add new element of type IDNAME to end of queue (last).
int insert_syncqueue( syncqueue_t * syncqueue, IDNAME ** newelem )
Add new element to end of queue (last).
int insert2_syncqueue( syncqueue_t * syncqueue, uint8_t elemsize, IDNAME ** newelem )
Removes elem of type IDNAME from the queue by overwriting it with the last.
int remove_syncqueue( syncqueue_t * syncqueue, IDNAME * elem, void (*initmove_elem)(IDNAME * dest, IDNAME * src) )
Removes an element from the queue by freeing syncqueue memory.
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 )
Adds elem to freelist.
void addtofreelist_syncqueue( syncqueue_t * syncqueue, struct dlist_t * freelist, IDNAME * elem )
Moves elements from the end of queue to elements stored in freelist.
int compact_syncqueue( syncqueue_t * syncqueue, IDNAME elem_t, struct dlist_t * freelist, void (*initmove_elem)(void * dest, void * src) )
Called from macro compact_syncqueue.
int compact2_syncqueue( syncqueue_t * syncqueue, uint16_t elemsize, struct dlist_t * freelist, void (*initmove_elem)(void * dest, void * src) )
Implements syncqueue_t.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.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.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.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.init_syncqueue.
#define init_syncqueue( syncqueue ) ((void)(*(syncqueue) = (syncqueue_t) syncqueue_INIT))
Implements syncqueue_t.len_syncqueue.
#define len_syncqueue( syncqueue ) ((syncqueue)->nrelements)
Implements syncqueue_t.queuefromaddr_syncqueue.
#define queuefromaddr_syncqueue( nodeaddr ) ((syncqueue_t*)queuefromaddr_queue(nodeaddr))
Implements syncqueue_t.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.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.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 ; }))
Double linked circular list.
struct dlist_t
Implements queue_t.genericcast_queue.
#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) ; }))