source: CIVL/examples/pthread/cprover/06_ticket_true.c@ 1aaefd4

main test-branch
Last change on this file since 1aaefd4 was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 1.5 KB
Line 
1//Ticket lock with proportional backoff
2//
3//From Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors, 1991 (Fig. 2).
4//Also available as pseudo-code here: http://www.cs.rochester.edu/research/synchronization/pseudocode/ss.html#ticket
5
6#include <pthread.h>
7
8#define assume(e) __VERIFIER_assume(e)
9#define assert(e) { if(!(e)) { ERROR: goto ERROR; (void)0; } }
10
11volatile unsigned next_ticket = 0;
12volatile unsigned now_serving = 0;
13
14#define FAILED 3 //this is already and the limit of what we can handle
15
16#define NEXT(e) ((e + 1) % FAILED)
17// #define NEXT(e) ((e+1 == FAILED)?0:e+1)
18
19unsigned __VERIFIER_atomic_fetch_and_increment__next_ticket(){
20 unsigned value;
21
22 if(NEXT(next_ticket) == now_serving){
23 value = FAILED;
24 }
25 else
26 {
27 value = next_ticket;
28 next_ticket = NEXT(next_ticket);
29 }
30
31 return value;
32}
33
34inline void acquire_lock(){
35 unsigned my_ticket;
36
37 my_ticket = __VERIFIER_atomic_fetch_and_increment__next_ticket(); //returns old value; arithmetic overflow is harmless (Alex: it is not if we have 2^64 threads)
38
39 if(my_ticket == FAILED){
40 assume(0);
41 }else{
42 while(1){
43 //pause(my_ticket - now_serving);
44 // consume this many units of time
45 // on most machines, subtraction works correctly despite overflow
46 if(now_serving == my_ticket){
47 break;
48 }
49 }
50 }
51
52 return;
53}
54
55inline void release_lock(){
56 now_serving++;
57}
58
59int c = 0;
60void* thr1(void* arg){
61 acquire_lock();
62 c++;
63 assert(c == 1);
64 c--;
65 release_lock();
66
67 return 0;
68}
69
70int main(){
71 pthread_t t;
72
73 while(1) { pthread_create(&t, 0, thr1, 0); }
74}
75
Note: See TracBrowser for help on using the repository browser.