+int sthread_sem_init(sthread_sem_t* sem, int /*pshared*/, unsigned int value)
+{
+ auto s = sg4::Semaphore::create(value);
+ intrusive_ptr_add_ref(s.get());
+
+ sem->sem = s.get();
+ return 0;
+}
+int sthread_sem_destroy(sthread_sem_t* sem)
+{
+ intrusive_ptr_release(static_cast<sg4::Semaphore*>(sem->sem));
+ return 0;
+}
+int sthread_sem_post(sthread_sem_t* sem)
+{
+ static_cast<sg4::Semaphore*>(sem->sem)->release();
+ return 0;
+}
+int sthread_sem_wait(sthread_sem_t* sem)
+{
+ static_cast<sg4::Semaphore*>(sem->sem)->acquire();
+ return 0;
+}
+int sthread_sem_trywait(sthread_sem_t* sem)
+{
+ auto* s = static_cast<sg4::Semaphore*>(sem->sem);
+ if (s->would_block()) {
+ errno = EAGAIN;
+ return -1;
+ }
+ s->acquire();
+ return 0;
+}
+int sthread_sem_timedwait(sthread_sem_t* sem, const struct timespec* abs_timeout)
+{
+ if (static_cast<sg4::Semaphore*>(sem->sem)->acquire_timeout(static_cast<double>(abs_timeout->tv_sec) +
+ static_cast<double>(abs_timeout->tv_nsec) / 1E9)) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ return 0;
+}