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