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

Linux Cross Reference
Tina4/src/sys/gen/ralloc.c

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

  1 /**@(#)Memory allocation (Tina's malloc).
  2  * @(#)Intelligent wrappers to malloc and free
  3  * (revised version 24 10 91)
  4  *
  5  * 2 additional features
  6  *
  7  * 1. test for exhausted memory (giving the option to free some) hence
  8  * user need not check results of allocation directly
  9  * note: this option is a pain - commented out.
 10  *
 11  * 2. allows efficient (time but perhaps not space) block allocation user
 12  * provides blocking factor multi block support synchronised free
 13  *
 14  * Why no equivalent of realloc?
 15  * Because we don't know size of original memory, so can't copy data from it.
 16  */
 17 
 18 #include <stdio.h>
 19 #include <string.h>
 20 #include <tina/sys.h>
 21 #include <tina/sysfuncs.h>
 22 
 23 /* blocking types */
 24 #define NOT_BLOCKED 0
 25 #define BLOCKED_ALLOC 1
 26 
 27 #ifdef _ICC
 28 #include <process.h>
 29 #define sleep(n) ProcWait((n)*1000000/(ProcGetPriority()*64))
 30 #else
 31 extern unsigned sleep(unsigned seconds);
 32 #endif
 33 
 34 #ifdef IBM
 35 extern void free();
 36 #endif
 37 
 38 /* basic repated malloc call */
 39 static void *rep_alloc(unsigned int size)
 40 {
 41     Align  *cptr = NULL;
 42     char    mess[256];
 43 
 44     cptr = (Align *) malloc(size);
 45     /**
 46     while (cptr == NULL)
 47     {
 48         (void) sprintf(mess, " %d out of store: try and free some", size);
 49         message(mess);
 50         sleep(5);
 51         cptr = (Align *) malloc(size);
 52         if (cptr != NULL)
 53             message("store ok");
 54     }
 55     **/
 56     if(cptr == NULL)
 57     {
 58         (void) sprintf(mess, "allocating 0 not %d bytes", size);
 59         message(mess);
 60     }
 61     return cptr;
 62 }
 63 
 64 static Blk_stat *blk_stat_make(unsigned int label, unsigned int size)
 65 {
 66     Blk_stat *blk = ts_ralloc(Blk_stat);
 67 
 68     blk->label = label;
 69     blk->block = (Align *) rep_alloc(size);
 70     blk->block_list = link_alloc((void *) blk->block, BLOCKED_ALLOC);
 71     blk->bsize = size;
 72     blk->n = size;
 73     return (blk);
 74 }
 75 
 76 static void blk_stat_free(Blk_stat * blk_stat)
 77 {
 78     if (blk_stat == NULL)
 79         return;
 80 
 81     list_rm(blk_stat->block_list, (void (*) ()) free);
 82     rfree((void *) blk_stat);
 83 }
 84 
 85 /* state variables */
 86 static List *blk_stat_list = NULL;
 87 static Blk_stat *current = NULL;
 88 static unsigned int label = 0;
 89 static Bool blocked_alloc = false;
 90 
 91 /* start new blocked allocation list set blocked_alloc true return
 92  * access key for allocation list */
 93 unsigned int ralloc_new_blocked(unsigned int s)
 94 {
 95     blocked_alloc = false;
 96     ++label;
 97     current = blk_stat_make(label, s);
 98     blk_stat_list = ref_addtostart(blk_stat_list, (void *) current, (int) label);
 99     blocked_alloc = true;
100     return (label);
101 }
102 
103 /* (re)start blocked allocation on list keyed by label */
104 unsigned int ralloc_start_blocked(unsigned int label)
105 {
106     List   *ptr = link_get_by_type((List *) blk_stat_list, (int) label);
107     unsigned int old_label;
108 
109     if (ptr == NULL)
110     {                           /* label does not key an active list */
111         blocked_alloc = false;
112         return 0;
113     }
114     old_label = (current == NULL) ? 0 : current->label;
115 
116     current = (Blk_stat *) ptr->to;
117     blocked_alloc = true;
118 
119     return (old_label);
120 }
121 
122 /* stop performing blocked allocation */
123 unsigned int ralloc_end_blocked(void)
124 {
125     unsigned int old_label;
126 
127     blocked_alloc = false;
128     old_label = (current == NULL) ? 0 : current->label;
129     current = NULL;
130     return (old_label);
131 }
132 
133 /* free up blocked allocation list and delete list entry */
134 void    ralloc_free_blocked(unsigned int label)
135 {
136     List   *ptr = link_get_by_type(blk_stat_list, (int) label);
137 
138     blocked_alloc = false;
139     blk_stat_list = list_rm_el(blk_stat_list, ptr, blk_stat_free);
140 }
141 
142 /* perform allocation into current blocked allocation list */
143 static void *blk_alloc(unsigned int size)
144 {
145     Align  *ptr;
146     unsigned int ibks;
147 
148     if (size > current->bsize)
149     {                           /* generate special block */
150         Align  *block = (Align *) rep_alloc(size);
151 
152         blocked_alloc = false;  /* to stop recursion */
153         current->block_list = ref_addtostart(current->block_list, (void *) block, BLOCKED_ALLOC);
154         blocked_alloc = true;
155         return block;
156     }
157     if (size > current->n)
158     {                           /* need a new block */
159         current->block = (Align *) rep_alloc(current->bsize);
160         blocked_alloc = false;  /* to stop recursion */
161         current->block_list = ref_addtostart(current->block_list, (void *) current->block, BLOCKED_ALLOC);
162         blocked_alloc = true;
163         current->n = current->bsize;
164     }
165     ibks = size / sizeof(Align);
166     if (size % sizeof(Align))
167         ibks++;
168     ptr = current->block;
169     current->block += ibks;
170     current->n -= ibks * sizeof(Align);
171 
172     return ptr;
173 }
174 
175 /* malloc wrapper and initialisation */
176 void   *ralloc(size_t size)
177 {
178     Align  *ptr;
179 
180     size += sizeof(Align);
181     if (blocked_alloc == true)
182     {
183         ptr = (Align *) blk_alloc(size);
184         (void) memset((char *) ptr, 0, (int) size);
185         *(int *) ptr = BLOCKED_ALLOC;
186     } else
187     {
188         ptr = (Align *) rep_alloc(size);
189         (void) memset((char *) ptr, 0, (int) size);
190         *(int *) ptr = NOT_BLOCKED;
191     }
192     return ++ptr;
193 }
194 
195 /* free wrapper */
196 void    rfree(void *ptr)
197 {
198     Align  *iptr;
199 
200     if (ptr == NULL)
201         return;
202     iptr = (Align *) ptr;
203     iptr--;
204     if (*((int *) iptr) == NOT_BLOCKED)
205         free((char *) iptr);
206     else if (*((int *) iptr) != BLOCKED_ALLOC)
207         error("memory overwriting detected in rfree()",warning);
208 }
209 

~ [ 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.