ReadWriteLock Linuximpl

Implements ReadWriteLock.

Summary
ReadWriteLock LinuximplImplements ReadWriteLock.
CopyrightThis program is free software.
Files
C-kern/api/platform/sync/rwlock.hHeader file ReadWriteLock.
C-kern/platform/Linux/sync/rwlock.cImplementation file ReadWriteLock Linuximpl.
rwlock_t
helper
INTERFACE_rwlocklistUse macro slist_IMPLEMENT to generate an adapted interface of slist_t to thread_t.
lifetime
query
synchronize
lockflag_rwlockWait until rwlock->lockflag is cleared and set it atomically.
unlockflag_rwlockClear rwlock->lockflag.
wakeupreader_rwlockWakes up all readers waiting in rwlock->readers.
wakeupwriter_rwlockWakes up the first writer stored in list rwlock->writers.
insertandwait_rwlockAdds thread to list of waiting threads in rwlock.
test

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/platform/sync/rwlock.h

Header file ReadWriteLock.

C-kern/platform/Linux/sync/rwlock.c

Implementation file ReadWriteLock Linuximpl.

rwlock_t

Summary
helper
INTERFACE_rwlocklistUse macro slist_IMPLEMENT to generate an adapted interface of slist_t to thread_t.
lifetime
query
synchronize
lockflag_rwlockWait until rwlock->lockflag is cleared and set it atomically.
unlockflag_rwlockClear rwlock->lockflag.
wakeupreader_rwlockWakes up all readers waiting in rwlock->readers.
wakeupwriter_rwlockWakes up the first writer stored in list rwlock->writers.
insertandwait_rwlockAdds thread to list of waiting threads in rwlock.
test

helper

INTERFACE_rwlocklist

Use macro slist_IMPLEMENT to generate an adapted interface of slist_t to thread_t.

lifetime

query

synchronize

lockflag_rwlock

static inline void lockflag_rwlock(rwlock_t *rwlock)

Wait until rwlock->lockflag is cleared and set it atomically.  Includes an acuire memory barrier.  Calling thread can see what was written by other threads before the flag was set.

unlockflag_rwlock

static inline void unlockflag_rwlock(rwlock_t *rwlock)

Clear rwlock->lockflag.  Include a release memory barrier.  All other threads can see what was written before flag was cleared.

wakeupreader_rwlock

static inline void wakeupreader_rwlock(rwlock_t *rwlock)

Wakes up all readers waiting in rwlock->readers.

(unchecked) Precondition

  • rwlock->lockflag is set.
  • rwlock->readers not empty

wakeupwriter_rwlock

static inline void wakeupwriter_rwlock(rwlock_t *rwlock)

Wakes up the first writer stored in list rwlock->writers.

(unchecked) Precondition

  • rwlock->lockflag is set.
  • rwlock->writers not empty

insertandwait_rwlock

static inline void insertandwait_rwlock(rwlock_t *rwlock,
slist_t *waitlist,
thread_t *self)

Adds thread to list of waiting threads in rwlock. rwlock->lockflag is cleared and thread is suspended.  If the thread is resumed lockflag of thread is set and nextwait of thread is checked against 0 and then lockflag of thread is cleared.  If nextwait is 0 the function returns else the thread suspends itself again.

(unchecked) Precondition

  • rwlock->lockflag is set.

test

Implements a simple many readers and single writer lock for threads of a single process.
Implements ReadWriteLock.
#define slist_IMPLEMENT(
   _fsuffix,
   object_t,
   name_nextptr
) typedef slist_iterator_t iteratortype##_fsuffix ; typedef object_t * iteratedtype##_fsuffix ; static inline int initfirst##_fsuffix##iterator(slist_iterator_t * iter, slist_t * list) __attribute__ ((always_inline)) ; static inline int free##_fsuffix##iterator(slist_iterator_t * iter) __attribute__ ((always_inline)) ; static inline bool next##_fsuffix##iterator(slist_iterator_t * iter, object_t ** node) __attribute__ ((always_inline)) ; static inline void init##_fsuffix(slist_t * list) __attribute__ ((always_inline)) ; static inline int free##_fsuffix(slist_t * list, struct typeadapt_t * typeadp) __attribute__ ((always_inline)) ; static inline int isempty##_fsuffix(const slist_t * list) __attribute__ ((always_inline)) ; static inline object_t * first##_fsuffix(const slist_t * list) __attribute__ ((always_inline)) ; static inline object_t * last##_fsuffix(const slist_t * list) __attribute__ ((always_inline)) ; static inline object_t * next##_fsuffix(object_t * node) __attribute__ ((always_inline)) ; static inline bool isinlist##_fsuffix(object_t * node) __attribute__ ((always_inline)) ; static inline void insertfirst##_fsuffix(slist_t * list, object_t * new_node) __attribute__ ((always_inline)) ; static inline void insertlast##_fsuffix(slist_t * list, object_t * new_node) __attribute__ ((always_inline)) ; static inline void insertafter##_fsuffix(slist_t * list, object_t * prev_node, object_t * new_node) __attribute__ ((always_inline)) ; static inline int removefirst##_fsuffix(slist_t * list, object_t ** removed_node) __attribute__ ((always_inline)) ; static inline int removeafter##_fsuffix(slist_t * list, object_t * prev_node, object_t ** removed_node) __attribute__ ((always_inline)) ; static inline int removeall##_fsuffix(slist_t * list, struct typeadapt_t * typeadp) __attribute__ ((always_inline)) ; static inline slist_node_t * asnode##_fsuffix(object_t * object) { static_assert(&((object_t*)0)->name_nextptr == (slist_node_t**)offsetof(object_t, name_nextptr), "correct type") ; return (slist_node_t *) ((uintptr_t)object + offsetof(object_t, name_nextptr)) ; } static inline object_t * asobject##_fsuffix(slist_node_t * node) { return (object_t *) ((uintptr_t)node - offsetof(object_t, name_nextptr)) ; } static inline object_t * asobjectnull##_fsuffix(slist_node_t * node) { return node ? (object_t *) ((uintptr_t)node - offsetof(object_t, name_nextptr)) : 0 ; } static inline void init##_fsuffix(slist_t * list) { init_slist(list) ; } static inline void initsingle##_fsuffix(slist_t * list, object_t * node) { initsingle_slist(list, asnode##_fsuffix(node)) ; } static inline int free##_fsuffix(slist_t * list, struct typeadapt_t * typeadp) { return free_slist(list, offsetof(object_t, name_nextptr), typeadp) ; } static inline int isempty##_fsuffix(const slist_t * list) { return isempty_slist(list) ; } static inline object_t * first##_fsuffix(const slist_t * list) { return asobjectnull##_fsuffix(first_slist(list)) ; } static inline object_t * last##_fsuffix(const slist_t * list) { return asobjectnull##_fsuffix(last_slist(list)) ; } static inline object_t * next##_fsuffix(object_t * node) { return asobject##_fsuffix(next_slist(asnode##_fsuffix(node))) ; } static inline bool isinlist##_fsuffix(object_t * node) { return isinlist_slist(asnode##_fsuffix(node)) ; } static inline void insertfirst##_fsuffix(slist_t * list, object_t * new_node) { insertfirst_slist(list, asnode##_fsuffix(new_node)) ; } static inline void insertlast##_fsuffix(slist_t * list, object_t * new_node) { insertlast_slist(list, asnode##_fsuffix(new_node)) ; } static inline void insertafter##_fsuffix(slist_t * list, object_t * prev_node, object_t * new_node) { insertafter_slist(list, asnode##_fsuffix(prev_node), asnode##_fsuffix(new_node)) ; } static inline int removefirst##_fsuffix(slist_t * list, object_t ** removed_node) { int err = removefirst_slist(list, (slist_node_t**)removed_node) ; if (!err) *removed_node = asobject##_fsuffix(*(slist_node_t**)removed_node) ; return err ; } static inline int removeafter##_fsuffix(slist_t * list, object_t * prev_node, object_t ** removed_node) { int err = removeafter_slist(list, asnode##_fsuffix(prev_node), (slist_node_t**)removed_node) ; if (!err) *removed_node = asobject##_fsuffix(*(slist_node_t**)removed_node) ; return err ; } static inline int removeall##_fsuffix(slist_t * list, struct typeadapt_t * typeadp) { return removeall_slist(list, offsetof(object_t, name_nextptr), typeadp) ; } static inline int initfirst##_fsuffix##iterator(slist_iterator_t * iter, slist_t * list) { return initfirst_slistiterator(iter, list) ; } static inline int free##_fsuffix##iterator(slist_iterator_t * iter) { return free_slistiterator(iter) ; } static inline bool next##_fsuffix##iterator(slist_iterator_t * iter, object_t ** node) { bool isNext = next_slistiterator(iter, (slist_node_t**)node) ; if (isNext) *node = asobject##_fsuffix(*(slist_node_t**)node) ; return isNext ; }
Implements slist_t.slist_IMPLEMENT.
static inline void lockflag_rwlock(rwlock_t *rwlock)
Wait until rwlock->lockflag is cleared and set it atomically.
static inline void unlockflag_rwlock(rwlock_t *rwlock)
Clear rwlock->lockflag.
static inline void wakeupreader_rwlock(rwlock_t *rwlock)
Wakes up all readers waiting in rwlock->readers.
static inline void wakeupwriter_rwlock(rwlock_t *rwlock)
Wakes up the first writer stored in list rwlock->writers.
static inline void insertandwait_rwlock(rwlock_t *rwlock,
slist_t *waitlist,
thread_t *self)
Adds thread to list of waiting threads in rwlock.
Close