2 * Copyright (c) 2009 Martin Decky
3 * Copyright (c) 2009 Tomas Bures
4 * Copyright (c) 2009 Lubomir Bulej
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * - The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <libarch/config.h>
36 #include "../tester.h"
39 * The test is a slight adaptation of malloc1 test. The major difference
40 * is that the test forces the heap allocator to create multiple
41 * heap areas by creating disturbing address space areas.
44 static subphase_t subphases_32B
[] = {
58 .name
= "Alloc/Dealloc",
70 .name
= "Deallocation",
83 static subphase_t subphases_128K
[] = {
97 .name
= "Alloc/Dealloc",
109 .name
= "Deallocation",
122 static subphase_t subphases_default
[] = {
124 .name
= "Allocation",
136 .name
= "Alloc/Dealloc",
148 .name
= "Deallocation",
164 static phase_t phases
[] = {
166 .name
= "32 B memory blocks",
168 .min_block_size
= 32,
171 .subphases
= subphases_32B
174 .name
= "128 KB memory blocks",
176 .min_block_size
= 128 * 1024,
177 .max_block_size
= 128 * 1024
179 .subphases
= subphases_128K
182 .name
= "2500 B memory blocks",
184 .min_block_size
= 2500,
185 .max_block_size
= 2500
187 .subphases
= subphases_default
190 .name
= "1 B .. 250000 B memory blocks",
193 .max_block_size
= 250000
195 .subphases
= subphases_default
199 static void do_subphase(phase_t
*phase
, subphase_t
*subphase
)
201 for (unsigned int cycles
= 0; /* always */; cycles
++) {
203 if ((subphase
->cond
.max_cycles
) &&
204 (cycles
>= subphase
->cond
.max_cycles
)) {
206 * We have performed the required number of
207 * cycles. End the current subphase.
213 * Decide whether we alloc or free memory in this step.
215 unsigned int rnd
= rand() % 100;
216 if (rnd
< subphase
->prob
.alloc
) {
218 * Compute a random number lying in interval
219 * <min_block_size, max_block_size>
221 int alloc
= phase
->alloc
.min_block_size
+
222 (rand() % (phase
->alloc
.max_block_size
- phase
->alloc
.min_block_size
+ 1));
224 mem_block_t
*blk
= alloc_block(alloc
);
229 if (subphase
->cond
.no_memory
) {
230 /* We filled the memory. Proceed to next subphase */
238 if ((mem_blocks_count
% AREA_GRANULARITY
) == 0) {
239 mem_area_t
*area
= map_area(AREA_SIZE
);
251 } else if (rnd
< subphase
->prob
.free
) {
252 mem_block_t
*blk
= get_random_block();
255 if (subphase
->cond
.no_allocated
) {
256 /* We free all the memory. Proceed to next subphase. */
270 TPRINTF("\n.. finished.\n");
273 static void do_phase(phase_t
*phase
)
275 for (unsigned int subno
= 0; subno
< 3; subno
++) {
276 subphase_t
*subphase
= &phase
->subphases
[subno
];
278 TPRINTF(".. Sub-phase %u (%s)\n", subno
+ 1, subphase
->name
);
279 do_subphase(phase
, subphase
);
284 const char *test_malloc3(void)
288 for (unsigned int phaseno
= 0; phaseno
< sizeof_array(phases
);
290 phase_t
*phase
= &phases
[phaseno
];
292 TPRINTF("Entering phase %u (%s)\n", phaseno
+ 1, phase
->name
);
298 TPRINTF("Phase finished.\n");
301 TPRINTF("Cleaning up.\n");
304 return "Test failed";