diff options
Diffstat (limited to 'nptl/DESIGN-sem-old.txt')
-rw-r--r-- | nptl/DESIGN-sem-old.txt | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/nptl/DESIGN-sem-old.txt b/nptl/DESIGN-sem-old.txt new file mode 100644 index 0000000..2db2f35 --- /dev/null +++ b/nptl/DESIGN-sem-old.txt @@ -0,0 +1,67 @@ +Semaphores pseudocode +============================== + + int sem_wait(sem_t * sem); + int sem_trywait(sem_t * sem); + int sem_post(sem_t * sem); + int sem_getvalue(sem_t * sem, int * sval); + +struct sem_t { + + unsigned int lock: + - internal mutex + + unsigned int count; + - current semaphore count, also used as a futex + + unsigned int waiters; + - number of threads queued in sem_wait(). +} + +sem_wait(sem_t *sem) +{ + lll_lock(sem->lock); + for (;;) { + + if (sem->count) + break; + + sem->waiters++; + lll_unlock(sem->lock); + + futex_wait(&sem->count, 0) + + lll_lock(sem->lock); + sem->waiters--; + } + sem->count--; + lll_unlock(sem->lock); +} + +sem_post(sem_t *sem) +{ + lll_lock(sem->lock); + sem->count++; + if (sem->waiters) + futex_wake(&sem->count, sem->count); + lll_unlock(sem->lock); +} + +sem_trywait(sem_t *sem) +{ + lll_lock(sem->lock); + if (sem->count) { + sem->count--; + lll_unlock(sem->lock); + return 0; + } else { + lll_unlock(sem->lock); + return -EAGAIN; + } +} + +sem_getvalue(sem_t *sem, int *sval) +{ + *sval = sem->count; + read_barrier(); +} |