00001 00030 /* 00031 * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University 00032 * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology 00033 * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology, Nagoya Institute of Technology 00034 * All rights reserved 00035 */ 00036 00037 #undef DEBUG /* output debug message */ 00038 00039 #define MYBMALLOC_LINKED 1 00040 00041 #include <sent/stddefs.h> 00042 00043 static boolean mybmalloc_initialized = FALSE; 00044 static char *current = NULL; 00045 static char *nowp = NULL; 00046 static char *endp = NULL; 00047 static unsigned int blocksize; 00048 static int align; 00049 static unsigned int align_mask; 00050 00051 #ifdef MYBMALLOC_LINKED 00052 00053 typedef struct _linked_buffer { 00054 unsigned long size; 00055 char *buffer; 00056 char *nowp; 00057 struct _linked_buffer *next; 00058 } *LINKED_BUFFER; 00059 00060 static LINKED_BUFFER first_linked_buffer = NULL; 00061 static LINKED_BUFFER last_linked_buffer = NULL; 00062 #endif 00063 00064 00069 void 00070 mybmalloc_set_param() 00071 { 00072 long pagesize, blockpagenum; 00073 00074 /* block size should be rounded up by page size */ 00075 pagesize = getpagesize(); 00076 blockpagenum = (MYBMALLOC_BLOCK_SIZE + (pagesize - 1)) / pagesize; 00077 blocksize = pagesize * blockpagenum; 00078 00079 /* alignment by a word (= pointer size?) */ 00080 #ifdef NO_ALIGN_DOUBLE 00081 align = sizeof(void *); 00082 #else 00083 /* better for floating points */ 00084 align = sizeof(double); 00085 #endif 00086 align_mask = ~(align - 1); /* assume power or 2 */ 00087 #ifdef DEBUG 00088 j_printerr("pagesize=%d blocksize=%d align=%d (bytes)\n", (int)pagesize, blocksize, align); 00089 #endif 00090 00091 mybmalloc_initialized = TRUE; 00092 } 00093 00101 void * 00102 mybmalloc(int size) 00103 { 00104 void *allocated; 00105 if (!mybmalloc_initialized) mybmalloc_set_param(); /* initialize if not yet */ 00106 /* malloc segment should be aligned to a word boundary */ 00107 size = (size + align - 1) & align_mask; 00108 if (!current || nowp + size >= endp) { 00109 #ifndef MYBMALLOC_LINKED 00110 if (size > blocksize) { 00111 /* large block, fall to normal malloc */ 00112 return(mymalloc(size)); 00113 } 00114 /* allocate next block */ 00115 current = (char *)mymalloc(blocksize); 00116 endp = current + blocksize; 00117 nowp = current; 00118 #else 00119 unsigned long current_size; 00120 LINKED_BUFFER linked_buffer = NULL; 00121 static LINKED_BUFFER prev_linked_buffer = NULL; 00122 00123 if (first_linked_buffer != NULL) { 00124 LINKED_BUFFER next_lb; 00125 00126 if (prev_linked_buffer != NULL) { 00127 prev_linked_buffer->nowp = nowp; 00128 } 00129 00130 /* search the buffer having left space */ 00131 next_lb = first_linked_buffer; 00132 while (next_lb != NULL) { 00133 if (next_lb->nowp + size <= next_lb->buffer + next_lb->size) { 00134 linked_buffer = next_lb; 00135 break; 00136 } 00137 next_lb = next_lb->next; 00138 } 00139 } 00140 00141 if (linked_buffer != NULL) { 00142 current = linked_buffer->nowp; 00143 endp = linked_buffer->buffer + linked_buffer->size; 00144 } else { 00145 current_size = (unsigned long)blocksize; 00146 while (current_size < (unsigned long)size) { 00147 current_size += (unsigned long)blocksize; 00148 } 00149 00150 linked_buffer = (LINKED_BUFFER)mymalloc(sizeof(struct _linked_buffer)); 00151 linked_buffer->size = current_size; 00152 linked_buffer->buffer = (char *)mymalloc(linked_buffer->size); 00153 linked_buffer->nowp = linked_buffer->buffer; 00154 linked_buffer->next = NULL; 00155 00156 if (first_linked_buffer == NULL) { 00157 first_linked_buffer = linked_buffer; 00158 } else if (last_linked_buffer != NULL) { 00159 last_linked_buffer->next = linked_buffer; 00160 } 00161 last_linked_buffer = linked_buffer; 00162 current = linked_buffer->buffer; 00163 endp = current + current_size; 00164 } 00165 prev_linked_buffer = linked_buffer; 00166 00167 nowp = current; 00168 #endif 00169 } 00170 /* return current pointer */ 00171 allocated = nowp; 00172 nowp += size; 00173 return(allocated); 00174 } 00175 00180 void mybmalloc_free(void) 00181 { 00182 #ifdef MYBMALLOC_LINKED 00183 if (first_linked_buffer != NULL) { 00184 LINKED_BUFFER curr_lb, next_lb; 00185 00186 next_lb = first_linked_buffer; 00187 while (next_lb != NULL) { 00188 curr_lb = next_lb; 00189 next_lb = curr_lb->next; 00190 free(curr_lb->buffer); 00191 free(curr_lb); 00192 } 00193 } 00194 first_linked_buffer = NULL; 00195 last_linked_buffer = NULL; 00196 current = nowp = endp = NULL; 00197 #endif 00198 00199 return; 00200 } 00201 00209 char * 00210 mybstrdup(char *s) 00211 { 00212 char *allocated; 00213 int size = strlen(s) + 1; 00214 allocated = mybmalloc(size); 00215 memcpy(allocated, s, size); 00216 return(allocated); 00217 } 00218 00227 void * 00228 mybmalloc2(int size, BMALLOC_BASE **list) 00229 { 00230 void *allocated; 00231 BMALLOC_BASE *new; 00232 if (!mybmalloc_initialized) mybmalloc_set_param(); /* initialize if not yet */ 00233 /* malloc segment should be aligned to a word boundary */ 00234 size = (size + align - 1) & align_mask; 00235 if (*list == NULL || (*list)->now + size >= (*list)->end) { 00236 new = (BMALLOC_BASE *)mymalloc(sizeof(BMALLOC_BASE)); 00237 if (size > blocksize) { 00238 /* large block, allocate a whole block */ 00239 new->base = mymalloc(size); 00240 new->end = (char *)new->base + size; 00241 } else { 00242 /* allocate per blocksize */ 00243 new->base = mymalloc(blocksize); 00244 new->end = (char *)new->base + blocksize; 00245 } 00246 new->now = (char *)new->base; 00247 new->next = (*list); 00248 *list = new; 00249 } 00250 /* return current pointer */ 00251 allocated = (*list)->now; 00252 (*list)->now += size; 00253 return(allocated); 00254 } 00255 00261 void 00262 mybfree2(BMALLOC_BASE **list) 00263 { 00264 BMALLOC_BASE *b, *btmp; 00265 b = *list; 00266 while (b) { 00267 btmp = b->next; 00268 free(b->base); 00269 free(b); 00270 b = btmp; 00271 } 00272 *list = NULL; 00273 }