#include #include "ucore/ticket_lock.h" //pthread implementation of http://en.wikipedia.org/wiki/Ticket_lock //The underlying phtread mutex is not held while the lock is acquired. //This will allow other threads to enqueue itself. // //The condition variable is needed to wake up threads waiting to acquire //the lock instead of letting the system block on the pthread mutex while waiting. int uc_ticket_lock_init(struct UCTicketLock *lock) { return uc_ticket_lock_init_ex(lock, NULL, NULL); } int uc_ticket_lock_init_ex(struct UCTicketLock *lock, pthread_mutexattr_t *mattr, pthread_condattr_t *cattr) { int rc; lock->queue_head = 0; lock->queue_tail = 0; rc = pthread_mutex_init(&lock->mutex, mattr); assert(rc == 0); if (rc != 0) { return rc; } rc = pthread_cond_init(&lock->cond, cattr); if (rc != 0) { pthread_mutex_destroy(&lock->mutex); } assert(rc == 0); return rc; } void uc_ticket_lock(struct UCTicketLock *lock) { unsigned long queue_me; pthread_mutex_lock(&lock->mutex); queue_me = lock->queue_tail++; while (queue_me != lock->queue_head) { pthread_cond_wait(&lock->cond, &lock->mutex); } pthread_mutex_unlock(&lock->mutex); } void uc_ticket_unlock(struct UCTicketLock *lock) { pthread_mutex_lock(&lock->mutex); lock->queue_head++; pthread_cond_broadcast(&lock->cond); pthread_mutex_unlock(&lock->mutex); }