Build on wheezy, and presumably precise
[invirt/third/libt4.git] / lock_tester.cc
1 //
2 // Lock server tester
3 //
4
5 #include "lock_protocol.h"
6 #include "lock_client.h"
7 #include "rpc.h"
8 #include "jsl_log.h"
9 #include <arpa/inet.h>
10 #include <vector>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include "lang/verify.h"
14 #include "lock_client_cache_rsm.h"
15 #include "tprintf.h"
16 #include <sys/types.h>
17 #include <unistd.h>
18
19 char tprintf_thread_prefix = 'c';
20
21 // must be >= 2
22 int nt = 6; //XXX: lab1's rpc handlers are blocking. Since rpcs uses a thread pool of 10 threads, we cannot test more than 10 blocking rpc.
23 std::string dst;
24 lock_client_cache_rsm **lc = new lock_client_cache_rsm * [nt];
25 lock_protocol::lockid_t a = 1;
26 lock_protocol::lockid_t b = 2;
27 lock_protocol::lockid_t c = 3;
28
29 // check_grant() and check_release() check that the lock server
30 // doesn't grant the same lock to both clients.
31 // it assumes that lock names are distinct in the first byte.
32 int ct[256];
33 pthread_mutex_t count_mutex;
34
35 void
36 check_grant(lock_protocol::lockid_t lid)
37 {
38   ScopedLock ml(&count_mutex);
39   int x = lid & 0xff;
40   if(ct[x] != 0){
41     fprintf(stderr, "error: server granted %016llx twice\n", lid);
42     fprintf(stdout, "error: server granted %016llx twice\n", lid);
43     exit(1);
44   }
45   ct[x] += 1;
46 }
47
48 void
49 check_release(lock_protocol::lockid_t lid)
50 {
51   ScopedLock ml(&count_mutex);
52   int x = lid & 0xff;
53   if(ct[x] != 1){
54     fprintf(stderr, "error: client released un-held lock %016llx\n",  lid);
55     exit(1);
56   }
57   ct[x] -= 1;
58 }
59
60 void
61 test1(void)
62 {
63     tprintf ("acquire a release a acquire a release a\n");
64     lc[0]->acquire(a);
65     check_grant(a);
66     lc[0]->release(a);
67     check_release(a);
68     lc[0]->acquire(a);
69     check_grant(a);
70     lc[0]->release(a);
71     check_release(a);
72
73     tprintf ("acquire a acquire b release b release a\n");
74     lc[0]->acquire(a);
75     check_grant(a);
76     lc[0]->acquire(b);
77     check_grant(b);
78     lc[0]->release(b);
79     check_release(b);
80     lc[0]->release(a);
81     check_release(a);
82 }
83
84 void *
85 test2(void *x) 
86 {
87   int i = * (int *) x;
88
89   tprintf ("test2: client %d acquire a release a\n", i);
90   lc[i]->acquire(a);
91   tprintf ("test2: client %d acquire done\n", i);
92   check_grant(a);
93   sleep(1);
94   tprintf ("test2: client %d release\n", i);
95   check_release(a);
96   lc[i]->release(a);
97   tprintf ("test2: client %d release done\n", i);
98   return 0;
99 }
100
101 void *
102 test3(void *x)
103 {
104   int i = * (int *) x;
105
106   tprintf ("test3: client %d acquire a release a concurrent\n", i);
107   for (int j = 0; j < 10; j++) {
108     lc[i]->acquire(a);
109     check_grant(a);
110     tprintf ("test3: client %d got lock\n", i);
111     check_release(a);
112     lc[i]->release(a);
113   }
114   return 0;
115 }
116
117 void *
118 test4(void *x)
119 {
120   int i = * (int *) x;
121
122   tprintf ("test4: thread %d acquire a release a concurrent; same clnt\n", i);
123   for (int j = 0; j < 10; j++) {
124     lc[0]->acquire(a);
125     check_grant(a);
126     tprintf ("test4: thread %d on client 0 got lock\n", i);
127     check_release(a);
128     lc[0]->release(a);
129   }
130   return 0;
131 }
132
133 void *
134 test5(void *x)
135 {
136   int i = * (int *) x;
137
138   tprintf ("test5: client %d acquire a release a concurrent; same and diff clnt\n", i);
139   for (int j = 0; j < 10; j++) {
140     if (i < 5)  lc[0]->acquire(a);
141     else  lc[1]->acquire(a);
142     check_grant(a);
143     tprintf ("test5: client %d got lock\n", i);
144     check_release(a);
145     if (i < 5) lc[0]->release(a);
146     else lc[1]->release(a);
147   }
148   return 0;
149 }
150
151 int
152 main(int argc, char *argv[])
153 {
154     int r;
155     pthread_t th[nt];
156     int test = 0;
157
158     setvbuf(stdout, NULL, _IONBF, 0);
159     setvbuf(stderr, NULL, _IONBF, 0);
160     srandom(getpid());
161
162     //jsl_set_debug(2);
163
164     if(argc < 2) {
165       fprintf(stderr, "Usage: %s [host:]port [test]\n", argv[0]);
166       exit(1);
167     }
168
169     dst = argv[1]; 
170
171     if (argc > 2) {
172       test = atoi(argv[2]);
173       if(test < 1 || test > 5){
174         tprintf("Test number must be between 1 and 5\n");
175         exit(1);
176       }
177     }
178
179     VERIFY(pthread_mutex_init(&count_mutex, NULL) == 0);
180     tprintf("cache lock client\n");
181     for (int i = 0; i < nt; i++) lc[i] = new lock_client_cache_rsm(dst);
182
183     if(!test || test == 1){
184       test1();
185     }
186
187     if(!test || test == 2){
188       // test2
189       for (int i = 0; i < nt; i++) {
190         int *a = new int (i);
191         r = pthread_create(&th[i], NULL, test2, (void *) a);
192         VERIFY (r == 0);
193       }
194       for (int i = 0; i < nt; i++) {
195         pthread_join(th[i], NULL);
196       }
197     }
198
199     if(!test || test == 3){
200       tprintf("test 3\n");
201       
202       // test3
203       for (int i = 0; i < nt; i++) {
204         int *a = new int (i);
205         r = pthread_create(&th[i], NULL, test3, (void *) a);
206         VERIFY (r == 0);
207       }
208       for (int i = 0; i < nt; i++) {
209         pthread_join(th[i], NULL);
210       }
211     }
212
213     if(!test || test == 4){
214       tprintf("test 4\n");
215       
216       // test 4
217       for (int i = 0; i < 2; i++) {
218         int *a = new int (i);
219         r = pthread_create(&th[i], NULL, test4, (void *) a);
220         VERIFY (r == 0);
221       }
222       for (int i = 0; i < 2; i++) {
223         pthread_join(th[i], NULL);
224       }
225     }
226
227     if(!test || test == 5){
228       tprintf("test 5\n");
229       
230       // test 5
231       
232       for (int i = 0; i < nt; i++) {
233         int *a = new int (i);
234         r = pthread_create(&th[i], NULL, test5, (void *) a);
235         VERIFY (r == 0);
236       }
237       for (int i = 0; i < nt; i++) {
238         pthread_join(th[i], NULL);
239       }
240     }
241
242     tprintf ("%s: passed all tests successfully\n", argv[0]);
243
244 }