Bump version to 0.3.5next
[archipelago] / xseg / xtypes / xobj_test.c
1 /*
2  * Copyright 2012 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and
30  * documentation are those of the authors and should not be
31  * interpreted as representing official policies, either expressed
32  * or implied, of GRNET S.A.
33  */
34
35 #include <stdio.h>
36 #include <xtypes/xobj.h>
37 #include <pthread.h>
38 #include <sys/time.h>
39
40 #define OBJ_H_MAGIC 0
41 #define FOO_OBJ_H_MAGIC 1
42
43 struct foo {
44         uint64_t id;
45         uint64_t bar;
46         uint64_t bar1;
47         uint64_t bar2;
48 };
49
50 void *mem;
51 unsigned long size = 1024*1024 * 100;
52 unsigned long al_unit = 12;
53 unsigned long nr_threads = 8;
54 struct xheap *heap;
55 struct xobject_h obj_h;
56
57
58 unsigned long allocations = 0;
59
60 struct thread_arg{
61         int id;
62         struct xobject_h *obj_h;
63         unsigned long c;
64         unsigned long gets;
65         unsigned long puts;
66 };
67
68 void *thread_test(void *arg)
69 {
70         struct thread_arg *targ = (struct thread_arg *) arg;
71         struct xobject_h *obj_h = targ->obj_h;
72         int id = targ->id;
73         unsigned long c = targ->c;
74
75         struct foo *foo_obj;
76         unsigned long i = 0;
77         do {
78                 foo_obj = xobj_get_obj(obj_h, X_ALLOC);
79                 if (foo_obj != NULL){
80                         i++;
81                         memset(foo_obj, 1, sizeof(struct foo));
82                         if (c) {
83                                 xobj_put_obj(obj_h, foo_obj);
84                                 c--;
85                         }
86                 }
87         }while (foo_obj != NULL);
88
89         targ->gets = i;
90         targ->puts = targ->c - c;
91         return NULL;
92 }
93
94 int test_threads()
95 {
96         int i;
97         unsigned long gets = 0;
98         unsigned long puts = 0;
99
100         int r = xheap_init(heap, size, al_unit, mem);
101         if (r < 0){
102                 printf("threads: xheap init error\n");
103                 return -1;
104         }
105         xobj_handler_init(&obj_h, mem, FOO_OBJ_H_MAGIC, sizeof(struct foo), heap);
106
107         struct thread_arg *targs = malloc(sizeof(struct thread_arg) * nr_threads);
108         if (!targs) {
109                 printf("error malloc\n");
110                 return -1;
111         }
112
113         pthread_t *threads = malloc(sizeof(pthread_t) * nr_threads);
114         if (!threads){
115                 printf("error malloc\n");
116                 return -1;
117         }
118
119         for (i = 0; i < nr_threads; i++) {
120                 targs[i].id = i;
121                 targs[i].obj_h = &obj_h;
122                 targs[i].c = 256;
123                 targs[i].gets = 0;
124                 targs[i].puts = 0;
125         }
126
127         for (i = 0; i < nr_threads; i++) {
128                 r = pthread_create(&threads[i], NULL, thread_test, &targs[i]);
129                 if (r) {
130                         printf("error pthread_create\n");
131                         return -1;
132                 }
133         }
134
135         for (i = 0; i < nr_threads; i++) {
136                 pthread_join(threads[i], NULL);
137                 gets +=  targs[i].gets;
138                 puts += targs[i].puts;
139         }
140         if (gets - puts != allocations)
141                 return -1;
142         return 0;
143 }
144
145 int basic_test()
146 {
147         unsigned long c = 0;
148         int r;
149         struct foo *foo_obj;
150         struct timeval start, end;
151
152         r = xheap_init(heap, size, al_unit, mem);
153         if (r < 0) {
154                 printf("error heap_init\n");
155                 return -1;
156         }
157
158         xobj_handler_init(&obj_h, mem, FOO_OBJ_H_MAGIC, sizeof(struct foo), heap);
159         gettimeofday(&start, NULL);
160         foo_obj = xobj_get_obj(&obj_h, X_ALLOC);
161 //      printf("foo_obj: %lx\n", foo_obj);
162         while (foo_obj){
163                 c++;
164                 foo_obj = xobj_get_obj(&obj_h, X_ALLOC);
165 //              printf("foo_obj[%lu]: %lx\n", c, foo_obj);
166         }
167         gettimeofday(&end, NULL);
168         allocations = c;
169         timersub(&end, &start, &end);
170         unsigned long us;
171         us = end.tv_sec * 1000000 + end.tv_usec;
172         printf("Allocated %lu objects of size %d (Total size: %lu)\n",
173                         c, sizeof(struct foo), c*sizeof(struct foo));
174         printf("Total time: %lu us\n", us);
175         unsigned long tpa =  (unsigned long) ((us*1000) / allocations);
176         printf("Time per allocation: %lu ns\n", tpa);
177         unsigned long aps =  (unsigned long) ((allocations * 1000000)/us);
178         printf("Allocations per second: %lu\n\n", aps);
179         return 0;
180 }
181
182 int get_put_test()
183 {
184         unsigned long c = 0;
185         struct foo *foo_obj;
186         int r;  
187         void **buf;
188         unsigned long i;
189         buf = malloc(sizeof(void *) * allocations);
190         if (!buf) {
191                 printf("error malloc\n");
192                 return -1;
193         }
194         for (i = 0; i < allocations; i++) {
195                 buf[i] = NULL;
196         }
197
198         r = xheap_init(heap, size, al_unit, mem);
199         if (r < 0) {
200                 printf("error heap_init\n");
201                 return -1;
202         }
203
204         xobj_handler_init(&obj_h, mem, FOO_OBJ_H_MAGIC, sizeof(struct foo), heap);
205
206         foo_obj = xobj_get_obj(&obj_h, X_ALLOC);
207 //      printf("foo_obj: %lx\n", foo_obj);
208         c = 0;
209         while (foo_obj){
210                 buf[c] = foo_obj;
211                 c++;
212                 memset(foo_obj, 1, sizeof(struct foo));
213                 foo_obj = xobj_get_obj(&obj_h, X_ALLOC);
214 //              printf("foo_obj[%lu]: %lx\n", c, foo_obj);
215         }
216         if (c != allocations) {
217                 printf("allocated %lu instead of expected %lu\n", c, allocations);
218                 return -1;
219         }
220         
221         c = 0;
222         for (i = 0; i < allocations; i++) {
223                 foo_obj = buf[i];
224                 if (foo_obj == NULL)
225                         continue;
226                 c++;
227                 xobj_put_obj(&obj_h, foo_obj);
228         }
229         if (c != allocations) {
230                 printf("put %lu instead of expected %lu\n", c, allocations);
231                 return -1;
232         }
233
234         foo_obj = xobj_get_obj(&obj_h, X_ALLOC);
235 //      printf("foo_obj: %lx\n", foo_obj);
236         c = 0;
237         while (foo_obj){
238                 c++;
239                 foo_obj = xobj_get_obj(&obj_h, X_ALLOC);
240 //              printf("foo_obj[%lu]: %lx\n", c, foo_obj);
241         }
242         if (c != allocations) {
243                 printf("reallocated %lu instead of expected %lu\n", c, allocations);
244                 return -1;
245         }
246
247         return 0;
248 }
249
250
251 int main(int argc, const char *argv[])
252 {
253         int r;
254         heap = malloc(sizeof(struct xheap));
255
256         mem = malloc(size);
257         if (!mem) {
258                 printf("error malloc\n");
259                 return -1;
260         }
261
262         r = basic_test();
263         if (r < 0) 
264                 printf("Basic test failed\n");
265         else
266                 printf("Basic test completed\n");
267
268         r = get_put_test();
269         if (r < 0) 
270                 printf("Get-Put-Get test failed\n");
271         else
272                 printf("Get-Put-Get test completed\n");
273
274         r = test_threads();
275         if (r < 0) 
276                 printf("Threaded test failed\n");
277         else
278                 printf("Threaded test completed\n");
279
280         return 0;
281 }