]> git.lizzy.rs Git - rust.git/blob - src/rt/sync/fair_ticket_lock.cpp
Populate tree.
[rust.git] / src / rt / sync / fair_ticket_lock.cpp
1 /*
2  * This works well as long as the number of contending threads
3  * is less than the number of processors. This is because of
4  * the fair locking scheme. If the thread that is next in line
5  * for acquiring the lock is not currently running, no other
6  * thread can acquire the lock. This is terrible for performance,
7  * and it seems that all fair locking schemes suffer from this
8  * behavior.
9  */
10
11 // #define TRACE
12
13 fair_ticket_lock::fair_ticket_lock() {
14     next_ticket = now_serving = 0;
15 }
16
17 fair_ticket_lock::~fair_ticket_lock() {
18
19 }
20
21 void fair_ticket_lock::lock() {
22     unsigned ticket = __sync_fetch_and_add(&next_ticket, 1);
23     while (now_serving != ticket) {
24         pause();
25     }
26 #ifdef TRACE
27     printf("locked   nextTicket: %d nowServing: %d",
28             next_ticket, now_serving);
29 #endif
30 }
31
32 void fair_ticket_lock::unlock() {
33     now_serving++;
34 #ifdef TRACE
35     printf("unlocked nextTicket: %d nowServing: %d",
36             next_ticket, now_serving);
37 #endif
38 }
39
40 void fair_ticket_lock::pause() {
41     asm volatile("pause\n" : : : "memory");
42 }
43