Changeset 2062 in kBuild for trunk/src/kmk/misc.c
- Timestamp:
- Nov 9, 2008 10:18:54 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/misc.c
r2057 r2062 1162 1162 } 1163 1163 1164 #ifdef CONFIG_WITH_ALLOC_CACHES1165 1166 /* Free am item.1167 This was not inlined because of aliasing issues arrising with GCC. */1168 void1169 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 #endif1179 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 #endif1206 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 void1218 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 else1233 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 void1254 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 void1266 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 else1287 {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 #else1308 /* and statistics */1309 cache->alloc_count += eat->alloc_count;1310 cache->free_count += eat->free_count;1311 #endif1312 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 else1318 {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 void1333 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 void1347 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 1357 1164 #ifdef CONFIG_WITH_PRINT_STATS_SWITCH 1358 1165 /* Print heap statistics if supported by the platform. */
Note:
See TracChangeset
for help on using the changeset viewer.