Merge "Avoid tsan warning about pthread_mutex_destroy."
This commit is contained in:
commit
ea5bb151af
@ -166,10 +166,13 @@ int pthread_mutexattr_getpshared(const pthread_mutexattr_t* attr, int* pshared)
|
|||||||
#define MUTEX_STATE_BITS_LOCKED_UNCONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_UNCONTENDED)
|
#define MUTEX_STATE_BITS_LOCKED_UNCONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_UNCONTENDED)
|
||||||
#define MUTEX_STATE_BITS_LOCKED_CONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_CONTENDED)
|
#define MUTEX_STATE_BITS_LOCKED_CONTENDED MUTEX_STATE_TO_BITS(MUTEX_STATE_LOCKED_CONTENDED)
|
||||||
|
|
||||||
/* return true iff the mutex if locked with no waiters */
|
// Return true iff the mutex is unlocked.
|
||||||
|
#define MUTEX_STATE_BITS_IS_UNLOCKED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_UNLOCKED)
|
||||||
|
|
||||||
|
// Return true iff the mutex is locked with no waiters.
|
||||||
#define MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_UNCONTENDED)
|
#define MUTEX_STATE_BITS_IS_LOCKED_UNCONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_UNCONTENDED)
|
||||||
|
|
||||||
/* return true iff the mutex if locked with maybe waiters */
|
// return true iff the mutex is locked with maybe waiters.
|
||||||
#define MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_CONTENDED)
|
#define MUTEX_STATE_BITS_IS_LOCKED_CONTENDED(v) (((v) & MUTEX_STATE_MASK) == MUTEX_STATE_BITS_LOCKED_CONTENDED)
|
||||||
|
|
||||||
/* used to flip from LOCKED_UNCONTENDED to LOCKED_CONTENDED */
|
/* used to flip from LOCKED_UNCONTENDED to LOCKED_CONTENDED */
|
||||||
@ -637,10 +640,14 @@ int pthread_mutex_timedlock(pthread_mutex_t* mutex_interface, const timespec* ab
|
|||||||
}
|
}
|
||||||
|
|
||||||
int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) {
|
int pthread_mutex_destroy(pthread_mutex_t* mutex_interface) {
|
||||||
// Use trylock to ensure that the mutex is valid and not already locked.
|
pthread_mutex_internal_t* mutex = __get_internal_mutex(mutex_interface);
|
||||||
int error = pthread_mutex_trylock(mutex_interface);
|
uint16_t old_state = atomic_load_explicit(&mutex->state, memory_order_relaxed);
|
||||||
if (error != 0) {
|
// Store 0xffff to make the mutex unusable. Although POSIX standard says it is undefined
|
||||||
return error;
|
// behavior to destroy a locked mutex, we prefer not to change mutex->state in that situation.
|
||||||
}
|
if (MUTEX_STATE_BITS_IS_UNLOCKED(old_state) &&
|
||||||
|
atomic_compare_exchange_strong_explicit(&mutex->state, &old_state, 0xffff,
|
||||||
|
memory_order_relaxed, memory_order_relaxed)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return EBUSY;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user