Merging r58073 through r58111 from trunk into soc-2013-depsgraph_mt
[blender.git] / source / blender / blenlib / intern / threads.c
index cd3132682b6e05c5f02e7fffb6b04e4fcc03f3b9..033213dff5d3ec9ea4b2d75c847937fd6fba13cf 100644 (file)
@@ -513,6 +513,52 @@ void BLI_rw_mutex_free(ThreadRWMutex *mutex)
        MEM_freeN(mutex);
 }
 
+/* Ticket Mutex Lock */
+
+struct TicketMutex {
+       pthread_cond_t cond;
+       pthread_mutex_t mutex;
+       unsigned int queue_head, queue_tail;
+};
+
+TicketMutex *BLI_ticket_mutex_alloc(void)
+{
+       TicketMutex *ticket = MEM_callocN(sizeof(TicketMutex), "TicketMutex");
+
+       pthread_cond_init(&ticket->cond, NULL);
+       pthread_mutex_init(&ticket->mutex, NULL);
+
+       return ticket;
+}
+
+void BLI_ticket_mutex_free(TicketMutex *ticket)
+{
+       pthread_mutex_destroy(&ticket->mutex);
+       pthread_cond_destroy(&ticket->cond);
+       MEM_freeN(ticket);
+}
+
+void BLI_ticket_mutex_lock(TicketMutex *ticket)
+{
+       unsigned int queue_me;
+
+       pthread_mutex_lock(&ticket->mutex);
+       queue_me = ticket->queue_tail++;
+
+       while (queue_me != ticket->queue_head)
+               pthread_cond_wait(&ticket->cond, &ticket->mutex);
+
+       pthread_mutex_unlock(&ticket->mutex);
+}
+
+void BLI_ticket_mutex_unlock(TicketMutex *ticket)
+{
+       pthread_mutex_lock(&ticket->mutex);
+       ticket->queue_head++;
+       pthread_cond_broadcast(&ticket->cond);
+       pthread_mutex_unlock(&ticket->mutex);
+}
+
 /* ************************************************ */
 
 typedef struct ThreadedWorker {