summary refs log tree commit diff
path: root/nptl/DESIGN-sem-old.txt
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/DESIGN-sem-old.txt')
-rw-r--r--nptl/DESIGN-sem-old.txt67
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 0000000000..2db2f35ce2
--- /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();
+}