From 298ba74a45802d0da5d25b5518dc098016f34166 Mon Sep 17 00:00:00 2001
From: Justine Tunney <jtunney@gmail.com>
Date: Thu, 23 Feb 2023 08:07:54 -0800
Subject: [PATCH] Make POSIX semaphores always process shared

Python triggered the undefined behavior previously since it appears to
be posting to a semaphore owned by a different process that wasn't set
to process shared mode. The performance loss to process shared futexes
is so low and semaphores are generally used for this purpose, so it'll
be much simpler to simply not impose undefined behavior here.
---
 libc/thread/sem_getvalue.c            |  1 -
 libc/thread/sem_post.c                |  3 +-
 libc/thread/sem_timedwait.c           |  2 +-
 libc/thread/sem_trywait.c             |  1 -
 test/libc/thread/sem_timedwait_test.c | 48 ---------------------------
 5 files changed, 2 insertions(+), 53 deletions(-)

diff --git a/libc/thread/sem_getvalue.c b/libc/thread/sem_getvalue.c
index db638f248..f1ac20b40 100644
--- a/libc/thread/sem_getvalue.c
+++ b/libc/thread/sem_getvalue.c
@@ -29,7 +29,6 @@
  * @return 0 on success, or -1 w/ errno
  */
 int sem_getvalue(sem_t *sem, int *sval) {
-  _unassert(sem->sem_pshared || sem->sem_pid == getpid());
   *sval = atomic_load_explicit(&sem->sem_value, memory_order_relaxed);
   return 0;
 }
diff --git a/libc/thread/sem_post.c b/libc/thread/sem_post.c
index 4587c9938..37c5f3f43 100644
--- a/libc/thread/sem_post.c
+++ b/libc/thread/sem_post.c
@@ -33,11 +33,10 @@
  */
 int sem_post(sem_t *sem) {
   int rc, old, wakeups;
-  _unassert(sem->sem_pshared || sem->sem_pid == getpid());
   old = atomic_fetch_add_explicit(&sem->sem_value, 1, memory_order_acq_rel);
   _unassert(old > INT_MIN);
   if (old >= 0) {
-    wakeups = nsync_futex_wake_(&sem->sem_value, 1, sem->sem_pshared);
+    wakeups = nsync_futex_wake_(&sem->sem_value, 1, true);
     _npassert(wakeups >= 0);
     rc = 0;
   } else {
diff --git a/libc/thread/sem_timedwait.c b/libc/thread/sem_timedwait.c
index bc3fa15c2..9419fab74 100644
--- a/libc/thread/sem_timedwait.c
+++ b/libc/thread/sem_timedwait.c
@@ -75,7 +75,7 @@ int sem_timedwait(sem_t *sem, const struct timespec *abstime) {
 
   do {
     if (!(v = atomic_load_explicit(&sem->sem_value, memory_order_relaxed))) {
-      rc = nsync_futex_wait_(&sem->sem_value, v, sem->sem_pshared, abstime);
+      rc = nsync_futex_wait_(&sem->sem_value, v, true, abstime);
       if (rc == -EINTR || rc == -ECANCELED) {
         errno = -rc;
         rc = -1;
diff --git a/libc/thread/sem_trywait.c b/libc/thread/sem_trywait.c
index 765a4187a..0fa730554 100644
--- a/libc/thread/sem_trywait.c
+++ b/libc/thread/sem_trywait.c
@@ -34,7 +34,6 @@
  */
 int sem_trywait(sem_t *sem) {
   int v;
-  _unassert(sem->sem_pshared || sem->sem_pid == getpid());
   v = atomic_load_explicit(&sem->sem_value, memory_order_relaxed);
   do {
     _unassert(v > INT_MIN);
diff --git a/test/libc/thread/sem_timedwait_test.c b/test/libc/thread/sem_timedwait_test.c
index 7fa087d2d..bb8beb2a7 100644
--- a/test/libc/thread/sem_timedwait_test.c
+++ b/test/libc/thread/sem_timedwait_test.c
@@ -42,54 +42,6 @@ TEST(sem_init, einval) {
   ASSERT_SYS(EINVAL, -1, sem_init(&sem, 0, -1));
 }
 
-TEST(sem_post, accessInChildProcessWhenNotPshared_isUndefinedBehavior) {
-  if (!IsModeDbg()) return;
-  int val;
-  sem_t sem;
-  ASSERT_SYS(0, 0, sem_init(&sem, 0, 0));
-  SPAWN(fork);
-  IgnoreStderr();
-  sem_post(&sem);
-  EXITS(77);
-}
-
-TEST(sem_getvalue, accessInChildProcessWhenNotPshared_isUndefinedBehavior) {
-  if (!IsModeDbg()) return;
-  int val;
-  sem_t sem;
-  ASSERT_SYS(0, 0, sem_init(&sem, 0, 0));
-  ASSERT_SYS(0, 0, sem_getvalue(&sem, &val));
-  SPAWN(fork);
-  IgnoreStderr();
-  sem_getvalue(&sem, &val);
-  EXITS(77);
-  ASSERT_SYS(0, 0, sem_destroy(&sem));
-}
-
-TEST(sem_timedwait, accessInChildProcessWhenNotPshared_isUndefinedBehavior) {
-  if (!IsModeDbg()) return;
-  int val;
-  sem_t sem;
-  ASSERT_SYS(0, 0, sem_init(&sem, 0, 0));
-  SPAWN(fork);
-  IgnoreStderr();
-  sem_timedwait(&sem, 0);
-  EXITS(77);
-  ASSERT_SYS(0, 0, sem_destroy(&sem));
-}
-
-TEST(sem_trywait, accessInChildProcessWhenNotPshared_isUndefinedBehavior) {
-  if (!IsModeDbg()) return;
-  int val;
-  sem_t sem;
-  ASSERT_SYS(0, 0, sem_init(&sem, 0, 0));
-  SPAWN(fork);
-  IgnoreStderr();
-  sem_trywait(&sem);
-  EXITS(77);
-  ASSERT_SYS(0, 0, sem_destroy(&sem));
-}
-
 TEST(sem_post, afterDestroyed_isUndefinedBehavior) {
   if (!IsModeDbg()) return;
   int val;