Remove unistd.h
[helenos.git] / uspace / app / tester / mm / malloc3.c
blob6f5fac9420d05f0be3ddd829e99e473016e1f872
1 /*
2 * Copyright (c) 2009 Martin Decky
3 * Copyright (c) 2009 Tomas Bures
4 * Copyright (c) 2009 Lubomir Bulej
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <stddef.h>
34 #include <libarch/config.h>
35 #include "common.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[] = {
46 .name = "Allocation",
47 .cond = {
48 .max_cycles = 200,
49 .no_memory = 1,
50 .no_allocated = 0,
52 .prob = {
53 .alloc = 90,
54 .free = 100
58 .name = "Alloc/Dealloc",
59 .cond = {
60 .max_cycles = 200,
61 .no_memory = 0,
62 .no_allocated = 0,
64 .prob = {
65 .alloc = 50,
66 .free = 100
70 .name = "Deallocation",
71 .cond = {
72 .max_cycles = 0,
73 .no_memory = 0,
74 .no_allocated = 1,
76 .prob = {
77 .alloc = 10,
78 .free = 100
83 static subphase_t subphases_128K[] = {
85 .name = "Allocation",
86 .cond = {
87 .max_cycles = 0,
88 .no_memory = 1,
89 .no_allocated = 0,
91 .prob = {
92 .alloc = 70,
93 .free = 100
97 .name = "Alloc/Dealloc",
98 .cond = {
99 .max_cycles = 30,
100 .no_memory = 0,
101 .no_allocated = 0,
103 .prob = {
104 .alloc = 50,
105 .free = 100
109 .name = "Deallocation",
110 .cond = {
111 .max_cycles = 0,
112 .no_memory = 0,
113 .no_allocated = 1,
115 .prob = {
116 .alloc = 30,
117 .free = 100
122 static subphase_t subphases_default[] = {
124 .name = "Allocation",
125 .cond = {
126 .max_cycles = 0,
127 .no_memory = 1,
128 .no_allocated = 0,
130 .prob = {
131 .alloc = 90,
132 .free = 100
136 .name = "Alloc/Dealloc",
137 .cond = {
138 .max_cycles = 200,
139 .no_memory = 0,
140 .no_allocated = 0,
142 .prob = {
143 .alloc = 50,
144 .free = 100
148 .name = "Deallocation",
149 .cond = {
150 .max_cycles = 0,
151 .no_memory = 0,
152 .no_allocated = 1,
154 .prob = {
155 .alloc = 10,
156 .free = 100
162 * Phase definitions.
164 static phase_t phases[] = {
166 .name = "32 B memory blocks",
167 .alloc = {
168 .min_block_size = 32,
169 .max_block_size = 32
171 .subphases = subphases_32B
174 .name = "128 KB memory blocks",
175 .alloc = {
176 .min_block_size = 128 * 1024,
177 .max_block_size = 128 * 1024
179 .subphases = subphases_128K
182 .name = "2500 B memory blocks",
183 .alloc = {
184 .min_block_size = 2500,
185 .max_block_size = 2500
187 .subphases = subphases_default
190 .name = "1 B .. 250000 B memory blocks",
191 .alloc = {
192 .min_block_size = 1,
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.
209 break;
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);
225 RETURN_IF_ERROR;
227 if (blk == NULL) {
228 TPRINTF("F(A)");
229 if (subphase->cond.no_memory) {
230 /* We filled the memory. Proceed to next subphase */
231 break;
233 } else {
234 TPRINTF("A");
235 fill_block(blk);
236 RETURN_IF_ERROR;
238 if ((mem_blocks_count % AREA_GRANULARITY) == 0) {
239 mem_area_t *area = map_area(AREA_SIZE);
240 RETURN_IF_ERROR;
242 if (area != NULL) {
243 TPRINTF("*");
244 fill_area(area);
245 RETURN_IF_ERROR;
246 } else
247 TPRINTF("F(*)");
251 } else if (rnd < subphase->prob.free) {
252 mem_block_t *blk = get_random_block();
253 if (blk == NULL) {
254 TPRINTF("F(R)");
255 if (subphase->cond.no_allocated) {
256 /* We free all the memory. Proceed to next subphase. */
257 break;
259 } else {
260 TPRINTF("R");
261 check_block(blk);
262 RETURN_IF_ERROR;
264 free_block(blk);
265 RETURN_IF_ERROR;
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);
280 RETURN_IF_ERROR;
284 const char *test_malloc3(void)
286 init_mem();
288 for (unsigned int phaseno = 0; phaseno < sizeof_array(phases);
289 phaseno++) {
290 phase_t *phase = &phases[phaseno];
292 TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name);
294 do_phase(phase);
295 if (error_flag)
296 break;
298 TPRINTF("Phase finished.\n");
301 TPRINTF("Cleaning up.\n");
302 done_mem();
303 if (error_flag)
304 return "Test failed";
306 return NULL;