Changeset 1863 for trunk/src/kmk/misc.c


Ignore:
Timestamp:
Oct 14, 2008, 11:46:23 AM (17 years ago)
Author:
bird
Message:

kmk: Allocation caches for nameseq, dep and idep. next: variable.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/misc.c

    r1862 r1863  
    709709
    710710
    711 #ifdef KMK
    712 /* Cache free struct dep to save time in free during snap_deps.
    713    free is esp. slow on darwin for some reason. */
    714 static struct dep *free_deps = NULL;
    715 static struct dep *free_deps_start = NULL;
    716 static struct dep *free_deps_end = NULL;
    717 
    718 static struct dep *
    719 alloc_dep_int (void)
    720 {
    721   struct dep *d = free_deps;
    722   if (MY_PREDICT_TRUE(d))
    723     free_deps = d->next;
    724   else if (free_deps_start != free_deps_end)
    725     d = free_deps_start++;
    726   else
    727     {
    728       /* allocate another chunk block. */
    729       free_deps_start = xmalloc (sizeof (struct dep) * 256);
    730       free_deps_end = free_deps_start + 256;
    731       d = free_deps_start++;
    732     }
    733   return d;
    734 }
    735 
    736 static void
    737 free_dep_int (struct dep *d)
    738 {
    739   d->next = free_deps;
    740   free_deps = d;
    741 }
    742 #endif /* KMK */
    743 
    744 
    745711/* Allocate a new `struct dep' with all fields initialized to 0.   */
    746712
     
    748714alloc_dep ()
    749715{
    750 #ifndef KMK
     716#ifndef CONFIG_WITH_ALLOC_CACHES
    751717  struct dep *d = xmalloc (sizeof (struct dep));
    752 #else
    753   struct dep *d = alloc_dep_int ();
    754 #endif
    755718  memset (d, '\0', sizeof (struct dep));
    756719  return d;
     720#else
     721  return (struct dep *) alloccache_calloc (&dep_cache);
     722#endif
    757723}
    758724
     
    763729free_dep (struct dep *d)
    764730{
    765 #ifndef KMK
     731#ifndef CONFIG_WITH_ALLOC_CACHES
    766732  free (d);
    767733#else
    768   free_dep_int (d);
     734  alloccache_free (&dep_cache, d);
    769735#endif
    770736}
     
    781747  while (d != 0)
    782748    {
    783 #ifndef KMK
     749#ifndef CONFIG_WITH_ALLOC_CACHES
    784750      struct dep *c = xmalloc (sizeof (struct dep));
    785751#else
    786       struct dep *c = alloc_dep_int ();
     752      struct dep *c = (struct dep *) alloccache_alloc (&dep_cache);
    787753#endif
    788754      memcpy (c, d, sizeof (struct dep));
     
    809775      struct dep *df = d;
    810776      d = d->next;
    811 #ifndef KMK
     777#ifndef CONFIG_WITH_ALLOC_CACHES
    812778      free_dep (df);
    813779#else
    814       free_dep_int (df);
     780      alloccache_free (&dep_cache, df);
    815781#endif
    816782    }
     
    827793      struct nameseq *t = ns;
    828794      ns = ns->next;
     795#ifndef CONFIG_WITH_ALLOC_CACHES
    829796      free (t);
     797#else
     798      alloccache_free (&nameseq_cache, t);
     799#endif
    830800    }
    831801}
     
    11911161#endif
    11921162
     1163
     1164#ifdef CONFIG_WITH_ALLOC_CACHES
     1165
     1166/* Default allocator. */
     1167static void *
     1168alloccache_default_grow_alloc(void *ignore, unsigned int size)
     1169{
     1170  return xmalloc (size);
     1171}
     1172
     1173/* Worker for growing the cache. */
     1174struct alloccache_free_ent *
     1175alloccache_alloc_grow (struct alloccache *cache)
     1176{
     1177  void *item;
     1178  unsigned int items = (64*1024 - 32) / cache->size;
     1179  cache->free_start  = cache->grow_alloc (cache->grow_arg, items * cache->size);
     1180  cache->free_end    = cache->free_start + items * cache->size;
     1181  cache->total_count+= items;
     1182
     1183#ifndef NDEBUG /* skip the first item so the heap can detect free(). */
     1184  cache->total_count--;
     1185  cache->free_start += cache->size;
     1186#endif
     1187
     1188  item = cache->free_start;
     1189  cache->free_start += cache->size;
     1190  /* caller counts */
     1191  return (struct alloccache_free_ent *)item;
     1192}
     1193
     1194/* List of alloc caches, for printing. */
     1195static struct alloccache *alloccache_head = NULL;
     1196
     1197/* Initializes an alloc cache */
     1198void
     1199alloccache_init (struct alloccache *cache, unsigned int size, const char *name,
     1200                 void *(*grow_alloc)(void *grow_arg, unsigned int size), void *grow_arg)
     1201{
     1202  /* ensure aligned and min sizeof (struct alloccache_free_ent). */
     1203  if (size & (sizeof (void *) - 1))
     1204    size += sizeof (void *) - (size & (sizeof (void *) - 1));
     1205
     1206  cache->free_start  = NULL;
     1207  cache->free_end    = NULL;
     1208  cache->free_head   = NULL;
     1209  cache->size        = size;
     1210  cache->alloc_count = 0;
     1211  cache->total_count = 0;
     1212  cache->name        = name;
     1213  cache->grow_arg    = grow_arg;
     1214  cache->grow_alloc  = grow_alloc ? grow_alloc : alloccache_default_grow_alloc;
     1215
     1216  cache->next        = alloccache_head;
     1217  alloccache_head    = cache;
     1218}
     1219
     1220/* Joins to caches, unlinking the 2nd one. */
     1221void
     1222alloccache_join (struct alloccache *cache, struct alloccache *eat)
     1223{
     1224  assert (cache->size == eat->size);
     1225
     1226#if 0 /* probably a waste of time */ /* FIXME: Optimize joining, avoid all list walking. */
     1227  /* add the free list... */
     1228  if (eat->free_head)
     1229    {
     1230     if (!cache->free_head)
     1231       cache->free_head = eat->free_head;
     1232     else if (eat->total_count - eat->alloc_count < cache->total_count - cache->alloc_count)
     1233       {
     1234         struct alloccache_free_ent *last = eat->free_head;
     1235         while (last->next)
     1236           last = last->next;
     1237         last->next = cache->free_head;
     1238         cache->free_head = eat->free_head;
     1239       }
     1240     else
     1241       {
     1242         struct alloccache_free_ent *last = cache->free_head;
     1243         while (last->next)
     1244           last = last->next;
     1245         last->next = eat->free_head;
     1246       }
     1247    }
     1248
     1249  /* ... and the free space. */
     1250  while (eat->free_start != eat->free_end)
     1251    {
     1252      struct alloccache_free_ent *f = (struct alloccache_free_ent *)eat->free_start;
     1253      eat->free_start += eat->size;
     1254      f->next = cache->free_head;
     1255      cache->free_head = f;
     1256    }
     1257
     1258  /* and statistics */
     1259  cache->alloc_count += eat->alloc_count;
     1260  cache->total_count += eat->total_count;
     1261#else
     1262  /* and statistics */
     1263  cache->alloc_count += eat->alloc_count;
     1264  cache->total_count += eat->alloc_count;
     1265#endif
     1266
     1267  /* unlink and disable the eat cache */
     1268  if (alloccache_head == eat)
     1269    alloccache_head = eat->next;
     1270  else
     1271    {
     1272      struct alloccache *cur = alloccache_head;
     1273      while (cur->next != eat)
     1274        cur = cur->next;
     1275      assert (cur && cur->next == eat);
     1276      cur->next = eat->next;
     1277    }
     1278
     1279  eat->size = 0;
     1280  eat->free_end = eat->free_start = NULL;
     1281  eat->free_head = NULL;
     1282}
     1283
     1284/* Print one alloc cache. */
     1285void
     1286alloccache_print (struct alloccache *cache)
     1287{
     1288  printf (_("\n# Alloc Cache: %s item size: %u  alloc: %d  total: %u\n"),
     1289          cache->name, cache->size, (int)cache->alloc_count, cache->total_count);
     1290}
     1291
     1292/* Print all alloc caches. */
     1293void
     1294alloccache_print_all (void)
     1295{
     1296  struct alloccache *cur;
     1297  for (cur = alloccache_head; cur; cur = cur->next)
     1298    alloccache_print (cur);
     1299}
     1300
     1301#endif /* CONFIG_WITH_ALLOC_CACHES */
Note: See TracChangeset for help on using the changeset viewer.