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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3061bc1 was 582a0b8, checked in by Jakub Jermar <jakub@…>, 8 years ago

Remove unistd.h

  • Rename usleep() and sleep() to thread_usleep() and thread_sleep() and move to thread.[hc].
  • Include stddef.h in order to provide NULL.
  • Move getpagesize() to libposix.
  • Sync uspace/dist/src/c/demos with originals.
  • 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 <stddef.h>
34#include "common.h"
35#include "../tester.h"
36
37/*
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.
45 */
46
47/*
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.
51 */
52static subphase_t subphases_32B[] = {
53 {
54 .name = "Allocation",
55 .cond = {
56 .max_cycles = 200,
57 .no_memory = 1,
58 .no_allocated = 0,
59 },
60 .prob = {
61 .alloc = 90,
62 .free = 100
63 }
64 },
65 {
66 .name = "Alloc/Dealloc",
67 .cond = {
68 .max_cycles = 200,
69 .no_memory = 0,
70 .no_allocated = 0,
71 },
72 .prob = {
73 .alloc = 50,
74 .free = 100
75 }
76 },
77 {
78 .name = "Deallocation",
79 .cond = {
80 .max_cycles = 0,
81 .no_memory = 0,
82 .no_allocated = 1,
83 },
84 .prob = {
85 .alloc = 10,
86 .free = 100
87 }
88 }
89};
90
91static subphase_t subphases_128K[] = {
92 {
93 .name = "Allocation",
94 .cond = {
95 .max_cycles = 0,
96 .no_memory = 1,
97 .no_allocated = 0,
98 },
99 .prob = {
100 .alloc = 70,
101 .free = 100
102 }
103 },
104 {
105 .name = "Alloc/Dealloc",
106 .cond = {
107 .max_cycles = 30,
108 .no_memory = 0,
109 .no_allocated = 0,
110 },
111 .prob = {
112 .alloc = 50,
113 .free = 100
114 }
115 },
116 {
117 .name = "Deallocation",
118 .cond = {
119 .max_cycles = 0,
120 .no_memory = 0,
121 .no_allocated = 1,
122 },
123 .prob = {
124 .alloc = 30,
125 .free = 100
126 }
127 }
128};
129
130static subphase_t subphases_default[] = {
131 {
132 .name = "Allocation",
133 .cond = {
134 .max_cycles = 0,
135 .no_memory = 1,
136 .no_allocated = 0,
137 },
138 .prob = {
139 .alloc = 90,
140 .free = 100
141 }
142 },
143 {
144 .name = "Alloc/Dealloc",
145 .cond = {
146 .max_cycles = 200,
147 .no_memory = 0,
148 .no_allocated = 0,
149 },
150 .prob = {
151 .alloc = 50,
152 .free = 100
153 }
154 },
155 {
156 .name = "Deallocation",
157 .cond = {
158 .max_cycles = 0,
159 .no_memory = 0,
160 .no_allocated = 1,
161 },
162 .prob = {
163 .alloc = 10,
164 .free = 100
165 }
166 }
167};
168
169/*
170 * Phase definitions.
171 */
172static phase_t phases[] = {
173 {
174 .name = "32 B memory blocks",
175 .alloc = {
176 .min_block_size = 32,
177 .max_block_size = 32
178 },
179 .subphases = subphases_32B
180 },
181 {
182 .name = "128 KB memory blocks",
183 .alloc = {
184 .min_block_size = 128 * 1024,
185 .max_block_size = 128 * 1024
186 },
187 .subphases = subphases_128K
188 },
189 {
190 .name = "2500 B memory blocks",
191 .alloc = {
192 .min_block_size = 2500,
193 .max_block_size = 2500
194 },
195 .subphases = subphases_default
196 },
197 {
198 .name = "1 B .. 250000 B memory blocks",
199 .alloc = {
200 .min_block_size = 1,
201 .max_block_size = 250000
202 },
203 .subphases = subphases_default
204 }
205};
206
207static void do_subphase(phase_t *phase, subphase_t *subphase)
208{
209 for (unsigned int cycles = 0; /* always */; cycles++) {
210
211 if ((subphase->cond.max_cycles) &&
212 (cycles >= subphase->cond.max_cycles)) {
213 /*
214 * We have performed the required number of
215 * cycles. End the current subphase.
216 */
217 break;
218 }
219
220 /*
221 * Decide whether we alloc or free memory in this step.
222 */
223 unsigned int rnd = rand() % 100;
224 if (rnd < subphase->prob.alloc) {
225 /*
226 * Compute a random number lying in interval
227 * <min_block_size, max_block_size>
228 */
229 int alloc = phase->alloc.min_block_size +
230 (rand() % (phase->alloc.max_block_size - phase->alloc.min_block_size + 1));
231
232 mem_block_t *blk = alloc_block(alloc);
233 RETURN_IF_ERROR;
234
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;
240 }
241 } else {
242 TPRINTF("A");
243 fill_block(blk);
244 RETURN_IF_ERROR;
245 }
246
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;
254 }
255 } else {
256 TPRINTF("R");
257 check_block(blk);
258 RETURN_IF_ERROR;
259
260 free_block(blk);
261 RETURN_IF_ERROR;
262 }
263 }
264 }
265
266 TPRINTF("\n.. finished.\n");
267}
268
269static void do_phase(phase_t *phase)
270{
271 for (unsigned int subno = 0; subno < 3; subno++) {
272 subphase_t *subphase = &phase->subphases[subno];
273
274 TPRINTF(".. Sub-phase %u (%s)\n", subno + 1, subphase->name);
275 do_subphase(phase, subphase);
276 RETURN_IF_ERROR;
277 }
278}
279
280const char *test_malloc1(void)
281{
282 init_mem();
283
284 for (unsigned int phaseno = 0; phaseno < sizeof_array(phases);
285 phaseno++) {
286 phase_t *phase = &phases[phaseno];
287
288 TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name);
289
290 do_phase(phase);
291 if (error_flag)
292 break;
293
294 TPRINTF("Phase finished.\n");
295 }
296
297 TPRINTF("Cleaning up.\n");
298 done_mem();
299 if (error_flag)
300 return "Test failed";
301
302 return NULL;
303}
Note: See TracBrowser for help on using the repository browser.