~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Tina6/tina-libs/tina/sys/sysMem_ralloc.c

Version: ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /**********
  2  *
  3  * Copyright (c) 2003, Division of Imaging Science and Biomedical Engineering,
  4  * University of Manchester, UK.  All rights reserved.
  5  * 
  6  * Redistribution and use in source and binary forms, with or without modification, 
  7  * are permitted provided that the following conditions are met:
  8  * 
  9  *   . Redistributions of source code must retain the above copyright notice, 
 10  *     this list of conditions and the following disclaimer.
 11  *    
 12  *   . Redistributions in binary form must reproduce the above copyright notice,
 13  *     this list of conditions and the following disclaimer in the documentation 
 14  *     and/or other materials provided with the distribution.
 15  * 
 16  *   . Neither the name of the University of Manchester nor the names of its
 17  *     contributors may be used to endorse or promote products derived from this 
 18  *     software without specific prior written permission.
 19  * 
 20  * 
 21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  * POSSIBILITY OF SUCH DAMAGE.
 32  *
 33  **********
 34  *
 35  * Program :    TINA
 36  * File    :  $Source: /home/tina/cvs/tina-libs/tina/sys/sysMem_ralloc.c,v $
 37  * Date    :  $Date: 2003/09/22 16:09:02 $
 38  * Version :  $Revision: 1.8 $
 39  * CVS Id  :  $Id: sysMem_ralloc.c,v 1.8 2003/09/22 16:09:02 tony Exp $
 40  *
 41  * Author  :  Legacy TINA
 42  */
 43 /** 
 44  *  @file
 45  *  @brief Tina specific memory allocation functions.
 46  *
 47  *  At the lowest level the functions in this file wrap the standard c 'malloc' and 'free' 
 48  *  with the important addition of a testable string (picket fence) prior to each block
 49  *  in order to detect memory overwriting. These low-level routines are called by
 50  *  most (though not all) memory allocation processes in Tina.
 51  *  
 52  *
 53  *  There are two groups of functions;
 54  *
 55  *  - Block allocation.  A global scope linked list is maintained to which other lists are
 56  *    added.  Each of these lists indexes the start memory addresses of allocaterd memory areas.
 57  *    In this way groups of allocated memory can be associated together in one place and 'remanaged'
 58  *    just by indexing a label.
 59  *
 60  *  - Malloc.
 61  *
 62  */
 63 
 64 #include "sysMem_ralloc.h"
 65 
 66 #if HAVE_CONFIG_H
 67 #include <config.h>
 68 #endif
 69 
 70 #include <stdio.h>
 71 #include <stdlib.h>
 72 #include <string.h>
 73 #include <tina/sys/sys_GenDef.h>
 74 #include <tina/sys/sys_LstDef.h>
 75 #include <tina/sys/sys_MemDef.h>
 76 #include <tina/sys/sysLst_list.h>
 77 #include <tina/sys/sysMem_ralloc.h>
 78 #include <tina/sys/sysGen_messages.h>
 79 #include <tina/sys/sysGen_error.h>
 80 
 81 /* ICC ? */
 82 #ifdef _ICC
 83 #include <process.h>
 84 #define sleep(n) ProcWait((n)*1000000/(ProcGetPriority()*64))
 85 #else
 86 extern unsigned sleep(unsigned seconds);
 87 #endif
 88 
 89 /* IBM ? */
 90 #ifdef IBM
 91 extern void     free();
 92 #endif
 93 
 94 /**
 95  * Tags for blocking code.
 96  */
 97 #define NOT_BLOCKED 0
 98 #define BLOCKED_ALLOC 1
 99 
100 /**
101  * Global blocking variables.
102  */
103 static List    *blk_stat_list = NULL;   /** Head of overall block allocation lists. */                                                  /* static data! */
104 static Blk_stat *current = NULL;/** Current block (to which allocations are being referenced. */                                /* static data! */
105 static unsigned int label = 0;  /** Numeric label for current list. */                                                                                  /* static data! */
106 static Bool     blocked_alloc = false;  /** Tells ralloc and rfree whether blocked allocation is being done. */ /* static data! */
107 
108 
109 /**
110  * @brief Little more than malloc.  
111  * @param size Amount of memory to allocate.
112  * @return cptr Pointer to allocated memory. 
113  * 
114  * Use to make repeated (infinite) attempts to allocate the memory but this could easily lead to an 
115  * infinite loop.  This part has now been commented out.  What is left is something which does little
116  * more than malloc.
117  *
118  */
119 static void    *rep_alloc(unsigned int size)
120 {
121         Align          *cptr = NULL;
122         char            mess[256];
123 
124         cptr = (Align *) malloc(size);
125         /*
126         while (cptr == NULL)
127         {
128             (void) sprintf(mess, " %d out of store: try and free some", size);
129             message(mess);
130             sleep(5);
131             cptr = (Align *) malloc(size);
132             if (cptr != NULL)
133                 message("store ok");
134         }
135         */
136         if (cptr == NULL)
137         {
138                 (void) sprintf(mess, "allocating 0 not %d bytes", size);
139                 message(mess);
140         }
141         return cptr;
142 }
143 
144 /** 
145  *  @brief Make and parameterise a block allocation structure.
146  *  @param label Key of list which block is in.
147  *  @param size Amount of memory in this block.
148  *  @return blk Pointer to structure.
149  */
150 static Blk_stat *blk_stat_make(unsigned int label, unsigned int size)
151 {
152         Blk_stat       *blk = ts_ralloc(Blk_stat);
153 
154         blk->label = label;
155         blk->block = (Align *) rep_alloc(size);
156         blk->block_list = link_alloc((void *) blk->block, BLOCKED_ALLOC);
157         blk->bsize = size;
158         blk->n = size;
159         return (blk);
160 }
161 
162 
163 /** 
164  *  @brief Free block allocation structure.
165  *  @param blk_stat Pointer to structure to free.
166  */
167 static void     blk_stat_free(Blk_stat * blk_stat)
168 {
169         if (blk_stat == NULL)
170                 return;
171 
172         list_rm(blk_stat->block_list, (void (*) ()) free);
173         rfree((void *) blk_stat);
174 }
175 
176 /** 
177  *  @brief Allocate the memory.
178  *  @param size Amount of memory to allocate.
179  *  @return ptr Pointer to allocated memory.
180  */
181 static void    *blk_alloc(unsigned int size)
182 {
183         Align          *ptr;
184         unsigned int    ibks;
185 
186         if (size > current->bsize)
187         {                       /* generate special block */
188                 Align          *block = (Align *) rep_alloc(size);
189 
190                 blocked_alloc = false;  /* to stop recursion */
191                 current->block_list = ref_addtostart(current->block_list, (void *) block, BLOCKED_ALLOC);
192                 blocked_alloc = true;
193                 return block;
194         }
195         if (size > current->n)
196         {                       /* need a new block */
197                 current->block = (Align *) rep_alloc(current->bsize);
198                 blocked_alloc = false;  /* to stop recursion */
199                 current->block_list = ref_addtostart(current->block_list, (void *) current->block, BLOCKED_ALLOC);
200                 blocked_alloc = true;
201                 current->n = current->bsize;
202         }
203         ibks = size / sizeof(Align);
204         if (size % sizeof(Align))
205                 ibks++;
206         ptr = current->block;
207         current->block += ibks;
208         current->n -= ibks * sizeof(Align);
209 
210         return ptr;
211 }
212 
213 
214 /** 
215  *  @brief Begin new blocked allocation list.
216  *  @param s Size of memory area to be allocated.
217  *  @return label Key for the newly allocation list.
218  */
219 unsigned int    ralloc_new_blocked(unsigned int s)
220 {
221         blocked_alloc = false;
222         ++label;
223         current = blk_stat_make(label, s);
224         blk_stat_list = ref_addtostart(blk_stat_list, (void *) current, (int) label);
225         blocked_alloc = true;
226         return (label);
227 }
228 
229 
230 /** 
231  *  @brief (re)start blocked allocation on list.  
232  *  @param label Key indicating which list to add to.
233  *  @return old_label Key for the list now being allocated to.
234  *
235  *  Make this list the current one to add new allocations to.
236  */
237 unsigned int    ralloc_start_blocked(unsigned int label)
238 {
239         List           *ptr = link_get_by_type((List *) blk_stat_list, (int) label);
240         unsigned int    old_label;
241 
242         if (ptr == NULL)
243         {                       /* label does not key an active list */
244                 blocked_alloc = false;
245                 return 0;
246         }
247         old_label = (current == NULL) ? 0 : current->label;
248 
249         current = (Blk_stat *) ptr->to;
250         blocked_alloc = true;
251 
252         return (old_label);
253 }
254 
255 
256 /** 
257  *  @brief Stop performing blocked allocation.
258  *  @return old_label Key to last allocation block.
259  */
260 unsigned int    ralloc_end_blocked(void)
261 {
262         unsigned int    old_label;
263 
264         blocked_alloc = false;
265         old_label = (current == NULL) ? 0 : current->label;
266         current = NULL;
267         return (old_label);
268 }
269 
270 
271 /** 
272  *  @brief Free up blocked allocation list and delete list entry.
273  *  @param label Key of block to free.
274  */
275 void            ralloc_free_blocked(unsigned int label)
276 {
277         List           *ptr = link_get_by_type(blk_stat_list, (int) label);
278 
279         blocked_alloc = false;
280         blk_stat_list = list_rm_el(blk_stat_list, ptr, blk_stat_free);
281 }
282 
283 
284 /** 
285  *  @brief Basic memory allocation function.  
286  *  @param size Size of memory area to allocate.
287  *
288  *  This is the basic memory allocation function in tina and should be used in place
289  *  of malloc.  Its behaviour mirrors that of malloc whilst recognising blocking types
290  *  and zeroing the memory area being allocated.
291  *
292  *  PAB 16/11/2010: prevent attempts to write to the allocated memory if the pointer 
293  *  returned from blk_alloc is NULL (proabable cause: out of memory).  The caller should
294  *  check whether the pointer returned by this function is NULL.
295  *
296  */
297 void           *ralloc(size_t size)
298 {
299         Align          *ptr;
300 
301         size += sizeof(Align);
302         if (blocked_alloc == true)
303         {
304                 ptr = (Align *) blk_alloc(size);
305                 if(ptr==NULL) return NULL;
306                 (void) memset((char *) ptr, 0, (int) size);
307                 *(int *) ptr = BLOCKED_ALLOC;
308         } else
309         {
310                 ptr = (Align *) rep_alloc(size);
311                 if(ptr==NULL) return NULL;
312                 (void) memset((char *) ptr, 0, (int) size);
313                 *(int *) ptr = NOT_BLOCKED;
314         }
315         return ++ptr;
316 }
317 
318 
319 /** 
320  *  @brief Basic memory freeing function.
321  *  @param ptr Pointer to memory area to be freed.
322  *  
323  *  This is the basic memory freeing function in tina nd should be used in place of free.
324  *  Its behaviour mirors that of free whilst recognising blocking types.
325  */
326 void            rfree(void *ptr)
327 {
328         Align          *iptr;
329 
330         if (ptr == NULL)
331                 return;
332         iptr = (Align *) ptr;
333         iptr--;
334         if (*((int *) iptr) == NOT_BLOCKED)
335                 free((char *) iptr);
336         else if (*((int *) iptr) != BLOCKED_ALLOC)
337                 error("memory overwriting detected in rfree()", warning);
338 }
339 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.