[libc-commits] [libc] [libc][semaphore] Add post and wait operations for internal semaphore (PR #198959)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Fri Jun 12 12:53:14 PDT 2026


================
@@ -54,6 +81,83 @@ class Semaphore {
         const_cast<Futex &>(value).load(cpp::MemoryOrder::RELAXED));
   }
 
+  // Atomically increments the semaphore value and
+  // wakes one blocked waiter if any.
+  LIBC_INLINE int post() {
+    FutexWordType v = value.load(cpp::MemoryOrder::RELAXED);
+
+    do {
+      if (v >= SEM_VALUE_MAX)
+        return EOVERFLOW;
+      // RELEASE on success, since post should publish prior writes
+      // RELAXED on failure, since no synchronization event occurs
+    } while (!value.compare_exchange_weak(v, v + 1, cpp::MemoryOrder::RELEASE,
+                                          cpp::MemoryOrder::RELAXED));
+
+    // Wake one waiter if any,
+    // waiter selection is left to linux futex implementation.
+    value.notify_one(is_shared);
+    return 0;
+  }
+
+  // Attempts to decrement the semaphore value without blocking.
+  LIBC_INLINE int trywait() {
+    FutexWordType v = value.load(cpp::MemoryOrder::RELAXED);
+
+    while (v > 0) {
+      // ACQUIRE on success to synchronize with the matching post().
+      if (value.compare_exchange_weak(v, v - 1, cpp::MemoryOrder::ACQUIRE,
+                                      cpp::MemoryOrder::RELAXED))
+        return 0;
+    }
+
+    return EAGAIN;
+  }
+
+  // Blocking wait, decrements the value when positive, or blocks until a
+  // post() makes it positive again.
+  LIBC_INLINE int wait() {
+    for (;;) {
+      if (trywait() == 0)
+        return 0;
----------------
michaelrj-google wrote:

This could be simplified:
```suggestion
    while (trywait() == 0) {
```
Then put `return 0` after the end of the loop

https://github.com/llvm/llvm-project/pull/198959


More information about the libc-commits mailing list