// XXX *technically* there is a race condition that could allow // XXX a signal to be missed. If thread A is preempted in _wait() // XXX after unlocking the mutex and before waiting, and if other // XXX threads call signal or broadcast UINT_MAX/2 times (exactly), // XXX before thread A is scheduled again and calls futex_wait(), // XXX then the signal will be lost.
// We use one bit in pthread_condattr_t (long) values as the 'shared' flag // and one bit for the clock type (CLOCK_REALTIME is 0 and // CLOCK_MONOTONIC is 1). The rest of the bits are a counter. // // The 'value' field in pthread_cond_t has the same layout.
static_assert(sizeof(pthread_cond_t) == sizeof(pthread_cond_internal_t), "pthread_cond_t should actually be pthread_cond_internal_t in implementation.");
// For binary compatibility with old version of pthread_cond_t, we can't use more strict alignment // than 4-byte alignment.
static_assert(alignof(pthread_cond_t) == 4, "pthread_cond_t should fulfill the alignment requirement of pthread_cond_internal_t.");
// This function is used by pthread_cond_broadcast and // pthread_cond_signal to atomically decrement the counter // then wake up thread_count threads. staticint __pthread_cond_pulse(pthread_cond_internal_t* cond, int thread_count) { // We don't use a release/seq_cst fence here. Because pthread_cond_wait/signal can't be // used as a method for memory synchronization by itself. It should always be used with // pthread mutexes. Note that Spurious wakeups from pthread_cond_wait/timedwait may occur, // so when using condition variables there is always a boolean predicate involving shared // variables associated with each condition wait that is true if the thread should proceed. // If the predicate is seen true before a condition wait, pthread_cond_wait/timedwait will // 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.
#ifdefined(__LP64__) if (atomic_load_explicit(&cond->waiters, memory_order_relaxed) == 0) { return0;
} #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);
#if !defined(__LP64__) // This exists only for backward binary compatibility on 32 bit platforms. // (This is actually a _new_ function in API 28 that we could only implement for LP64.) extern"C"int pthread_cond_timedwait_monotonic(pthread_cond_t* cond_interface,
pthread_mutex_t* mutex, const timespec* abs_timeout) { return pthread_cond_timedwait_monotonic_np(cond_interface, mutex, abs_timeout);
} #endif
#if !defined(__LP64__) // This exists only for backward binary compatibility on 32 bit platforms. // (This function never existed for LP64.) extern"C"int pthread_cond_timedwait_relative_np(pthread_cond_t* cond_interface,
pthread_mutex_t* mutex, const timespec* rel_timeout) {
timespec ts;
timespec* abs_timeout = nullptr; if (rel_timeout != nullptr) {
absolute_timespec_from_timespec(ts, *rel_timeout, CLOCK_MONOTONIC);
abs_timeout = &ts;
} return __pthread_cond_timedwait(__get_internal_cond(cond_interface), mutex, false, abs_timeout);
} #endif
#if !defined(__LP64__) // This exists only for backward binary compatibility on 32 bit platforms. // (This function never existed for LP64.) extern"C"int pthread_cond_timeout_np(pthread_cond_t* cond_interface,
pthread_mutex_t* mutex, unsigned ms) {
timespec ts;
timespec_from_ms(ts, ms); return pthread_cond_timedwait_relative_np(cond_interface, mutex, &ts);
} #endif
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.