Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #include "libts.h"
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 void
00045 StrList::dump(FILE * fp)
00046 {
00047   Str *str;
00048 
00049   for (str = head; str != NULL; str = str->next)
00050     str->dump(fp);
00051 }
00052 
00053 
00054 
00055 
00056 Str *
00057 StrList::_new_cell(const char *s, int len_not_counting_nul)
00058 {
00059   Str *cell;
00060   char *p;
00061   int l = len_not_counting_nul;
00062 
00063   
00064   if (cells_allocated < STRLIST_BASE_CELLS) {
00065     cell = &(base_cells[cells_allocated]);
00066   } else {
00067     p = (char *) alloc(sizeof(Str) + 7);
00068     if (p == NULL)
00069       return (NULL);            
00070     p = (char *) ((((uintptr_t)p) + 7) & ~7);       
00071     cell = (Str *) p;
00072   }
00073   ++cells_allocated;
00074 
00075   
00076   if (copy_when_adding_string) {
00077     char *buf = (char *) alloc(l + 1);
00078     if (buf == NULL)
00079       return (NULL);            
00080     memcpy(buf, s, l);
00081     buf[l] = '\0';
00082 
00083     cell->str = (const char *) buf;
00084   } else {
00085     cell->str = s;
00086   }
00087 
00088   cell->len = l;
00089 
00090   return (cell);
00091 }
00092 
00093 
00094 
00095 
00096 void *
00097 StrList::overflow_heap_alloc(int size)
00098 {
00099   if (!overflow_first) {
00100     overflow_first = overflow_current = StrListOverflow::create_heap(STRLIST_OVERFLOW_HEAP_SIZE);
00101   }
00102 
00103   return overflow_current->alloc(size, &overflow_current);
00104 }
00105 
00106 
00107 
00108 
00109 void
00110 StrList::overflow_heap_clean()
00111 {
00112   if (overflow_first)
00113     overflow_first->clean();
00114 }
00115 
00116 
00117 #define INIT_OVERFLOW_ALIGNMENT      8
00118 
00119 const int overflow_head_hdr_size = INK_ALIGN(sizeof(StrListOverflow), INIT_OVERFLOW_ALIGNMENT);
00120 
00121 void
00122 StrListOverflow::init()
00123 {
00124   next = NULL;
00125   heap_size = 0;
00126   heap_used = 0;
00127 }
00128 
00129 void
00130 StrListOverflow::clean()
00131 {
00132   StrListOverflow *current_free = this;
00133   StrListOverflow *next_free;
00134 
00135   while (current_free) {
00136     next_free = current_free->next;
00137     ats_free(current_free);
00138     current_free = next_free;
00139   }
00140 }
00141 
00142 void *
00143 StrListOverflow::alloc(int size, StrListOverflow ** new_heap_ptr)
00144 {
00145 
00146   if (size > (heap_size - heap_used)) {
00147     int new_heap_size = heap_size * 2;
00148 
00149     if (new_heap_size < size) {
00150       new_heap_size = INK_ALIGN(size, 2048);
00151       ink_release_assert(new_heap_size >= size);
00152     }
00153 
00154     ink_assert(next == NULL);
00155     *new_heap_ptr = next = create_heap(new_heap_size);
00156     return next->alloc(size, new_heap_ptr);
00157   }
00158 
00159   char *start = ((char *) this) + overflow_head_hdr_size;
00160   char *rval = start + heap_used;
00161   heap_used += size;
00162   ink_assert(heap_used <= heap_size);
00163   return (void *) rval;
00164 }
00165 
00166 StrListOverflow *
00167 StrListOverflow::create_heap(int user_size)
00168 {
00169   
00170   
00171   
00172   
00173   
00174   
00175   int total_size = overflow_head_hdr_size + user_size;
00176 
00177   StrListOverflow *o = (StrListOverflow *)ats_malloc(total_size);
00178   o->init();
00179   o->heap_size = user_size;
00180 
00181   return o;
00182 }