Merge "pthread_cond: only call futex_wake when there are waiters"
diff --git a/libc/bionic/pthread_cond.cpp b/libc/bionic/pthread_cond.cpp
index e857069..793dcd9 100644
--- a/libc/bionic/pthread_cond.cpp
+++ b/libc/bionic/pthread_cond.cpp
@@ -116,7 +116,8 @@
   }
 
 #if defined(__LP64__)
-  char __reserved[44];
+  atomic_uint waiters;
+  char __reserved[40];
 #endif
 };
 
@@ -141,6 +142,10 @@
   }
   atomic_init(&cond->state, init_state);
 
+#if defined(__LP64__)
+  atomic_init(&cond->waiters, 0);
+#endif
+
   return 0;
 }
 
@@ -163,6 +168,12 @@
   // not be called. That's why pthread_wait/signal pair can't be used as a method for memory
   // synchronization. And it doesn't help even if we use any fence here.
 
+#if defined(__LP64__)
+  if (atomic_load_explicit(&cond->waiters, memory_order_relaxed) == 0) {
+    return 0;
+  }
+#endif
+
   // The increase of value should leave flags alone, even if the value can overflows.
   atomic_fetch_add_explicit(&cond->state, COND_COUNTER_STEP, memory_order_relaxed);
 
@@ -178,9 +189,19 @@
   }
 
   unsigned int old_state = atomic_load_explicit(&cond->state, memory_order_relaxed);
+
+#if defined(__LP64__)
+  atomic_fetch_add_explicit(&cond->waiters, 1, memory_order_relaxed);
+#endif
+
   pthread_mutex_unlock(mutex);
   int status = __futex_wait_ex(&cond->state, cond->process_shared(), old_state,
                                use_realtime_clock, abs_timeout_or_null);
+
+#if defined(__LP64__)
+  atomic_fetch_sub_explicit(&cond->waiters, 1, memory_order_relaxed);
+#endif
+
   pthread_mutex_lock(mutex);
 
   if (status == -ETIMEDOUT) {