Implements SyncRun.
SyncRun impl | Implements SyncRun. |
Copyright | This program is free software. |
Files | |
C-kern/ | Header file SyncRun. |
C-kern/ | Implementation file SyncRun impl. |
Types | |
struct initqueue_entry_t | Exports initqueue_entry_t into global namespace. |
runqueue_entry_t | Make runqueue_entry_t an alias for syncthread_t. |
struct run2queue_entry_t | Exports run2queue_entry_t into global namespace. |
struct waitqueue_entry_t | Exports waitqueue_entry_t into global namespace. |
struct wait2queue_entry_t | Exports wait2queue_entry_t into global namespace. |
Enumerations | |
syncrun_qid_e | Index into syncrun_t.queues. |
initqueue_entry_t | Helds all data needed to construct a new syncthread_t. |
lifetime | |
init_initqueueentry | Initialize initentry with mainfct and initarg. |
init2_initqueueentry | Initialize initentry with mainfct and initarg and initargsize. |
query | |
sizeentry_initqueueentry | The size in bytes of initqueue_entry_t depending on initargsize. |
runqueue_entry_t | Contains only a single syncthread_t. |
lifetime | |
init_runqueueentry | Initializes runentry with thread. |
initmove_runqueueentry | Initializes dest with src. |
run2queue_entry_t | Contains a single syncthread_t and its corresponding exitevent. |
lifetime | |
init_run2queueentry | Initializes runentry with thread and exitevent. |
initmove_run2queueentry | Initializes dest with src. |
waitqueue_entry_t | Contains waiting thread (syncwait_t). |
lifetime | |
init_waitqueueentry | Initializes waitentry with thread and uses srun->waitinfo to read the event and the continuelabel. |
initmove_waitqueueentry | Moves content of initialized src to dest. |
query | |
cast_waitqueueentry | Casts pointer to syncwait_t into pointer to waitqueue_entry_t. |
wait2queue_entry_t | Contains waiting thread (syncwait_t) and its exitevent. |
lifetime | |
init_wait2queueentry | Initializes waitentry with thread and exitevent and uses srun->waitinfo to read the event and the continuelabel. |
initmove_wait2queueentry | Moves content of initialized src to dest. |
query | |
cast_wait2queueentry | Casts pointer to syncwait_t into pointer to wait2queue_entry_t. |
syncrun_t | |
static variables | |
s_syncrun_errtimer | Allows to introduce artificial errors during test. |
lifetime | |
query | |
internal | |
thread-lifetime | |
synchronization | |
run | |
preparewakeup_syncrun | Sets all values in srun->wakeup (syncrun_t.wakeup). |
preparerun_syncrun | Sets all values in srun->running (syncrun_t.running). |
execwaiting_syncrun | Calls callwakeup_syncthread for a waiting thread given in waiting. |
execabort_syncrun | Calls callabort_syncthread for every thread stored in queue qith id qid. |
clearevents_syncrun | Set all <syncevent_t.waiting> pointer to 0 which reference threads in the wait queues. |
test | |
test_run | Test runall_syncrun with all possible state transitions. |
test_run2 | Test correct variable values of a single thread in every posible state. |
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 SyncRun.
Implementation file SyncRun impl.
typedef struct initqueue_entry_t initqueue_entry_t
Exports initqueue_entry_t into global namespace.
typedef struct runqueue_entry_t runqueue_entry_t
Make runqueue_entry_t an alias for syncthread_t.
typedef struct run2queue_entry_t run2queue_entry_t
Exports run2queue_entry_t into global namespace.
typedef struct waitqueue_entry_t waitqueue_entry_t
Exports waitqueue_entry_t into global namespace.
typedef struct wait2queue_entry_t wait2queue_entry_t
Exports wait2queue_entry_t into global namespace.
Index into syncrun_t.queues. syncrun_qid_INIT - Index of queue holding initqueue_entry_t which describe an unitialized thread with its init argument. syncrun_qid_RUN - Index of queue holding runqueue_entry_t which describe already initialized threads. syncrun_qid_RUN2 - Index of queue holding run2queue_entry_t which describe already initialized threads. These threads generate an exit event. syncrun_qid_WAIT - Index of queue holding waitqueue_entry_t which describes a thread waiting for an event/condition. syncrun_qid_WAIT2 - Index of queue holding wait2queue_entry_t which describes a thread waiting for an event/condition. These threads generate an exit event. syncrun_qid_WLIST - Index of queue holding entries of syncwlist_t (see wlistentry_t). Every entry references a waiting thread in <syncrun_qid_WAIT> or <syncrun_qid_WAIT2>. syncrun_qid_WAKEUP - Index of queue holding entries of syncevent_t which references a waiting thread in <syncrun_qid_WAIT> or <syncrun_qid_WAIT2>.
struct initqueue_entry_t
Helds all data needed to construct a new syncthread_t. The structure contains a syncthread_t its possible unused exitevent (syncevent_t) and the initargsize and initarg[] data of an possible allocated init argument.
lifetime | |
init_initqueueentry | Initialize initentry with mainfct and initarg. |
init2_initqueueentry | Initialize initentry with mainfct and initarg and initargsize. |
query | |
sizeentry_initqueueentry | The size in bytes of initqueue_entry_t depending on initargsize. |
static inline void init2_initqueueentry( initqueue_entry_t * initentry, syncrun_f mainfct, uint8_t initargsize )
Initialize initentry with mainfct and initarg and initargsize. The caller must have reserved sizeentry_initqueueentry bytes for initentry.
static inline uint16_t sizeentry_initqueueentry( uint8_t initargsize )
The size in bytes of initqueue_entry_t depending on initargsize. If initargsize is set to 0 the returned value equals sizeof(initqueue_entry_t).
struct runqueue_entry_t
Contains only a single syncthread_t. Entry will be stored in queue with id <syncrun_qid_RUN>.
lifetime | |
init_runqueueentry | Initializes runentry with thread. |
initmove_runqueueentry | Initializes dest with src. |
struct run2queue_entry_t
Contains a single syncthread_t and its corresponding exitevent. Entry will be stored in queue with id <syncrun_qid_RUN2>.
lifetime | |
init_run2queueentry | Initializes runentry with thread and exitevent. |
initmove_run2queueentry | Initializes dest with src. |
struct waitqueue_entry_t
Contains waiting thread (syncwait_t). Entry will be stored in queue with id <syncrun_qid_WAIT>.
lifetime | |
init_waitqueueentry | Initializes waitentry with thread and uses srun->waitinfo to read the event and the continuelabel. |
initmove_waitqueueentry | Moves content of initialized src to dest. |
query | |
cast_waitqueueentry | Casts pointer to syncwait_t into pointer to waitqueue_entry_t. |
static inline void init_waitqueueentry( /*out*/waitqueue_entry_t * waitentry, syncrun_t * srun, syncthread_t * thread )
Initializes waitentry with thread and uses srun->waitinfo to read the event and the continuelabel. The continuelabel stored in syncrun_t.waitinfo is the place, where execution will continue after wakeup.
static inline void initmove_waitqueueentry( /*out*/waitqueue_entry_t * dest, waitqueue_entry_t * src )
Moves content of initialized src to dest. After return dest contains previous content of dest (back pointer of referenced objects are adapted). Src is left untouched but is considered in an invalid, uninitialized state. You have to initialize it before src can be used again.
static inline waitqueue_entry_t * cast_waitqueueentry( syncwait_t * waitentry )
Casts pointer to syncwait_t into pointer to waitqueue_entry_t.
struct wait2queue_entry_t
Contains waiting thread (syncwait_t) and its exitevent. Entry will be stored in queue with id <syncrun_qid_WAIT2>.
lifetime | |
init_wait2queueentry | Initializes waitentry with thread and exitevent and uses srun->waitinfo to read the event and the continuelabel. |
initmove_wait2queueentry | Moves content of initialized src to dest. |
query | |
cast_wait2queueentry | Casts pointer to syncwait_t into pointer to wait2queue_entry_t. |
static inline void init_wait2queueentry( /*out*/wait2queue_entry_t * waitentry, syncrun_t * srun, syncthread_t * thread, syncevent_t * exitevent )
Initializes waitentry with thread and exitevent and uses srun->waitinfo to read the event and the continuelabel. The continuelabel stored in syncrun_t.waitinfo is the place, where execution will continue after wakeup.
static inline void initmove_wait2queueentry( /*out*/wait2queue_entry_t * dest, wait2queue_entry_t * src )
Moves content of initialized src to dest. After return dest contains previous content of dest (back pointer of referenced objects are adapted). Src is left untouched but is considered in an invalid, uninitialized state. You have to initialize it before src can be used again.
static inline wait2queue_entry_t * cast_wait2queueentry( syncwait_t * waitentry )
Casts pointer to syncwait_t into pointer to wait2queue_entry_t.
static variables | |
s_syncrun_errtimer | Allows to introduce artificial errors during test. |
lifetime | |
query | |
internal | |
thread-lifetime | |
synchronization | |
run | |
preparewakeup_syncrun | Sets all values in srun->wakeup (syncrun_t.wakeup). |
preparerun_syncrun | Sets all values in srun->running (syncrun_t.running). |
execwaiting_syncrun | Calls callwakeup_syncthread for a waiting thread given in waiting. |
execabort_syncrun | Calls callabort_syncthread for every thread stored in queue qith id qid. |
clearevents_syncrun | Set all <syncevent_t.waiting> pointer to 0 which reference threads in the wait queues. |
test | |
test_run | Test runall_syncrun with all possible state transitions. |
test_run2 | Test correct variable values of a single thread in every posible state. |
static test_errortimer_t s_syncrun_errtimer
Allows to introduce artificial errors during test. Only defined if KONFIG_UNITTEST is defined.
static inline void preparewakeup_syncrun( syncrun_t * srun, void * continuelabel, int retcode )
Sets all values in srun->wakeup (syncrun_t.wakeup). Parameter continuelabel and retcode are copied into the corresponding data members of wakeup. This function is called before a waiting threads is woken up.
static inline int preparerun_syncrun( syncrun_t * srun, syncthread_t * running_thread )
Sets all values in srun->running (syncrun_t.running). The exitevent of the last started thread is set to 0 meaning that there is no previously started thread. The running thread thread is set to value of parameter running_thread. The state of the thread is initialized to syncrun_state_CONTINUE. Therefore threads run until they exit or abort themselves.
static int execwaiting_syncrun( syncrun_t * srun, syncwait_t * waiting, int retcode )
Calls callwakeup_syncthread for a waiting thread given in waiting. The argument retcode is set into srun->wakeup and is the return code of the exited syncthread_t. Function waitforexit_syncrun returns this retcode as its own return value. For other types of events retcode is ignored (see waitforevent_syncrun and waitforlist_syncrun). If the called syncthread exits or aborts and another thread waits for its exit the function calls itself. If the waiting thread waits for another event after return it will be kept in the wait queue. If its state is syncrun_state_CONTINUE after return it will be moved into queue <syncrun_qid_RUN> or queue <syncrun_qid_RUN2>.
static int execabort_syncrun( syncrun_t * srun, enum syncrun_qid_e qid, uint16_t entrysize )
Calls callabort_syncthread for every thread stored in queue qith id qid. The parameter entrysize gives the size of an entry in the queue. The initqueue is therefore not supported. All queue entries are removed. This function assumes that clearevents_syncrun has been called before. If you abort threads stored in queue with qid <syncrun_qid_RUN2> or <syncrun_qid_WAIT2> other threads waiting for them to exit are not woken up. Therefore execabort_syncrun is always called in the context of <abortall_syncrun>.
Exports initqueue_entry_t into global namespace.
typedef struct initqueue_entry_t initqueue_entry_t
Helds all data needed to construct a new syncthread_t.
struct initqueue_entry_t
Make runqueue_entry_t an alias for syncthread_t.
typedef struct runqueue_entry_t runqueue_entry_t
A simple function context which is executed in a cooperative way.
struct syncthread_t
Exports run2queue_entry_t into global namespace.
typedef struct run2queue_entry_t run2queue_entry_t
Contains a single syncthread_t and its corresponding exitevent.
struct run2queue_entry_t
Exports waitqueue_entry_t into global namespace.
typedef struct waitqueue_entry_t waitqueue_entry_t
Contains waiting thread (syncwait_t).
struct waitqueue_entry_t
Exports wait2queue_entry_t into global namespace.
typedef struct wait2queue_entry_t wait2queue_entry_t
Contains waiting thread (syncwait_t) and its exitevent.
struct wait2queue_entry_t
Queues wich are used to store syncthread_t.
syncqueue_t queues[7]
Initialize initentry with mainfct and initarg.
static inline void init_initqueueentry( initqueue_entry_t * initentry, syncrun_f mainfct, void * initarg )
Initialize initentry with mainfct and initarg and initargsize.
static inline void init2_initqueueentry( initqueue_entry_t * initentry, syncrun_f mainfct, uint8_t initargsize )
The size in bytes of initqueue_entry_t depending on initargsize.
static inline uint16_t sizeentry_initqueueentry( uint8_t initargsize )
Initializes runentry with thread.
static inline void init_runqueueentry( /*out*/runqueue_entry_t * runentry, const syncthread_t * thread )
Initializes dest with src.
static inline void initmove_runqueueentry( /*out*/runqueue_entry_t * dest, runqueue_entry_t * src )
Initializes runentry with thread and exitevent.
static inline void init_run2queueentry( /*out*/run2queue_entry_t * runentry, syncthread_t * thread, syncevent_t * exitevent )
Initializes dest with src.
static inline void initmove_run2queueentry( /*out*/run2queue_entry_t * dest, run2queue_entry_t * src )
Describes a syncthread_t waiting for a syncevent_t.
struct syncwait_t
Initializes waitentry with thread and uses srun->waitinfo to read the event and the continuelabel.
static inline void init_waitqueueentry( /*out*/waitqueue_entry_t * waitentry, syncrun_t * srun, syncthread_t * thread )
Moves content of initialized src to dest.
static inline void initmove_waitqueueentry( /*out*/waitqueue_entry_t * dest, waitqueue_entry_t * src )
Casts pointer to syncwait_t into pointer to waitqueue_entry_t.
static inline waitqueue_entry_t * cast_waitqueueentry( syncwait_t * waitentry )
Initializes waitentry with thread and exitevent and uses srun->waitinfo to read the event and the continuelabel.
static inline void init_wait2queueentry( /*out*/wait2queue_entry_t * waitentry, syncrun_t * srun, syncthread_t * thread, syncevent_t * exitevent )
Moves content of initialized src to dest.
static inline void initmove_wait2queueentry( /*out*/wait2queue_entry_t * dest, wait2queue_entry_t * src )
Casts pointer to syncwait_t into pointer to wait2queue_entry_t.
static inline wait2queue_entry_t * cast_wait2queueentry( syncwait_t * waitentry )
Allows to introduce artificial errors during test.
static test_errortimer_t s_syncrun_errtimer
Sets all values in srun->wakeup (syncrun_t.wakeup).
static inline void preparewakeup_syncrun( syncrun_t * srun, void * continuelabel, int retcode )
Stores information used during wakeup of a thread which waited for an event.
struct { void * continuelabel ; int retcode ; } wakeup
Sets all values in srun->running (syncrun_t.running).
static inline int preparerun_syncrun( syncrun_t * srun, syncthread_t * running_thread )
Stores information of the current thread and its running state.
struct { struct syncevent_t * laststarted ; struct syncthread_t * thread ; uint8_t state ; } running
Calls callwakeup_syncthread for a waiting thread given in waiting.
static int execwaiting_syncrun( syncrun_t * srun, syncwait_t * waiting, int retcode )
Implements syncthread_t.callwakeup_syncthread.
#define callwakeup_syncthread( sthread ) ( __extension__ ({ typeof(sthread) _sthread = (sthread) ; _sthread->mainfct(_sthread, syncthread_signal_WAKEUP) ; }))
Calls callabort_syncthread for every thread stored in queue qith id qid.
static int execabort_syncrun( syncrun_t * srun, enum syncrun_qid_e qid, uint16_t entrysize )
Implements syncthread_t.callabort_syncthread.
#define callabort_syncthread( sthread ) ( __extension__ ({ typeof(sthread) _sthread = (sthread) ; _sthread->mainfct(_sthread, syncthread_signal_ABORT) ; }))
Set all syncevent_t.waiting pointer to 0 which reference threads in the wait queues.
static int clearevents_syncrun( syncrun_t * srun )
Test runall_syncrun with all possible state transitions.
static int test_run( void )
Test correct variable values of a single thread in every posible state.
static int test_run2( void )
Implements a double linked list of syncevent_t and stores them in a syncqueue_t.
struct syncwlist_t
Type of entry stored in syncwlist_t.
struct wlistentry_t
Event type stores a pointer to a single waiting syncwait_t.
struct syncevent_t
Stores waiting information of the running thread if its state is changed to syncrun_state_WAIT.
struct { struct syncwlist_t * wlist ; struct syncevent_t * event ; void * continuelabel ; } waitinfo
Define this in your Makefile to include additional code for testing single components.
#define KONFIG_UNITTEST
Implements syncrun_t.waitforexit_syncrun.
#define waitforexit_syncrun( srun ) ( __extension__ ({ __label__ waitlabel ; setstatewait_syncrun((srun), srun->running.laststarted, __extension__ && waitlabel) ; return 0 ; waitlabel: retcode_syncrun(srun) ; }))
Implements syncrun_t.waitforevent_syncrun.
#define waitforevent_syncrun( srun, syncevent ) ( __extension__ ({ __label__ waitlabel ; setstatewait_syncrun((srun), (syncevent), __extension__ && waitlabel) ; return 0 ; waitlabel: (void)0 ; }))
Implements syncrun_t.waitforlist_syncrun.
#define waitforlist_syncrun( srun, syncwlist ) ( __extension__ ({ __label__ waitlabel ; setstatewaitlist_syncrun((srun), (syncwlist), __extension__ && waitlabel) ; return 0 ; waitlabel: (void)0 ; }))