root / xseg / xtypes / xcache_test.c @ 7cf0125c
History | View | Annotate | Download (7.1 kB)
1 |
#include "xcache.h" |
---|---|
2 |
#include <stdio.h> |
3 |
#include <stdlib.h> |
4 |
#include <pthread.h> |
5 |
#include <xtypes/xlock.h> |
6 |
#include <sys/time.h> |
7 |
|
8 |
|
9 |
unsigned long sum = 0; |
10 |
struct xlock lock;
|
11 |
uint32_t lru = 0;
|
12 |
|
13 |
struct ce{
|
14 |
unsigned long tid; |
15 |
}; |
16 |
|
17 |
int init(void *c, void *e) |
18 |
{ |
19 |
return 0; |
20 |
} |
21 |
|
22 |
void put_unsafe(void *c, void *e) |
23 |
{ |
24 |
sum++; |
25 |
} |
26 |
|
27 |
void put_safe(void *c, void *e) |
28 |
{ |
29 |
__sync_add_and_fetch(&sum, 1);
|
30 |
} |
31 |
|
32 |
void put_test(void *c, void *e) |
33 |
{ |
34 |
struct ce *ce = e;
|
35 |
if (ce->tid){
|
36 |
fprintf(stderr, "Invalid lru eviction\n");
|
37 |
fprintf(stderr, "test3: failed\n");
|
38 |
} else {
|
39 |
fprintf(stderr, "test3: PASSED\n");
|
40 |
} |
41 |
} |
42 |
|
43 |
void *node_init(void *c) |
44 |
{ |
45 |
return malloc(sizeof(struct ce)); |
46 |
} |
47 |
|
48 |
|
49 |
int test1(unsigned long n) |
50 |
{ |
51 |
struct xcache cache;
|
52 |
struct xcache_ops c_ops = {
|
53 |
.on_init = init, |
54 |
.on_put = put_unsafe, |
55 |
.on_node_init = node_init |
56 |
}; |
57 |
xcache_handler h; |
58 |
sum = 0;
|
59 |
char name[XSEG_MAX_TARGETLEN];
|
60 |
unsigned long i; |
61 |
int r;
|
62 |
|
63 |
xcache_init(&cache, n, &c_ops, lru, NULL);
|
64 |
|
65 |
for (i = 0; i < n; i++) { |
66 |
sprintf(name, "%lu", i);
|
67 |
h = xcache_lookup(&cache, name); |
68 |
if (h != NoEntry){
|
69 |
fprintf(stderr, "Cache return cache entry\n");
|
70 |
return -1; |
71 |
} |
72 |
|
73 |
h = xcache_alloc_init(&cache, name); |
74 |
if (h == NoEntry){
|
75 |
fprintf(stderr, "Could not allocate cache entry\n");
|
76 |
return -1; |
77 |
} |
78 |
r = xcache_insert(&cache, h); |
79 |
if (r < 0){ |
80 |
xcache_put(&cache, h); |
81 |
fprintf(stderr, "Could not insert cache entry\n");
|
82 |
return -1; |
83 |
} |
84 |
xcache_put(&cache, h); |
85 |
} |
86 |
|
87 |
for (i = 0; i < n; i++) { |
88 |
sprintf(name, "%lu", i);
|
89 |
h = xcache_lookup(&cache, name); |
90 |
if (h == NoEntry){
|
91 |
fprintf(stderr, "Cache lookup failed\n");
|
92 |
return -1; |
93 |
} |
94 |
xcache_put(&cache, h); |
95 |
} |
96 |
|
97 |
for (i = n; i < 2*n; i++) { |
98 |
sprintf(name, "%lu", i);
|
99 |
h = xcache_lookup(&cache, name); |
100 |
if (h != NoEntry){
|
101 |
fprintf(stderr, "Cache return cache entry\n");
|
102 |
return -1; |
103 |
} |
104 |
|
105 |
h = xcache_alloc_init(&cache, name); |
106 |
if (h == NoEntry){
|
107 |
fprintf(stderr, "Could not allocate cache entry\n");
|
108 |
return -1; |
109 |
} |
110 |
r = xcache_insert(&cache, h); |
111 |
if (r < 0){ |
112 |
xcache_put(&cache, h); |
113 |
fprintf(stderr, "Could not insert cache entry\n");
|
114 |
return -1; |
115 |
} |
116 |
xcache_put(&cache, h); |
117 |
} |
118 |
xcache_close(&cache); |
119 |
if (sum != 2*n){ |
120 |
fprintf(stderr, "%lu puts instead of %lu\n", sum, 2*n); |
121 |
return -1; |
122 |
} |
123 |
return 0; |
124 |
} |
125 |
|
126 |
|
127 |
int test3(unsigned long n) |
128 |
{ |
129 |
struct xcache cache;
|
130 |
struct xcache_ops c_ops = {
|
131 |
.on_init = init, |
132 |
.on_put = put_test, |
133 |
.on_node_init = node_init |
134 |
}; |
135 |
struct ce *ce;
|
136 |
xcache_handler h; |
137 |
sum = 0;
|
138 |
char name[XSEG_MAX_TARGETLEN];
|
139 |
unsigned long i; |
140 |
int r;
|
141 |
|
142 |
xcache_init(&cache, n, &c_ops, lru, NULL);
|
143 |
|
144 |
for (i = 0; i < n; i++) { |
145 |
sprintf(name, "%lu", i);
|
146 |
h = xcache_lookup(&cache, name); |
147 |
if (h != NoEntry){
|
148 |
fprintf(stderr, "Cache return cache entry\n");
|
149 |
return -1; |
150 |
} |
151 |
|
152 |
h = xcache_alloc_init(&cache, name); |
153 |
if (h == NoEntry){
|
154 |
fprintf(stderr, "Could not allocate cache entry\n");
|
155 |
return -1; |
156 |
} |
157 |
ce = get_cache_entry(&cache, h); |
158 |
ce->tid = i; |
159 |
r = xcache_insert(&cache, h); |
160 |
if (r < 0){ |
161 |
xcache_put(&cache, h); |
162 |
fprintf(stderr, "Could not insert cache entry\n");
|
163 |
return -1; |
164 |
} |
165 |
xcache_put(&cache, h); |
166 |
} |
167 |
|
168 |
sprintf(name, "%lu", n);
|
169 |
h = xcache_lookup(&cache, name); |
170 |
if (h != NoEntry){
|
171 |
fprintf(stderr, "Cache return cache entry\n");
|
172 |
return -1; |
173 |
} |
174 |
|
175 |
h = xcache_alloc_init(&cache, name); |
176 |
if (h == NoEntry){
|
177 |
fprintf(stderr, "Could not allocate cache entry\n");
|
178 |
return -1; |
179 |
} |
180 |
r = xcache_insert(&cache, h); |
181 |
if (r < 0){ |
182 |
xcache_put(&cache, h); |
183 |
fprintf(stderr, "Could not insert cache entry\n");
|
184 |
return -1; |
185 |
} |
186 |
xcache_put(&cache, h); |
187 |
|
188 |
//xcache_close(&cache);
|
189 |
return 0; |
190 |
} |
191 |
|
192 |
struct thread_arg{
|
193 |
struct xcache *cache;
|
194 |
unsigned long tid; |
195 |
unsigned long n; |
196 |
}; |
197 |
|
198 |
void *thread_test(void *arg) |
199 |
{ |
200 |
struct thread_arg *targ = (struct thread_arg *)arg; |
201 |
unsigned long n = targ->n; |
202 |
unsigned long i; |
203 |
xcache_handler h; |
204 |
char name[XSEG_MAX_TARGETLEN];
|
205 |
int r;
|
206 |
|
207 |
for (i = 0; i < n; i++) { |
208 |
sprintf(name, "%lu_%lu", targ->tid, i);
|
209 |
h = xcache_alloc_init(targ->cache, name); |
210 |
if (h == NoEntry){
|
211 |
fprintf(stderr, "Could not allocate cache entry\n");
|
212 |
return NULL; |
213 |
} |
214 |
r = xcache_insert(targ->cache, h); |
215 |
if (r < 0){ |
216 |
xcache_put(targ->cache, h); |
217 |
fprintf(stderr, "Could not insert cache entry\n");
|
218 |
return NULL; |
219 |
} |
220 |
xcache_put(targ->cache, h); |
221 |
} |
222 |
return NULL; |
223 |
} |
224 |
|
225 |
int test2(unsigned long cache_size, unsigned long n, unsigned long nr_threads) |
226 |
{ |
227 |
struct xcache cache;
|
228 |
struct xcache_ops c_ops = {
|
229 |
.on_init = init, |
230 |
.on_put = put_safe, |
231 |
.on_node_init = node_init |
232 |
}; |
233 |
xcache_handler h; |
234 |
sum = 0;
|
235 |
unsigned long i; |
236 |
int r;
|
237 |
|
238 |
xcache_init(&cache, cache_size, &c_ops, lru, NULL);
|
239 |
|
240 |
struct thread_arg *targs = malloc(sizeof(struct thread_arg)*nr_threads * n); |
241 |
pthread_t *threads = malloc(sizeof(pthread_t) * nr_threads);
|
242 |
|
243 |
for (i = 0; i < nr_threads; i++) { |
244 |
targs[i].tid = i+1;
|
245 |
targs[i].n = n; |
246 |
targs[i].cache = &cache; |
247 |
} |
248 |
for (i = 0; i < nr_threads; i++) { |
249 |
r = pthread_create(&threads[i], NULL, thread_test, &targs[i]);
|
250 |
if (r) {
|
251 |
fprintf(stderr, "error pthread_create\n");
|
252 |
return -1; |
253 |
} |
254 |
} |
255 |
|
256 |
for (i = 0; i < nr_threads; i++) { |
257 |
pthread_join(threads[i], NULL);
|
258 |
} |
259 |
|
260 |
|
261 |
|
262 |
free(targs); |
263 |
free(threads); |
264 |
xcache_close(&cache); |
265 |
|
266 |
return ((sum == (nr_threads*n)) ? 0 : -1); |
267 |
} |
268 |
|
269 |
/*
|
270 |
int test3(unsigned long n, unsigned long nr_threads)
|
271 |
{
|
272 |
int i, r;
|
273 |
struct xworkq wq;
|
274 |
xworkq_init(&wq, &lock, 0);
|
275 |
sum = 0;
|
276 |
xlock_release(&lock);
|
277 |
|
278 |
struct thread_arg *targs = malloc(sizeof(struct thread_arg)*nr_threads * n);
|
279 |
pthread_t *threads = malloc(sizeof(pthread_t) * nr_threads);
|
280 |
|
281 |
for (i = 0; i < nr_threads; i++) {
|
282 |
targs[i].num = i+1;
|
283 |
targs[i].n = n;
|
284 |
targs[i].wq = &wq;
|
285 |
}
|
286 |
for (i = 0; i < nr_threads; i++) {
|
287 |
r = pthread_create(&threads[i], NULL, thread_test, &targs[i]);
|
288 |
if (r) {
|
289 |
fprintf(stderr, "error pthread_create\n");
|
290 |
return -1;
|
291 |
}
|
292 |
}
|
293 |
|
294 |
for (i = 0; i < nr_threads; i++) {
|
295 |
pthread_join(threads[i], NULL);
|
296 |
}
|
297 |
|
298 |
|
299 |
|
300 |
free(targs);
|
301 |
free(threads);
|
302 |
xworkq_destroy(&wq);
|
303 |
|
304 |
unsigned long expected_sum = 0;
|
305 |
for (i = 0; i < nr_threads; i++) {
|
306 |
expected_sum += n*(i+1);
|
307 |
}
|
308 |
return ((sum == expected_sum) ? 0 : -1);
|
309 |
}
|
310 |
*/
|
311 |
|
312 |
int main(int argc, const char *argv[]) |
313 |
{ |
314 |
struct timeval start, end, tv;
|
315 |
int r;
|
316 |
int cache_size = atoi(argv[1]); |
317 |
int lru_type = atoi(argv[2]); |
318 |
int n = atoi(argv[3]); |
319 |
int t = atoi(argv[4]); |
320 |
|
321 |
lru = XCACHE_LRU_ARRAY; |
322 |
if (lru_type)
|
323 |
lru = XCACHE_LRU_HEAP; |
324 |
|
325 |
fprintf(stderr, "Running test1\n");
|
326 |
gettimeofday(&start, NULL);
|
327 |
r = test1(cache_size); |
328 |
if (r < 0){ |
329 |
fprintf(stderr, "Test1: FAILED\n");
|
330 |
return -1; |
331 |
} |
332 |
gettimeofday(&end, NULL);
|
333 |
timersub(&end, &start, &tv); |
334 |
fprintf(stderr, "Test1: PASSED\n");
|
335 |
fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec); |
336 |
|
337 |
fprintf(stderr, "running test2\n");
|
338 |
gettimeofday(&start, NULL);
|
339 |
r = test2(cache_size, n, t); |
340 |
gettimeofday(&end, NULL);
|
341 |
timersub(&end, &start, &tv); |
342 |
fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec); |
343 |
if (r < 0){ |
344 |
fprintf(stderr, "test2: failed\n");
|
345 |
return -1; |
346 |
} else {
|
347 |
fprintf(stderr, "test2: PASSED\n");
|
348 |
} |
349 |
|
350 |
|
351 |
fprintf(stderr, "running test3\n");
|
352 |
gettimeofday(&start, NULL);
|
353 |
r = test3(cache_size); |
354 |
if (r < 0){ |
355 |
fprintf(stderr, "test3: failed\n");
|
356 |
return -1; |
357 |
} |
358 |
gettimeofday(&end, NULL);
|
359 |
timersub(&end, &start, &tv); |
360 |
fprintf(stderr, "Test time: %ds %dusec\n\n", (int)tv.tv_sec, (int)tv.tv_usec); |
361 |
|
362 |
return 0; |
363 |
} |