test_mem.c

Go to the documentation of this file.
00001 /*##############################################################################
00002 
00003 nIP - nano IP stack
00004 
00005 File        : test_mem.c
00006 
00007 Description : Test nIP memory management
00008 
00009 Copyright notice:
00010 
00011 Copyright (C) 2007 -
00012 Andreas Dittrich, dittrich@informatik.hu-berlin.de
00013 Jon Kowal, kowal@informatik.hu-berlin.de
00014 
00015 This program is free software; you can redistribute it and/or
00016 modify it under the terms of the GNU General Public License
00017 as published by the Free Software Foundation; either version 2
00018 of the License, or (at your option) any later version.
00019 
00020 This program is distributed in the hope that it will be useful,
00021 but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00023 GNU General Public License for more details.
00024 
00025 You should have received a copy of the GNU General Public License
00026 along with this program; if not, write to the Free Software
00027 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00028 ##############################################################################*/
00029 
00030 #include "nip_init.h"
00031 #include "test/test_mem.h"
00032 #include "mem.h"
00033 #include "nip_error.h"
00034 
00035 #ifdef NIP_TEST_MEM
00036 
00037 /** performs several memory management checks
00038  *
00039  * 1. allocate more than maximum memory
00040  *
00041  *
00042  * @return 0 on SUCCESS or number of check that failed
00043  */
00044 uint8_t nip_test_mem()
00045 {
00046         nip_mem_size_t   res_length;
00047         nip_error_t      res_error;
00048         nip_mem_handle_t block_id;
00049         nip_mem_size_t   size, size1, size2, size3;
00050         nip_mem_size_t   unused;
00051 
00052         res_length = 0;
00053         block_id   = 0;
00054         // 1. Allocate memory block with minimum requested size of
00055         // NIP_MEM_DYNAMIC_SIZE+1. That should fail with NIP_E_OUT_OF_MEMORY error.
00056         block_id = nip_mem_alloc(
00057                 NIP_MEM_DYNAMIC_SIZE+1, /* wanted size */
00058                 NIP_MEM_DYNAMIC_SIZE+1, /* minimum size */
00059                 0,
00060                 &res_length
00061                 );
00062 
00063         if ( block_id != NIP_MEM_NULL
00064           || nip_error != NIP_E_OUT_OF_MEMORY
00065           || res_length != 0 )
00066                 return 1;
00067 
00068         res_length = 0;
00069         block_id   = 0;
00070         // 2. Allocate memory block with minimum requested size of
00071         // NIP_MEM_DYNAMIC_SIZE-sizeof(nip_mem_block_t)+1. That should fail with
00072         // NIP_E_OUT_OF_MEMORY error.
00073         block_id = nip_mem_alloc(
00074                 NIP_MEM_DYNAMIC_SIZE+1, /* wanted size */
00075                 NIP_MEM_DYNAMIC_SIZE-sizeof(nip_mem_block_t)+1, /* minimum size */
00076                 0,
00077                 &res_length
00078                 );
00079 
00080         if ( block_id != NIP_MEM_NULL
00081           || nip_error != NIP_E_OUT_OF_MEMORY
00082           || res_length != 0 )
00083                 return 2;
00084 
00085         res_length = 0;
00086         block_id   = 0;
00087         // 3. Allocate memory block with minimum requested size of
00088         // NIP_MEM_DYNAMIC_SIZE-sizeof(nip_mem_block_t), but too large size. That
00089         // succeed creating a block of minimum size that would take up all space.
00090         // The correct size has to be returned. The given Block-ID should be 1.
00091         block_id = nip_mem_alloc(
00092                 NIP_MEM_DYNAMIC_SIZE+1, /* wanted size */
00093                 NIP_MEM_DYNAMIC_SIZE-sizeof(nip_mem_block_t), /* minimum size */
00094                 0,
00095                 &res_length
00096                 );
00097 
00098         if ( block_id != 1
00099           || nip_error != NIP_E_OK
00100           || res_length != NIP_MEM_DYNAMIC_SIZE-sizeof(nip_mem_block_t) )
00101                 return 3;
00102 
00103         // 4. Allocating any amount of memory should fail now.
00104         block_id = nip_mem_alloc(10, 10, 0, &res_length );
00105         if ( block_id != NIP_MEM_NULL
00106           || nip_error != NIP_E_OUT_OF_MEMORY
00107           || res_length != NIP_MEM_DYNAMIC_SIZE-sizeof(nip_mem_block_t) ) /* should not have changed*/
00108                 return 4;
00109 
00110         // 5. Free allocated memory block 1. No check to that, but as it's simple
00111         // we'll assume it works.
00112         nip_mem_free( 1 );
00113 
00114         // 6.-8. Allocate three blocks filling up maximum space.
00115         block_id   = 0;
00116         size1 = 0;
00117         size       =  (NIP_MEM_DYNAMIC_SIZE-3*sizeof(nip_mem_block_t)) * 0.2;
00118         block_id = nip_mem_alloc(
00119                 size, /* wanted size */
00120                 size, /* minimum size */
00121                 0,
00122                 &size1
00123                 );
00124 
00125         if ( block_id != 1
00126           || nip_error != NIP_E_OK
00127           || size1 != size )
00128                 return 6;
00129 
00130         block_id   = 0;
00131         size2 = 0;
00132         size       =  (NIP_MEM_DYNAMIC_SIZE-3*sizeof(nip_mem_block_t)) * 0.3;
00133         block_id = nip_mem_alloc(
00134                 size, /* wanted size */
00135                 size, /* minimum size */
00136                 0,
00137                 &size2
00138                 );
00139 
00140         if ( block_id != 2
00141           || nip_error != NIP_E_OK
00142           || size2 != size )
00143                 return 7;
00144 
00145         block_id   = 0;
00146         res_length = 0;
00147         size       =  (NIP_MEM_DYNAMIC_SIZE-3*sizeof(nip_mem_block_t)) * 0.5;
00148         block_id = nip_mem_alloc(
00149                 size, /* wanted size */
00150                 size, /* minimum size */
00151                 0,
00152                 &size3
00153                 );
00154 
00155         if ( block_id != 3
00156           || nip_error != NIP_E_OK
00157           || size3 < size )     /* size3 may be larger than expected due to rounding
00158                                     inaccuracy which may result in one or two unused
00159                                     bytes to be added to the last block in memory
00160                                     because they are too few to form a new block. */
00161                 return 8;
00162         unused = size3 - size;
00163 
00164         // 9. free first block
00165         nip_mem_free( 1 );
00166 
00167         // 10. Allocate less than the available amount of memory. Since block-1 has
00168         // bin freed and is therefor unused. That block should be allocated and
00169         // because there is no unused Id between block-1 and block-2 the newly
00170         // allocated block will use up all the space of block-1.
00171         size       = size1 / 2;
00172         block_id   = 0;
00173         res_length = 0;
00174         block_id   = nip_mem_alloc(
00175                 size, /* wanted size */
00176                 size, /* minimum size */
00177                 0,
00178                 &res_length
00179                 );
00180 
00181         if ( block_id != 1
00182           || nip_error != NIP_E_OK
00183           || res_length != size1 )
00184                 return 10;
00185 
00186         // 11. Free first and second block
00187         nip_mem_free( 1 );
00188         nip_mem_free( 2 );
00189 
00190         // 12. Allocate less than the available amount of memory. Since block-1 and
00191         // block-2 are unused block-1 should be allocated and the remaining memory
00192         // be put into block-2.
00193         size       = size1 / 2;
00194         block_id   = 0;
00195         res_length = 0;
00196         block_id   = nip_mem_alloc(
00197                 size, /* wanted size */
00198                 size, /* minimum size */
00199                 0,
00200                 &res_length
00201         );
00202 
00203         if ( block_id != 1
00204           || nip_error != NIP_E_OK
00205           || res_length != size )
00206                 return 12;
00207 
00208         // 13. Allocate remaining memory for block 2
00209         size       = size1 + size2 - size;
00210         block_id   = 0;
00211         res_length = 0;
00212         block_id   = nip_mem_alloc(
00213                 size,
00214                 size,
00215                 0,
00216                 &res_length
00217         );
00218 
00219         if ( block_id != 2
00220           || nip_error != NIP_E_OK
00221           || res_length != size )
00222                 return 13;
00223 
00224         // 14. Reduce minimum length of block 1 to 10
00225         res_error = nip_mem_set_min_length( 1, 10 );
00226         if ( res_error != NIP_E_OK )
00227                 return 14;
00228 
00229         // 15. Set minimum length of block 1 to maximum possible length
00230         res_error = nip_mem_set_min_length( 1, size1/2 );
00231         if ( res_error != NIP_E_OK )
00232                 return 15;
00233 
00234         size1 = size1/2+unused;
00235         // 16. gather unused bytes
00236         if ( unused > 0 )
00237         {
00238                 res_error = nip_mem_set_min_length( 1, size1 );
00239                 if ( res_error != NIP_E_OK )
00240                         return 16;
00241         }
00242 
00243         // 17. Increase minimum length of block 1 over maximum size
00244         res_error = nip_mem_set_min_length( 1, size1+1 );
00245         if ( res_error != NIP_E_OUT_OF_MEMORY )
00246                 return 17;
00247 
00248         // check inserting new block in between two existing blocks
00249         // 18. free block 2, reduce min-size of block 1 and block 3 (19.)and allocate
00250         // new block with memory from all the others (20.).
00251         nip_mem_free( 2 );
00252         size1 = size1/2;
00253         res_error = nip_mem_set_min_length( 1, size1 );
00254         if ( res_error != NIP_E_OK )
00255                 return 18;
00256         
00257         // 19. reduce block 3 min-length
00258         size3 = size3/2;
00259         res_error = nip_mem_set_min_length( 3, size3 );
00260         if ( res_error != NIP_E_OK )
00261                 return 19;
00262 
00263         // 20. allocate new block
00264         size = size1+size3;
00265         block_id   = 0;
00266         res_length = 0;
00267         block_id   = nip_mem_alloc(
00268                 size,
00269                 size,
00270                 0,
00271                 &size2
00272         );
00273 
00274         if ( block_id != 2
00275           || nip_error != NIP_E_OK
00276           || size2 < size )
00277                 return 20;
00278 
00279 
00280         /// \todo check missing first block-case
00281         /// \todo check freeing of memory
00282         /// \todo check locked-block-case
00283         /// \todo more?
00284 
00285 
00286         // check inreasing a block into the space of an unused block
00287         // 21. free block 2, increase size of block1
00288         nip_mem_free( 2 );
00289         res_error = nip_mem_set_min_length( 1, size1+size2 );
00290         if ( res_error != NIP_E_OK )
00291                 return 21;
00292 
00293         return 0;
00294 }
00295 
00296 #endif

Generated on Thu Jul 10 01:09:29 2008 for NIP by  doxygen 1.5.5