source: mainline/uspace/app/tester/mm/malloc1.c@ ba8eecf

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ba8eecf was faeb7cc, checked in by Martin Decky <martin@…>, 14 years ago

add additional RETURN_IF_ERRORs

  • Property mode set to 100644
File size: 6.5 KB
Line 
1/*
2 * Copyright (c) 2009 Martin Decky
3 * Copyright (c) 2009 Tomas Bures
4 * Copyright (c) 2009 Lubomir Bulej
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
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.
18 *
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.
29 */
30
31#include <stdio.h>
32#include <stdlib.h>
33#include "common.h"
34#include "../tester.h"
35
36/*
37 * The test consists of several phases which differ in the size of blocks
38 * they allocate. The size of blocks is given as a range of minimum and
39 * maximum allowed size. Each of the phases is divided into 3 subphases which
40 * differ in the probability of free and alloc actions. Second subphase is
41 * started when malloc returns 'out of memory' or when MAX_ALLOC is reached.
42 * Third subphase is started after a given number of cycles. The third subphase
43 * as well as the whole phase ends when all memory blocks are released.
44 */
45
46/*
47 * Subphases are defined separately here. This is for two reasons:
48 * 1) data are not duplicated, 2) we don't have to state beforehand
49 * how many subphases a phase contains.
50 */
51static subphase_t subphases_32B[] = {
52 {
53 .name = "Allocation",
54 .cond = {
55 .max_cycles = 200,
56 .no_memory = 1,
57 .no_allocated = 0,
58 },
59 .prob = {
60 .alloc = 90,
61 .free = 100
62 }
63 },
64 {
65 .name = "Alloc/Dealloc",
66 .cond = {
67 .max_cycles = 200,
68 .no_memory = 0,
69 .no_allocated = 0,
70 },
71 .prob = {
72 .alloc = 50,
73 .free = 100
74 }
75 },
76 {
77 .name = "Deallocation",
78 .cond = {
79 .max_cycles = 0,
80 .no_memory = 0,
81 .no_allocated = 1,
82 },
83 .prob = {
84 .alloc = 10,
85 .free = 100
86 }
87 }
88};
89
90static subphase_t subphases_128K[] = {
91 {
92 .name = "Allocation",
93 .cond = {
94 .max_cycles = 0,
95 .no_memory = 1,
96 .no_allocated = 0,
97 },
98 .prob = {
99 .alloc = 70,
100 .free = 100
101 }
102 },
103 {
104 .name = "Alloc/Dealloc",
105 .cond = {
106 .max_cycles = 30,
107 .no_memory = 0,
108 .no_allocated = 0,
109 },
110 .prob = {
111 .alloc = 50,
112 .free = 100
113 }
114 },
115 {
116 .name = "Deallocation",
117 .cond = {
118 .max_cycles = 0,
119 .no_memory = 0,
120 .no_allocated = 1,
121 },
122 .prob = {
123 .alloc = 30,
124 .free = 100
125 }
126 }
127};
128
129static subphase_t subphases_default[] = {
130 {
131 .name = "Allocation",
132 .cond = {
133 .max_cycles = 0,
134 .no_memory = 1,
135 .no_allocated = 0,
136 },
137 .prob = {
138 .alloc = 90,
139 .free = 100
140 }
141 },
142 {
143 .name = "Alloc/Dealloc",
144 .cond = {
145 .max_cycles = 200,
146 .no_memory = 0,
147 .no_allocated = 0,
148 },
149 .prob = {
150 .alloc = 50,
151 .free = 100
152 }
153 },
154 {
155 .name = "Deallocation",
156 .cond = {
157 .max_cycles = 0,
158 .no_memory = 0,
159 .no_allocated = 1,
160 },
161 .prob = {
162 .alloc = 10,
163 .free = 100
164 }
165 }
166};
167
168/*
169 * Phase definitions.
170 */
171static phase_t phases[] = {
172 {
173 .name = "32 B memory blocks",
174 .alloc = {
175 .min_block_size = 32,
176 .max_block_size = 32
177 },
178 .subphases = subphases_32B
179 },
180 {
181 .name = "128 KB memory blocks",
182 .alloc = {
183 .min_block_size = 128 * 1024,
184 .max_block_size = 128 * 1024
185 },
186 .subphases = subphases_128K
187 },
188 {
189 .name = "2500 B memory blocks",
190 .alloc = {
191 .min_block_size = 2500,
192 .max_block_size = 2500
193 },
194 .subphases = subphases_default
195 },
196 {
197 .name = "1 B .. 250000 B memory blocks",
198 .alloc = {
199 .min_block_size = 1,
200 .max_block_size = 250000
201 },
202 .subphases = subphases_default
203 }
204};
205
206static void do_subphase(phase_t *phase, subphase_t *subphase)
207{
208 for (unsigned int cycles = 0; /* always */; cycles++) {
209
210 if ((subphase->cond.max_cycles) &&
211 (cycles >= subphase->cond.max_cycles)) {
212 /*
213 * We have performed the required number of
214 * cycles. End the current subphase.
215 */
216 break;
217 }
218
219 /*
220 * Decide whether we alloc or free memory in this step.
221 */
222 unsigned int rnd = rand() % 100;
223 if (rnd < subphase->prob.alloc) {
224 /*
225 * Compute a random number lying in interval
226 * <min_block_size, max_block_size>
227 */
228 int alloc = phase->alloc.min_block_size +
229 (rand() % (phase->alloc.max_block_size - phase->alloc.min_block_size + 1));
230
231 mem_block_t *blk = alloc_block(alloc);
232 RETURN_IF_ERROR;
233
234 if (blk == NULL) {
235 TPRINTF("F(A)");
236 if (subphase->cond.no_memory) {
237 /* We filled the memory. Proceed to next subphase */
238 break;
239 }
240 } else {
241 TPRINTF("A");
242 fill_block(blk);
243 RETURN_IF_ERROR;
244 }
245
246 } else if (rnd < subphase->prob.free) {
247 mem_block_t *blk = get_random_block();
248 if (blk == NULL) {
249 TPRINTF("F(R)");
250 if (subphase->cond.no_allocated) {
251 /* We free all the memory. Proceed to next subphase. */
252 break;
253 }
254 } else {
255 TPRINTF("R");
256 check_block(blk);
257 RETURN_IF_ERROR;
258
259 free_block(blk);
260 RETURN_IF_ERROR;
261 }
262 }
263 }
264
265 TPRINTF("\n.. finished.\n");
266}
267
268static void do_phase(phase_t *phase)
269{
270 for (unsigned int subno = 0; subno < 3; subno++) {
271 subphase_t *subphase = &phase->subphases[subno];
272
273 TPRINTF(".. Sub-phase %u (%s)\n", subno + 1, subphase->name);
274 do_subphase(phase, subphase);
275 RETURN_IF_ERROR;
276 }
277}
278
279const char *test_malloc1(void)
280{
281 init_mem();
282
283 for (unsigned int phaseno = 0; phaseno < sizeof_array(phases);
284 phaseno++) {
285 phase_t *phase = &phases[phaseno];
286
287 TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name);
288
289 do_phase(phase);
290 if (error_flag)
291 break;
292
293 TPRINTF("Phase finished.\n");
294 }
295
296 TPRINTF("Cleaning up.\n");
297 done_mem();
298 if (error_flag)
299 return "Test failed";
300
301 return NULL;
302}
Note: See TracBrowser for help on using the repository browser.