testsuite/testblockalloc: Test aligned block group allocation
[ghc.git] / testsuite / tests / rts / testblockalloc.c
1 #include "Rts.h"
2
3 #include <stdio.h>
4
5 extern bdescr *allocGroup_lock_lock(uint32_t n);
6 extern bdescr *allocAlignedGroupOnNode (uint32_t node, W_ n);
7 extern void freeGroup_lock(bdescr *p);
8
9 const int ARRSIZE = 256;
10 const int LOOPS = 100;
11 const int MAXALLOC = ((8 * 1024 * 1024) / BLOCK_SIZE - 1);
12 //const int MAXALLOC = ((64 * 1024 * 1024) / BLOCK_SIZE - 1);
13 const int SEED = 0xf00f00;
14
15 extern StgWord mblocks_allocated;
16
17 static void test_random_alloc(void)
18 {
19 bdescr *a[ARRSIZE];
20
21 // repeatedly sweep though the array, allocating new random-sized
22 // objects and deallocating the old ones.
23 for (int i=0; i < LOOPS; i++)
24 {
25 for (int j=0; j < ARRSIZE; j++)
26 {
27 if (i > 0)
28 {
29 IF_DEBUG(block_alloc, debugBelch("A%d: freeing %p, %d blocks @ %p\n", j, a[j], a[j]->blocks, a[j]->start));
30 freeGroup_lock(a[j]);
31 DEBUG_ONLY(checkFreeListSanity());
32 }
33
34 int b = (rand() % MAXALLOC) + 1;
35 a[j] = allocGroup_lock(b);
36 IF_DEBUG(block_alloc, debugBelch("A%d: allocated %p, %d blocks @ %p\n", j, a[j], b, a[j]->start));
37 // allocating zero blocks isn't allowed
38 DEBUG_ONLY(checkFreeListSanity());
39 }
40 }
41
42 for (int j=0; j < ARRSIZE; j++)
43 {
44 freeGroup_lock(a[j]);
45 }
46 }
47
48 static void test_sequential_alloc(void)
49 {
50 bdescr *a[ARRSIZE];
51
52 // this time, sweep forwards allocating new blocks, and then
53 // backwards deallocating them.
54 for (int i=0; i < LOOPS; i++)
55 {
56 for (int j=0; j < ARRSIZE; j++)
57 {
58 int b = (rand() % MAXALLOC) + 1;
59 a[j] = allocGroup_lock(b);
60 IF_DEBUG(block_alloc, debugBelch("B%d,%d: allocated %p, %d blocks @ %p\n", i, j, a[j], b, a[j]->start));
61 DEBUG_ONLY(checkFreeListSanity());
62 }
63 for (int j=ARRSIZE-1; j >= 0; j--)
64 {
65 IF_DEBUG(block_alloc, debugBelch("B%d,%d: freeing %p, %d blocks @ %p\n", i, j, a[j], a[j]->blocks, a[j]->start));
66 freeGroup_lock(a[j]);
67 DEBUG_ONLY(checkFreeListSanity());
68 }
69 }
70 }
71
72 static void test_aligned_alloc(void)
73 {
74 bdescr *a[ARRSIZE];
75
76 // this time, sweep forwards allocating new blocks, and then
77 // backwards deallocating them.
78 for (int i=0; i < LOOPS; i++)
79 {
80 for (int j=0; j < ARRSIZE; j++)
81 {
82 int b = (rand() % MAXALLOC) + 1;
83 a[j] = allocAlignedGroupOnNode(0, b);
84 if ((uintptr_t) a[j]->start % b != 0)
85 {
86 barf("%p is not aligned to allocation size %d", a[j], b);
87 }
88 IF_DEBUG(block_alloc, debugBelch("B%d,%d: allocated %p, %d blocks @ %p\n", i, j, a[j], b, a[j]->start));
89 DEBUG_ONLY(checkFreeListSanity());
90 }
91 for (int j=ARRSIZE-1; j >= 0; j--)
92 {
93 IF_DEBUG(block_alloc, debugBelch("B%d,%d: freeing %p, %d blocks @ %p\n", i, j, a[j], a[j]->blocks, a[j]->start));
94 freeGroup_lock(a[j]);
95 DEBUG_ONLY(checkFreeListSanity());
96 }
97 }
98 }
99
100 int main (int argc, char *argv[])
101 {
102 int i, j, b;
103
104 bdescr *a[ARRSIZE];
105
106 srand(SEED);
107
108 {
109 RtsConfig conf = defaultRtsConfig;
110 conf.rts_opts_enabled = RtsOptsAll;
111 hs_init_ghc(&argc, &argv, conf);
112 }
113
114 test_random_alloc();
115 test_sequential_alloc();
116 test_aligned_alloc();
117
118 DEBUG_ONLY(checkFreeListSanity());
119
120 hs_exit(); // will do a memory leak test
121
122 exit(0);
123 }