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.
35 #include "../tester.h"
38 * The test consists of several phases which differ in the size of blocks
39 * they allocate. The size of blocks is given as a range of minimum and
40 * maximum allowed size. Each of the phases is divided into 3 subphases which
41 * differ in the probability of free and alloc actions. Second subphase is
42 * started when malloc returns 'out of memory' or when MAX_ALLOC is reached.
43 * Third subphase is started after a given number of cycles. The third subphase
44 * as well as the whole phase ends when all memory blocks are released.
48 * Subphases are defined separately here. This is for two reasons:
49 * 1) data are not duplicated, 2) we don't have to state beforehand
50 * how many subphases a phase contains.
52 static subphase_t subphases_32B
[] = {
66 .name
= "Alloc/Dealloc",
78 .name
= "Deallocation",
91 static subphase_t subphases_128K
[] = {
105 .name
= "Alloc/Dealloc",
117 .name
= "Deallocation",
130 static subphase_t subphases_default
[] = {
132 .name
= "Allocation",
144 .name
= "Alloc/Dealloc",
156 .name
= "Deallocation",
172 static phase_t phases
[] = {
174 .name
= "32 B memory blocks",
176 .min_block_size
= 32,
179 .subphases
= subphases_32B
182 .name
= "128 KB memory blocks",
184 .min_block_size
= 128 * 1024,
185 .max_block_size
= 128 * 1024
187 .subphases
= subphases_128K
190 .name
= "2500 B memory blocks",
192 .min_block_size
= 2500,
193 .max_block_size
= 2500
195 .subphases
= subphases_default
198 .name
= "1 B .. 250000 B memory blocks",
201 .max_block_size
= 250000
203 .subphases
= subphases_default
207 static void do_subphase(phase_t
*phase
, subphase_t
*subphase
)
209 for (unsigned int cycles
= 0; /* always */; cycles
++) {
211 if ((subphase
->cond
.max_cycles
) &&
212 (cycles
>= subphase
->cond
.max_cycles
)) {
214 * We have performed the required number of
215 * cycles. End the current subphase.
221 * Decide whether we alloc or free memory in this step.
223 unsigned int rnd
= rand() % 100;
224 if (rnd
< subphase
->prob
.alloc
) {
226 * Compute a random number lying in interval
227 * <min_block_size, max_block_size>
229 int alloc
= phase
->alloc
.min_block_size
+
230 (rand() % (phase
->alloc
.max_block_size
- phase
->alloc
.min_block_size
+ 1));
232 mem_block_t
*blk
= alloc_block(alloc
);
237 if (subphase
->cond
.no_memory
) {
238 /* We filled the memory. Proceed to next subphase */
247 } else if (rnd
< subphase
->prob
.free
) {
248 mem_block_t
*blk
= get_random_block();
251 if (subphase
->cond
.no_allocated
) {
252 /* We free all the memory. Proceed to next subphase. */
266 TPRINTF("\n.. finished.\n");
269 static void do_phase(phase_t
*phase
)
271 for (unsigned int subno
= 0; subno
< 3; subno
++) {
272 subphase_t
*subphase
= &phase
->subphases
[subno
];
274 TPRINTF(".. Sub-phase %u (%s)\n", subno
+ 1, subphase
->name
);
275 do_subphase(phase
, subphase
);
280 const char *test_malloc1(void)
284 for (unsigned int phaseno
= 0; phaseno
< sizeof_array(phases
);
286 phase_t
*phase
= &phases
[phaseno
];
288 TPRINTF("Entering phase %u (%s)\n", phaseno
+ 1, phase
->name
);
294 TPRINTF("Phase finished.\n");
297 TPRINTF("Cleaning up.\n");
300 return "Test failed";