malloc3.c

00001 /*
00002  * Copyright (c) 2009 Martin Decky
00003  * Copyright (c) 2009 Tomas Bures
00004  * Copyright (c) 2009 Lubomir Bulej
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright
00012  *   notice, this list of conditions and the following disclaimer.
00013  * - Redistributions in binary form must reproduce the above copyright
00014  *   notice, this list of conditions and the following disclaimer in the
00015  *   documentation and/or other materials provided with the distribution.
00016  * - The name of the author may not be used to endorse or promote products
00017  *   derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00020  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00021  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00022  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00024  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00025  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00026  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00028  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  */
00030 
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include "common.h"
00034 #include "../tester.h"
00035 
00036 /*
00037  * The test is a slight adaptation of malloc1 test. The major difference
00038  * is that the test forces the heap allocator to create multiple
00039  * heap areas by creating disturbing address space areas.
00040  */
00041 
00042 static subphase_t subphases_32B[] = {
00043         {
00044                 .name = "Allocation",
00045                 .cond = {
00046                         .max_cycles = 200,
00047                         .no_memory = 1,
00048                         .no_allocated = 0,
00049                 },
00050                 .prob = {
00051                         .alloc = 90,
00052                         .free = 100
00053                 }
00054         },
00055         {
00056                 .name = "Alloc/Dealloc",
00057                 .cond = {
00058                         .max_cycles = 200,
00059                         .no_memory = 0,
00060                         .no_allocated = 0,
00061                 },
00062                 .prob = {
00063                         .alloc = 50,
00064                         .free = 100
00065                 }
00066         },
00067         {
00068                 .name = "Deallocation",
00069                 .cond = {
00070                         .max_cycles = 0,
00071                         .no_memory = 0,
00072                         .no_allocated = 1,
00073                 },
00074                 .prob = {
00075                         .alloc = 10,
00076                         .free = 100
00077                 }
00078         }
00079 };
00080 
00081 static subphase_t subphases_128K[] = {
00082         {
00083                 .name = "Allocation",
00084                 .cond = {
00085                         .max_cycles = 0,
00086                         .no_memory = 1,
00087                         .no_allocated = 0,
00088                 },
00089                 .prob = {
00090                         .alloc = 70,
00091                         .free = 100
00092                 }
00093         },
00094         {
00095                 .name = "Alloc/Dealloc",
00096                 .cond = {
00097                         .max_cycles = 30,
00098                         .no_memory = 0,
00099                         .no_allocated = 0,
00100                 },
00101                 .prob = {
00102                         .alloc = 50,
00103                         .free = 100
00104                 }
00105         },
00106         {
00107                 .name = "Deallocation",
00108                 .cond = {
00109                         .max_cycles = 0,
00110                         .no_memory = 0,
00111                         .no_allocated = 1,
00112                 },
00113                 .prob = {
00114                         .alloc = 30,
00115                         .free = 100
00116                 }
00117         }
00118 };
00119 
00120 static subphase_t subphases_default[] = {
00121         {
00122                 .name = "Allocation",
00123                 .cond = {
00124                         .max_cycles = 0,
00125                         .no_memory = 1,
00126                         .no_allocated = 0,
00127                 },
00128                 .prob = {
00129                         .alloc = 90,
00130                         .free = 100
00131                 }
00132         },
00133         {
00134                 .name = "Alloc/Dealloc",
00135                 .cond = {
00136                         .max_cycles = 200,
00137                         .no_memory = 0,
00138                         .no_allocated = 0,
00139                 },
00140                 .prob = {
00141                         .alloc = 50,
00142                         .free = 100
00143                 }
00144         },
00145         {
00146                 .name = "Deallocation",
00147                 .cond = {
00148                         .max_cycles = 0,
00149                         .no_memory = 0,
00150                         .no_allocated = 1,
00151                 },
00152                 .prob = {
00153                         .alloc = 10,
00154                         .free = 100
00155                 }
00156         }
00157 };
00158 
00159 /*
00160  * Phase definitions.
00161  */
00162 static phase_t phases[] = {
00163         {
00164                 .name = "32 B memory blocks",
00165                 .alloc = {
00166                         .min_block_size = 32,
00167                         .max_block_size = 32
00168                 },
00169                 .subphases = subphases_32B
00170         },
00171         {
00172                 .name = "128 KB memory blocks",
00173                 .alloc = {
00174                         .min_block_size = 128 * 1024,
00175                         .max_block_size = 128 * 1024
00176                 },
00177                 .subphases = subphases_128K
00178         },
00179         {
00180                 .name = "2500 B memory blocks",
00181                 .alloc = {
00182                         .min_block_size = 2500,
00183                         .max_block_size = 2500
00184                 },
00185                 .subphases = subphases_default
00186         },
00187         {
00188                 .name = "1 B .. 250000 B memory blocks",
00189                 .alloc = {
00190                         .min_block_size = 1,
00191                         .max_block_size = 250000
00192                 },
00193                 .subphases = subphases_default
00194         }
00195 };
00196 
00197 static void do_subphase(phase_t *phase, subphase_t *subphase)
00198 {
00199         for (unsigned int cycles = 0; /* always */; cycles++) {
00200                 
00201                 if ((subphase->cond.max_cycles) &&
00202                     (cycles >= subphase->cond.max_cycles)) {
00203                         /*
00204                          * We have performed the required number of
00205                          * cycles. End the current subphase.
00206                          */
00207                         break;
00208                 }
00209                 
00210                 /*
00211                  * Decide whether we alloc or free memory in this step.
00212                  */
00213                 unsigned int rnd = rand() % 100;
00214                 if (rnd < subphase->prob.alloc) {
00215                         /*
00216                          * Compute a random number lying in interval
00217                          * <min_block_size, max_block_size>
00218                          */
00219                         int alloc = phase->alloc.min_block_size +
00220                             (rand() % (phase->alloc.max_block_size - phase->alloc.min_block_size + 1));
00221                         
00222                         mem_block_t *blk = alloc_block(alloc);
00223                         RETURN_IF_ERROR;
00224                         
00225                         if (blk == NULL) {
00226                                 TPRINTF("F(A)");
00227                                 if (subphase->cond.no_memory) {
00228                                         /* We filled the memory. Proceed to next subphase */
00229                                         break;
00230                                 }
00231                         } else {
00232                                 TPRINTF("A");
00233                                 fill_block(blk);
00234                                 RETURN_IF_ERROR;
00235                                 
00236                                 if ((mem_blocks_count % AREA_GRANULARITY) == 0) {
00237                                         mem_area_t *area = map_area(AREA_SIZE);
00238                                         RETURN_IF_ERROR;
00239                                         
00240                                         if (area != NULL) {
00241                                                 TPRINTF("*");
00242                                                 fill_area(area);
00243                                                 RETURN_IF_ERROR;
00244                                         } else
00245                                                 TPRINTF("F(*)");
00246                                 }
00247                         }
00248                         
00249                 } else if (rnd < subphase->prob.free) {
00250                         mem_block_t *blk = get_random_block();
00251                         if (blk == NULL) {
00252                                 TPRINTF("F(R)");
00253                                 if (subphase->cond.no_allocated) {
00254                                         /* We free all the memory. Proceed to next subphase. */
00255                                         break;
00256                                 }
00257                         } else {
00258                                 TPRINTF("R");
00259                                 check_block(blk);
00260                                 RETURN_IF_ERROR;
00261                                 
00262                                 free_block(blk);
00263                                 RETURN_IF_ERROR;
00264                         }
00265                 }
00266         }
00267         
00268         TPRINTF("\n..  finished.\n");
00269 }
00270 
00271 static void do_phase(phase_t *phase)
00272 {
00273         for (unsigned int subno = 0; subno < 3; subno++) {
00274                 subphase_t *subphase = &phase->subphases[subno];
00275                 
00276                 TPRINTF(".. Sub-phase %u (%s)\n", subno + 1, subphase->name);
00277                 do_subphase(phase, subphase);
00278                 RETURN_IF_ERROR;
00279         }
00280 }
00281 
00282 const char *test_malloc3(void)
00283 {
00284         init_mem();
00285         
00286         for (unsigned int phaseno = 0; phaseno < sizeof_array(phases);
00287             phaseno++) {
00288                 phase_t *phase = &phases[phaseno];
00289                 
00290                 TPRINTF("Entering phase %u (%s)\n", phaseno + 1, phase->name);
00291                 
00292                 do_phase(phase);
00293                 if (error_flag)
00294                         break;
00295                 
00296                 TPRINTF("Phase finished.\n");
00297         }
00298         
00299         TPRINTF("Cleaning up.\n");
00300         done_mem();
00301         if (error_flag)
00302                 return "Test failed";
00303         
00304         return NULL;
00305 }

Generated on Thu Jun 2 07:45:43 2011 for HelenOS/USB by  doxygen 1.4.7