Browse Source

threads: add vlc_queuedmutex_held()

pull/138/head
Denis Charmet 4 years ago
parent
commit
c49d643801
  1. 19
      include/vlc_threads.h
  2. 9
      src/misc/threads.c

19
include/vlc_threads.h

@ -578,9 +578,10 @@ VLC_API void vlc_latch_wait(vlc_latch_t *);
typedef struct { typedef struct {
atomic_uint head; atomic_uint head;
atomic_uint tail; atomic_uint tail;
atomic_ulong owner;
} vlc_queuedmutex_t; } vlc_queuedmutex_t;
#define VLC_STATIC_QUEUEDMUTEX { ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0) } #define VLC_STATIC_QUEUEDMUTEX { ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0) }
void vlc_queuedmutex_init(vlc_queuedmutex_t *m); void vlc_queuedmutex_init(vlc_queuedmutex_t *m);
@ -588,6 +589,22 @@ void vlc_queuedmutex_lock(vlc_queuedmutex_t *m);
void vlc_queuedmutex_unlock(vlc_queuedmutex_t *m); void vlc_queuedmutex_unlock(vlc_queuedmutex_t *m);
/**
* Checks if a queued mutex is locked.
*
* This function checks if the calling thread holds a given queued mutual
* exclusion lock. It has no side effects and is essentially intended for
* run-time debugging.
*
* @note To assert that the calling thread holds a lock, the helper macro
* vlc_queuedmutex_assert() should be used instead of this function.
*
* @retval false the mutex is not locked by the calling thread
* @retval true the mutex is locked by the calling thread
*/
bool vlc_queuedmutex_held(vlc_queuedmutex_t *m);
#define vlc_queuedmutex_assert(m) assert(vlc_queuedmutex_held(m))
/** /**
* One-time initialization. * One-time initialization.
* *

9
src/misc/threads.c

@ -467,6 +467,12 @@ void vlc_queuedmutex_init(vlc_queuedmutex_t *m)
{ {
atomic_init(&m->head, 0); atomic_init(&m->head, 0);
atomic_init(&m->tail, 0); atomic_init(&m->tail, 0);
atomic_init(&m->owner, 0);
}
bool vlc_queuedmutex_held(vlc_queuedmutex_t *m)
{
return (vlc_thread_id() == atomic_load_explicit(&m->owner, memory_order_relaxed));
} }
void vlc_queuedmutex_lock(vlc_queuedmutex_t *m) void vlc_queuedmutex_lock(vlc_queuedmutex_t *m)
@ -478,10 +484,13 @@ void vlc_queuedmutex_lock(vlc_queuedmutex_t *m)
while ((head = atomic_load_explicit(&m->head, while ((head = atomic_load_explicit(&m->head,
memory_order_acquire)) != ticket) memory_order_acquire)) != ticket)
vlc_atomic_wait(&m->head, head); vlc_atomic_wait(&m->head, head);
atomic_store_explicit(&m->owner, vlc_thread_id(), memory_order_relaxed);
} }
void vlc_queuedmutex_unlock(vlc_queuedmutex_t *m) void vlc_queuedmutex_unlock(vlc_queuedmutex_t *m)
{ {
atomic_store_explicit(&m->owner, 0, memory_order_relaxed);
atomic_fetch_add_explicit(&m->head, 1, memory_order_release); atomic_fetch_add_explicit(&m->head, 1, memory_order_release);
vlc_atomic_notify_all(&m->head); vlc_atomic_notify_all(&m->head);
} }

Loading…
Cancel
Save