source: mainline/uspace/app/tester/mm/malloc3.c@ 38c773e7

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

make really sure the test does not trip over and fell on its own running chain saw

  • Property mode set to 100644
File size: 6.2 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 is a slight adaptation of malloc1 test. The major difference
38 * is that the test forces the heap allocator to create multiple
39 * heap areas by creating disturbing address space areas.
40 */
41
42static subphase_t subphases_32B[] = {
43 {
44 .name = "Allocation",
45 .cond = {
46 .max_cycles = 200,
47 .no_memory = 1,
48 .no_allocated = 0,
49 },
50 .prob = {
51 .alloc = 90,
52 .free = 100
53 }
54 },
55 {
56 .name = "Alloc/Dealloc",
57 .cond = {
58 .max_cycles = 200,
59 .no_memory = 0,
60 .no_allocated = 0,
61 },
62 .prob = {
63 .alloc = 50,
64 .free = 100
65 }
66 },
67 {
68 .name = "Deallocation",
69 .cond = {
70 .max_cycles = 0,
71 .no_memory = 0,
72 .no_allocated = 1,
73 },
74 .prob = {
75 .alloc = 10,
76 .free = 100
77 }
78 }
79};
80
81static subphase_t subphases_128K[] = {
82 {
83 .name = "Allocation",
84 .cond = {
85 .max_cycles = 0,
86 .no_memory = 1,
87 .no_allocated = 0,
88 },
89 .prob = {
90 .alloc = 70,
91 .free = 100
92 }
93 },
94 {
95 .name = "Alloc/Dealloc",
96 .cond = {
97 .max_cycles = 30,
98 .no_memory = 0,
99 .no_allocated = 0,
100 },
101 .prob = {
102 .alloc = 50,
103 .free = 100
104 }
105 },
106 {
107 .name = "Deallocation",
108 .cond = {
109 .max_cycles = 0,
110 .no_memory = 0,
111 .no_allocated = 1,
112 },
113 .prob = {
114 .alloc = 30,
115 .free = 100
116 }
117 }
118};
119
120static subphase_t subphases_default[] = {
121 {
122 .name = "Allocation",
123 .cond = {
124 .max_cycles = 0,
125 .no_memory = 1,
126 .no_allocated = 0,
127 },
128 .prob = {
129 .alloc = 90,
130 .free = 100
131 }
132 },
133 {
134 .name = "Alloc/Dealloc",
135 .cond = {
136 .max_cycles = 200,
137 .no_memory = 0,
138 .no_allocated = 0,
139 },
140 .prob = {
141 .alloc = 50,
142 .free = 100
143 }
144 },
145 {
146 .name = "Deallocation",
147 .cond = {
148 .max_cycles = 0,
149 .no_memory = 0,
150 .no_allocated = 1,
151 },
152 .prob = {
153 .alloc = 10,
154 .free = 100
155 }
156 }
157};
158
159/*
160 * Phase definitions.
161 */
162static phase_t phases[] = {
163 {
164 .name = "32 B memory blocks",
165 .alloc = {
166 .min_block_size = 32,
167 .max_block_size = 32
168 },
169 .subphases = subphases_32B
170 },
171 {
172 .name = "128 KB memory blocks",
173 .alloc = {
174 .min_block_size = 128 * 1024,
175 .max_block_size = 128 * 1024
176 },
177 .subphases = subphases_128K
178 },
179 {
180 .name = "2500 B memory blocks",
181 .alloc = {
182 .min_block_size = 2500,
183 .max_block_size = 2500
184 },
185 .subphases = subphases_default
186 },
187 {
188 .name = "1 B .. 250000 B memory blocks",
189 .alloc = {
190 .min_block_size = 1,
191 .max_block_size = 250000
192 },
193 .subphases = subphases_default
194 }
195};
196
197static void do_subphase(phase_t *phase, subphase_t *subphase)
198{
199 for (unsigned int cycles = 0; /* always */; cycles++) {
200
201 if ((subphase->cond.max_cycles) &&
202 (cycles >= subphase->cond.max_cycles)) {
203 /*
204 * We have performed the required number of
205 * cycles. End the current subphase.
206 */
207 break;
208 }
209
210 /*
211 * Decide whether we alloc or free memory in this step.
212 */
213 unsigned int rnd = rand() % 100;
214 if (rnd < subphase->prob.alloc) {
215 /*
216 * Compute a random number lying in interval
217 * <min_block_size, max_block_size>
218 */
219 int alloc = phase->alloc.min_block_size +
220 (rand() % (phase->alloc.max_block_size - phase->alloc.min_block_size + 1));
221
222 mem_block_t *blk = alloc_block(alloc);
223 RETURN_IF_ERROR;
224
225 if (blk == NULL) {
226 TPRINTF("F(A)");
227 if (subphase->cond.no_memory) {
228 /* We filled the memory. Proceed to next subphase */
229 break;
230 }
231 } else {
232 TPRINTF("A");
233 fill_block(blk);
234
235 if ((mem_blocks_count % AREA_GRANULARITY) == 0) {
236 mem_area_t *area = map_area(AREA_SIZE);
237 RETURN_IF_ERROR;
238 if (area != NULL) {
239 TPRINTF("*");
240 fill_area(area);
241 } else
242 TPRINTF("F(*)");
243 }
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_malloc3(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.