VirtualBox

Changeset 2062 in kBuild for trunk/src/kmk/misc.c


Ignore:
Timestamp:
Nov 9, 2008 10:18:54 PM (16 years ago)
Author:
bird
Message:

kmk: Moved the alloccache code into a separate file because it seems gcc has ends up in some inlining / aliasing trouble in free_dep_chain (alloccache_free is suspected to be inlined) with gcc 4.3.2 on S/390.

File:
1 edited

Legend:

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

    r2057 r2062  
    11621162}
    11631163
    1164 #ifdef CONFIG_WITH_ALLOC_CACHES
    1165 
    1166 /* Free am item.
    1167    This was not inlined because of aliasing issues arrising with GCC. */
    1168 void
    1169 alloccache_free (struct alloccache *cache, void *item)
    1170 {
    1171   struct alloccache_free_ent *f = (struct alloccache_free_ent *)item;
    1172 #if 0 /*ndef NDEBUG*/
    1173   struct alloccache_free_ent *c;
    1174   unsigned int i = 0;
    1175   for (c = cache->free_head; c != NULL; c = c->next, i++)
    1176     MY_ASSERT_MSG (c != f && i < 0x10000000,
    1177                    ("i=%u total_count=%u\n", i, cache->total_count));
    1178 #endif
    1179 
    1180   f->next = cache->free_head;
    1181   cache->free_head = f;
    1182   MAKE_STATS(cache->free_count++;);
    1183 }
    1184 
    1185 /* Default allocator. */
    1186 static void *
    1187 alloccache_default_grow_alloc(void *ignore, unsigned int size)
    1188 {
    1189   return xmalloc (size);
    1190 }
    1191 
    1192 /* Worker for growing the cache. */
    1193 struct alloccache_free_ent *
    1194 alloccache_alloc_grow (struct alloccache *cache)
    1195 {
    1196   void *item;
    1197   unsigned int items = (64*1024 - 32) / cache->size;
    1198   cache->free_start  = cache->grow_alloc (cache->grow_arg, items * cache->size);
    1199   cache->free_end    = cache->free_start + items * cache->size;
    1200   cache->total_count+= items;
    1201 
    1202 #ifndef NDEBUG /* skip the first item so the heap can detect free(). */
    1203   cache->total_count--;
    1204   cache->free_start += cache->size;
    1205 #endif
    1206 
    1207   item = cache->free_start;
    1208   cache->free_start += cache->size;
    1209   /* caller counts */
    1210   return (struct alloccache_free_ent *)item;
    1211 }
    1212 
    1213 /* List of alloc caches, for printing. */
    1214 static struct alloccache *alloccache_head = NULL;
    1215 
    1216 /* Initializes an alloc cache */
    1217 void
    1218 alloccache_init (struct alloccache *cache, unsigned int size, const char *name,
    1219                  void *(*grow_alloc)(void *grow_arg, unsigned int size), void *grow_arg)
    1220 {
    1221   unsigned act_size;
    1222 
    1223   /* ensure OK alignment and min sizeof (struct alloccache_free_ent). */
    1224   if (size <= sizeof (struct alloccache_free_ent))
    1225     act_size = sizeof (struct alloccache_free_ent);
    1226   else if (size <= 32)
    1227     {
    1228       act_size = 4;
    1229       while (act_size < size)
    1230         act_size <<= 1;
    1231     }
    1232   else
    1233     act_size = (size + 31U) & ~(size_t)31;
    1234 
    1235   /* align the structure. */
    1236   cache->free_start  = NULL;
    1237   cache->free_end    = NULL;
    1238   cache->free_head   = NULL;
    1239   cache->size        = act_size;
    1240   cache->total_count = 0;
    1241   cache->alloc_count = 0;
    1242   cache->free_count  = 0;
    1243   cache->name        = name;
    1244   cache->grow_arg    = grow_arg;
    1245   cache->grow_alloc  = grow_alloc ? grow_alloc : alloccache_default_grow_alloc;
    1246 
    1247   /* link it. */
    1248   cache->next        = alloccache_head;
    1249   alloccache_head    = cache;
    1250 }
    1251 
    1252 /* Terminate an alloc cache, free all the memory it contains. */
    1253 void
    1254 alloccache_term (struct alloccache *cache,
    1255                  void (*term_free)(void *term_arg, void *ptr, unsigned int size), void *term_arg)
    1256 {
    1257     /*cache->size = 0;*/
    1258     (void)cache;
    1259     (void)term_free;
    1260     (void)term_arg;
    1261     /* FIXME: Implement memory segment tracking and cleanup. */
    1262 }
    1263 
    1264 /* Joins to caches, unlinking the 2nd one. */
    1265 void
    1266 alloccache_join (struct alloccache *cache, struct alloccache *eat)
    1267 {
    1268   assert (cache->size == eat->size);
    1269 
    1270 #if 0 /* probably a waste of time */ /* FIXME: Optimize joining, avoid all list walking. */
    1271   /* add the free list... */
    1272   if (eat->free_head)
    1273     {
    1274      unsigned int eat_in_use = eat->alloc_count - eat->free_count;
    1275      unsigned int dst_in_use = cache->alloc_count - cache->free_count;
    1276      if (!cache->free_head)
    1277        cache->free_head = eat->free_head;
    1278      else if (eat->total_count - eat_in_use < cache->total_count - dst_ins_use)
    1279        {
    1280          struct alloccache_free_ent *last = eat->free_head;
    1281          while (last->next)
    1282            last = last->next;
    1283          last->next = cache->free_head;
    1284          cache->free_head = eat->free_head;
    1285        }
    1286      else
    1287        {
    1288          struct alloccache_free_ent *last = cache->free_head;
    1289          while (last->next)
    1290            last = last->next;
    1291          last->next = eat->free_head;
    1292        }
    1293     }
    1294 
    1295   /* ... and the free space. */
    1296   while (eat->free_start != eat->free_end)
    1297     {
    1298       struct alloccache_free_ent *f = (struct alloccache_free_ent *)eat->free_start;
    1299       eat->free_start += eat->size;
    1300       f->next = cache->free_head;
    1301       cache->free_head = f;
    1302     }
    1303 
    1304   /* and statistics */
    1305   cache->alloc_count += eat->alloc_count;
    1306   cache->free_count  += eat->free_count;
    1307 #else
    1308   /* and statistics */
    1309   cache->alloc_count += eat->alloc_count;
    1310   cache->free_count  += eat->free_count;
    1311 #endif
    1312   cache->total_count += eat->total_count;
    1313 
    1314   /* unlink and disable the eat cache */
    1315   if (alloccache_head == eat)
    1316     alloccache_head = eat->next;
    1317   else
    1318     {
    1319       struct alloccache *cur = alloccache_head;
    1320       while (cur->next != eat)
    1321         cur = cur->next;
    1322       assert (cur && cur->next == eat);
    1323       cur->next = eat->next;
    1324     }
    1325 
    1326   eat->size = 0;
    1327   eat->free_end = eat->free_start = NULL;
    1328   eat->free_head = NULL;
    1329 }
    1330 
    1331 /* Print one alloc cache. */
    1332 void
    1333 alloccache_print (struct alloccache *cache)
    1334 {
    1335   printf (_("\n# Alloc Cache: %s\n"
    1336               "#  Items: size = %-3u  total = %-6u"),
    1337           cache->name, cache->size, cache->total_count);
    1338   MAKE_STATS(printf (_("  in-use = %-6lu"),
    1339                      cache->alloc_count - cache->free_count););
    1340   MAKE_STATS(printf (_("\n#         alloc calls = %-7lu  free calls = %-7lu"),
    1341                      cache->alloc_count, cache->free_count););
    1342   printf ("\n");
    1343 }
    1344 
    1345 /* Print all alloc caches. */
    1346 void
    1347 alloccache_print_all (void)
    1348 {
    1349   struct alloccache *cur;
    1350   puts ("");
    1351   for (cur = alloccache_head; cur; cur = cur->next)
    1352     alloccache_print (cur);
    1353 }
    1354 
    1355 #endif /* CONFIG_WITH_ALLOC_CACHES */
    1356 
    13571164#ifdef CONFIG_WITH_PRINT_STATS_SWITCH
    13581165/* Print heap statistics if supported by the platform. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette