1 /* ``Licensed under the Apache License, Version 2.0 (the "License");
2 * you may not use this file except in compliance with the License.
3 * You may obtain a copy of the License at
4 *
5 * http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software
8 * distributed under the License is distributed on an "AS IS" BASIS,
9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the License for the specific language governing permissions and
11 * limitations under the License.
12 *
13 * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
14 * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
15 * AB. All Rights Reserved.''
16 *
17 * $Id$
18 */
19
20 #include "erl_int_sizes_config.h"
21
22 #include "testcase_driver.h"
23 #include "allocator_test.h"
24 #include <stdio.h>
25
26 #if defined(__WIN32__) && SIZEOF_VOID_P == 8
27 /* Use larger threashold for win64 as block alignment
28 is 16 bytes and not 8 */
29 #define SBCT ((1024*1024))
30 #else
31 #define SBCT ((512*1024))
32 #endif
33
34 char *
testcase_name(void)35 testcase_name(void)
36 {
37 return "bucket_mask";
38 }
39
40 void
testcase_cleanup(TestCaseState_t * tcs)41 testcase_cleanup(TestCaseState_t *tcs)
42 {
43 if (tcs->extra) {
44 STOP_ALC(tcs->extra);
45 tcs->extra = NULL;
46 }
47 }
48
49 void
testcase_run(TestCaseState_t * tcs)50 testcase_run(TestCaseState_t *tcs)
51 {
52 typedef struct linked_block {
53 struct linked_block* next;
54 }Linked;
55 Linked* link = NULL;
56 Linked* fence_list;
57 Linked* pad_list;
58 void* tmp;
59 void **blk;
60 Ulong sz;
61 Ulong residue;
62 Ulong smbcs;
63 int i;
64 int bi;
65 int bi_tests;
66 Ulong sbct = (SBCT/1024)*1024;
67 Ulong min_blk_sz;
68 Ulong ablk_hdr_sz = ABLK_HDR_SZ;
69 char smbcs_buf[30];
70 char sbct_buf[30];
71 int no_bkts = (int) NO_OF_BKTS;
72 char *argv1[] = {"-tasgf", "-tmmbcs0", sbct_buf, NULL};
73 char *argv2[] = {"-tasgf", "-tmmbcs0", sbct_buf, NULL, NULL};
74 Allctr_t *a;
75
76 sprintf(sbct_buf, "-tsbct%lu", sbct/1024);
77
78 a = START_ALC("bkt_mask_1_", 0, argv1);
79 tcs->extra = (void *) a;
80 ASSERT(tcs, a);
81
82 min_blk_sz = MIN_BLK_SZ(a);
83 smbcs = (no_bkts*sizeof(void *) + min_blk_sz) + min_blk_sz;
84 for (i = 0; i < no_bkts; i++) {
85 sz = BKT_MIN_SZ(a, i);
86 if (sz >= sbct)
87 break;
88 smbcs += sz + min_blk_sz;
89 }
90
91 bi_tests = i;
92 testcase_printf(tcs, "Will test %d buckets\n", bi_tests);
93
94 STOP_ALC(a);
95 tcs->extra = NULL;
96
97 smbcs /= 1024;
98 smbcs++;
99
100 testcase_printf(tcs, "smbcs = %lu\n", smbcs);
101 sprintf(smbcs_buf, "-tsmbcs%lu", smbcs);
102 argv2[3] = smbcs_buf;
103
104 a = START_ALC("bkt_mask_2_", 0, argv2);
105 tcs->extra = (void *) a;
106 ASSERT(tcs, a);
107
108
109 blk = (void **) ALLOC(a, no_bkts*sizeof(void *));
110
111 ASSERT(tcs, blk);
112 fence_list = NULL;
113
114 testcase_printf(tcs, "Allocating blocks and fences\n");
115 for (i = 0; i < bi_tests; i++) {
116 sz = BKT_MIN_SZ(a, i);
117 blk[i] = ALLOC(a, sz - ablk_hdr_sz);
118 link = (Linked*) ALLOC(a, sizeof(Linked));
119 ASSERT(tcs, blk[i] && link);
120 link->next = fence_list;
121 fence_list = link;
122 }
123
124 pad_list = 0;
125 do {
126 tmp = (void *) UMEM2BLK(link); /* last allocated */
127 tmp = (void *) NXT_BLK((Block_t *) tmp);
128 ASSERT(tcs, IS_LAST_BLK(tmp));
129 sz = BLK_SZ((Block_t *) tmp);
130 if (sz >= sbct) {
131 residue = sz;
132 sz = sbct - min_blk_sz;
133 residue -= sz;
134 }
135 else {
136 residue = 0;
137 }
138 testcase_printf(tcs, "Allocating leftover size = %lu, residue = %lu\n", sz, residue);
139 link = (Linked*) ALLOC(a, sz - ablk_hdr_sz);
140 ASSERT(tcs, link);
141 link->next = pad_list;
142 pad_list = link;
143 } while (residue);
144
145 bi = FIND_BKT(a, 0);
146 ASSERT(tcs, bi < 0);
147
148 for (i = 0; i < bi_tests; i++) {
149 sz = BKT_MIN_SZ(a, i);
150 testcase_printf(tcs, "Testing bucket %d\n", i);
151 FREE(a, blk[i]);
152 bi = FIND_BKT(a, i);
153 ASSERT(tcs, bi == i);
154 blk[i] = ALLOC(a, sz - ablk_hdr_sz);
155 bi = FIND_BKT(a, i);
156 ASSERT(tcs, bi != i);
157 }
158
159 for (i = 0; i < bi_tests; i++) {
160 FREE(a, blk[i]);
161 }
162 while (fence_list) {
163 link = fence_list;
164 fence_list = link->next;
165 FREE(a, link);
166 }
167
168 FREE(a, (void *) blk);
169
170 bi = FIND_BKT(a, 0);
171 ASSERT(tcs, bi == no_bkts - 1);
172
173 while (pad_list) {
174 link = pad_list;
175 pad_list = link->next;
176 FREE(a, link);
177 }
178
179 bi = FIND_BKT(a, 0);
180 ASSERT(tcs, bi < 0);
181
182 STOP_ALC(a);
183 tcs->extra = NULL;
184 }
185
186 ERL_NIF_INIT(bucket_mask, testcase_nif_funcs, testcase_nif_init,
187 NULL, NULL, NULL);
188