libsent/src/util/mybmalloc.c

Go to the documentation of this file.
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
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
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 
00264 char *
00265 mybstrdup2(char *s, BMALLOC_BASE **list)
00266 {
00267   char *allocated;
00268   int size = strlen(s) + 1;
00269   allocated = mybmalloc2(size, list);
00270   memcpy(allocated, s, size);
00271   return(allocated);
00272 }
00273 
00279 void
00280 mybfree2(BMALLOC_BASE **list)
00281 {
00282   BMALLOC_BASE *b, *btmp;
00283   b = *list;
00284   while (b) {
00285     btmp = b->next;
00286     free(b->base);
00287     free(b);
00288     b = btmp;
00289   }
00290   *list = NULL;
00291 }

Generated on Tue Dec 26 16:16:33 2006 for Julius by  doxygen 1.5.0