Remove unistd.h
[helenos.git] / uspace / app / tester / mm / malloc1.c
blob9b311b245d32e5e9fb987f4a7805d6334f816cef
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 "common.h"
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[] = {
54 .name = "Allocation",
55 .cond = {
56 .max_cycles = 200,
57 .no_memory = 1,
58 .no_allocated = 0,
60 .prob = {
61 .alloc = 90,
62 .free = 100
66 .name = "Alloc/Dealloc",
67 .cond = {
68 .max_cycles = 200,
69 .no_memory = 0,
70 .no_allocated = 0,
72 .prob = {
73 .alloc = 50,
74 .free = 100
78 .name = "Deallocation",
79 .cond = {
80 .max_cycles = 0,
81 .no_memory = 0,
82 .no_allocated = 1,
84 .prob = {
85 .alloc = 10,
86 .free = 100
91 static subphase_t subphases_128K[] = {
93 .name = "Allocation",
94 .cond = {
95 .max_cycles = 0,
96 .no_memory = 1,
97 .no_allocated = 0,
99 .prob = {
100 .alloc = 70,
101 .free = 100
105 .name = "Alloc/Dealloc",
106 .cond = {
107 .max_cycles = 30,
108 .no_memory = 0,
109 .no_allocated = 0,
111 .prob = {
112 .alloc = 50,
113 .free = 100
117 .name = "Deallocation",
118 .cond = {
119 .max_cycles = 0,
120 .no_memory = 0,
121 .no_allocated = 1,
123 .prob = {
124 .alloc = 30,
125 .free = 100
130 static subphase_t subphases_default[] = {
132 .name = "Allocation",
133 .cond = {
134 .max_cycles = 0,
135 .no_memory = 1,
136 .no_allocated = 0,
138 .prob = {
139 .alloc = 90,
140 .free = 100
144 .name = "Alloc/Dealloc",
145 .cond = {
146 .max_cycles = 200,
147 .no_memory = 0,
148 .no_allocated = 0,
150 .prob = {
151 .alloc = 50,
152 .free = 100
156 .name = "Deallocation",
157 .cond = {
158 .max_cycles = 0,
159 .no_memory = 0,
160 .no_allocated = 1,
162 .prob = {
163 .alloc = 10,
164 .free = 100
170 * Phase definitions.
172 static phase_t phases[] = {
174 .name = "32 B memory blocks",
175 .alloc = {
176 .min_block_size = 32,
177 .max_block_size = 32
179 .subphases = subphases_32B
182 .name = "128 KB memory blocks",
183 .alloc = {
184 .min_block_size = 128 * 1024,
185 .max_block_size = 128 * 1024
187 .subphases = subphases_128K
190 .name = "2500 B memory blocks",
191 .alloc = {
192 .min_block_size = 2500,
193 .max_block_size = 2500
195 .subphases = subphases_default
198 .name = "1 B .. 250000 B memory blocks",
199 .alloc = {
200 .min_block_size = 1,
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.
217 break;
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);
233 RETURN_IF_ERROR;
235 if (blk == NULL) {
236 TPRINTF("F(A)");
237 if (subphase->cond.no_memory) {
238 /* We filled the memory. Proceed to next subphase */
239 break;
241 } else {
242 TPRINTF("A");
243 fill_block(blk);
244 RETURN_IF_ERROR;
247 } else if (rnd < subphase->prob.free) {
248 mem_block_t *blk = get_random_block();
249 if (blk == NULL) {
250 TPRINTF("F(R)");
251 if (subphase->cond.no_allocated) {
252 /* We free all the memory. Proceed to next subphase. */
253 break;
255 } else {
256 TPRINTF("R");
257 check_block(blk);
258 RETURN_IF_ERROR;
260 free_block(blk);
261 RETURN_IF_ERROR;
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);
276 RETURN_IF_ERROR;
280 const char *test_malloc1(void)
282 init_mem();
284 for (unsigned int phaseno = 0; phaseno < sizeof_array(phases);
285 phaseno++) {
286 phase_t *phase = &phases[phaseno];
288 TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name);
290 do_phase(phase);
291 if (error_flag)
292 break;
294 TPRINTF("Phase finished.\n");
297 TPRINTF("Cleaning up.\n");
298 done_mem();
299 if (error_flag)
300 return "Test failed";
302 return NULL;