2 * Copyright 2012 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
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.
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.
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.
41 uint32_t al_unit = 12;
42 unsigned long size = 1048576;
43 unsigned long chunk = 4096;
44 unsigned long nr_threads = 4;
45 unsigned long nr_frees;
48 #define full_size(_x_) ((_x_) + sizeof(struct xheap_header))
49 void print_ptr(void *ptr)
51 uint64_t size = xheap_get_chunk_size(ptr);
52 printf("ptr: %lx, bytes: %llu (actual: %llu)\n",
54 (unsigned long long) size,
55 (unsigned long long) full_size(size));
58 unsigned long test(struct xheap *heap)
60 int r = xheap_init(heap, size, al_unit, mem);
62 printf("xheap init error\n");
66 uint64_t alloc_size = 0, start = heap->cur;
67 printf("heap starts with %llu\n", start);
70 ptr = xheap_allocate(heap, chunk);
73 if ((unsigned long) ptr & ((1 << al_unit) -1)) {
74 printf("ptr %x not aligned with al_unit %lu\n",
78 alloc_size += xheap_get_chunk_size(ptr);
81 printf("Allocated %lu chunks of size %lu with allocation unit %lu (%lu bytes)\n",
82 i, chunk, al_unit, (1<<al_unit));
83 printf("Total allocated space: %llu\n", (unsigned long long) alloc_size);
84 alloc_size += i*sizeof(struct xheap_header);
85 printf("Total allocated space plus headers: %llu\n",
86 (unsigned long long) alloc_size);
87 alloc_size += start + 2 * sizeof(struct xheap_header);
88 printf("Total allocated space plus headers and start/end padding: %llu\n",
89 (unsigned long long) alloc_size);
90 printf("Lost space: %llu\n", (unsigned long long) (heap->size - alloc_size));
94 int test_align(struct xheap *heap)
96 uint64_t bytes = heap->size;
97 int m = sizeof(bytes)*8 - __builtin_clzl(bytes -1);
100 for (i = 5; i < m; i++){
101 int r = xheap_init(heap, size, i, mem);
103 printf("align: xheap init error\n");
107 ptr = xheap_allocate(heap, chunk);
109 if ((unsigned long) ptr & ((1 << i) -1)) {
110 printf("ptr %x not aligned with al_unit %lu\n",
115 }while (ptr != NULL);
120 int test_reuse(struct xheap *heap)
122 int r = xheap_init(heap, size, al_unit, mem);
124 printf("xheap init error\n");
128 ptr1 = xheap_allocate(heap, chunk);
130 printf("couldn't allocate\n");
134 ptr2 = xheap_allocate(heap, chunk);
136 printf("couldn't allocate\n");
140 printf("alloc-free-alloc return diffrent ptr\n");
150 unsigned long allocations;
154 void *thread_test(void *arg)
156 struct thread_arg *targ = (struct thread_arg *) arg;
157 struct xheap *heap = targ->heap;
159 unsigned long c = targ->c;
163 ptr = xheap_allocate(heap, chunk);
166 memset(ptr, 1, xheap_get_chunk_size(ptr));
172 }while (ptr != NULL);
174 targ->allocations = i;
175 targ->frees = targ->c - c;
179 unsigned long test_threads(struct xheap *heap)
182 unsigned long allocations = 0;
185 int r = xheap_init(heap, size, al_unit, mem);
187 printf("threads: xheap init error\n");
191 struct thread_arg *targs = malloc(sizeof(struct thread_arg) * nr_threads);
193 printf("error malloc\n");
197 pthread_t *threads = malloc(sizeof(pthread_t) * nr_threads);
199 printf("error malloc\n");
203 for (i = 0; i < nr_threads; i++) {
205 targs[i].heap = heap;
209 for (i = 0; i < nr_threads; i++) {
210 r = pthread_create(&threads[i], NULL, thread_test, &targs[i]);
212 printf("error pthread_create\n");
217 for (i = 0; i < nr_threads; i++) {
218 pthread_join(threads[i], NULL);
219 allocations += targs[i].allocations;
220 nr_frees += targs[i].frees;
225 int main(int argc, const char *argv[])
227 unsigned long alloc, expected, i =0;
230 printf("Usage: %s al_unit size chunk_size nr_threads\n", argv[0]);
233 al_unit = atol(argv[1]);
234 size = atol(argv[2]);
235 chunk = atol(argv[3]);
236 nr_threads = atol(argv[4]);
241 printf("Testing align: ");
242 r = test_align(&heap);
248 printf("Testing reuse: ");
249 r= test_reuse(&heap);
254 expected = alloc + nr_frees;
256 while(r == expected && i < 100) {
257 r = test_threads(&heap);
258 expected = alloc + nr_frees;
260 printf("test_threads failed r: %lu vs expected %lu\n", r, expected);