int main (int argc, char *argv[]) { guint64 block_size = 512, area_size = 1024 * 1024, n_blocks, repeats = 1000000; if (argc > 1) block_size = parse_memsize (argv[1]); else { usage(); block_size = 512; } if (argc > 2) area_size = parse_memsize (argv[2]); if (argc > 3) repeats = parse_memsize (argv[3]); if (argc > 4) g_slice_set_config (G_SLICE_CONFIG_COLOR_INCREMENT, parse_memsize (argv[4])); /* figure number of blocks from block and area size. * divide area by 3 because touch_mem() allocates 3 areas */ n_blocks = area_size / 3 / ALIGN (block_size, sizeof (gsize) * 2); /* basic sanity checks */ if (!block_size || !n_blocks || block_size >= area_size) { g_printerr ("Invalid arguments: block-size=%" G_GUINT64_FORMAT " memory-size=%" G_GUINT64_FORMAT "\n", block_size, area_size); usage(); return 1; } g_printerr ("Will allocate and touch %" G_GUINT64_FORMAT " blocks of %" G_GUINT64_FORMAT " bytes (= %" G_GUINT64_FORMAT " bytes) %" G_GUINT64_FORMAT " times with color increment: 0x%08" G_GINT64_MODIFIER "x\n", n_blocks, block_size, n_blocks * block_size, repeats, (guint64)g_slice_get_config (G_SLICE_CONFIG_COLOR_INCREMENT)); touch_mem (block_size, n_blocks, repeats); return 0; }
int main (int argc, char *argv[]) { guint seed32, *seedp = NULL; gboolean ccounters = FALSE, use_memchunks = FALSE; guint n_threads = 1; const gchar *mode = "slab allocator + magazine cache", *emode = " "; if (argc > 1) n_threads = g_ascii_strtoull (argv[1], NULL, 10); if (argc > 2) { guint i, l = strlen (argv[2]); for (i = 0; i < l; i++) switch (argv[2][i]) { case 'G': /* GLib mode */ g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, FALSE); g_slice_set_config (G_SLICE_CONFIG_BYPASS_MAGAZINES, FALSE); mode = "slab allocator + magazine cache"; break; case 'S': /* slab mode */ g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, FALSE); g_slice_set_config (G_SLICE_CONFIG_BYPASS_MAGAZINES, TRUE); mode = "slab allocator"; break; case 'M': /* malloc mode */ g_slice_set_config (G_SLICE_CONFIG_ALWAYS_MALLOC, TRUE); mode = "system malloc"; break; case 'O': /* old memchunks */ use_memchunks = TRUE; mode = "old memchunks"; break; case 'f': /* eager freeing */ g_slice_set_config (G_SLICE_CONFIG_WORKING_SET_MSECS, 0); clean_memchunks = TRUE; emode = " with eager freeing"; break; case 'c': /* print contention counters */ ccounters = TRUE; break; case '~': want_corruption = TRUE; /* force occasional corruption */ break; default: usage(); return 1; } } if (argc > 3) prime_size = g_ascii_strtoull (argv[3], NULL, 10); if (argc > 4) { seed32 = g_ascii_strtoull (argv[4], NULL, 10); seedp = &seed32; } if (argc <= 1) usage(); { gchar strseed[64] = "<random>"; GThread **threads; guint i; if (seedp) g_snprintf (strseed, 64, "%u", *seedp); g_print ("Starting %d threads allocating random blocks <= %u bytes with seed=%s using %s%s\n", n_threads, prime_size, strseed, mode, emode); threads = g_alloca (sizeof(GThread*) * n_threads); if (!use_memchunks) for (i = 0; i < n_threads; i++) threads[i] = g_thread_create (test_sliced_mem_thread, seedp, TRUE, NULL); else { for (i = 0; i < n_threads; i++) threads[i] = g_thread_create (test_memchunk_thread, seedp, TRUE, NULL); } for (i = 0; i < n_threads; i++) g_thread_join (threads[i]); if (ccounters) { guint n, n_chunks = g_slice_get_config (G_SLICE_CONFIG_CHUNK_SIZES); g_print (" ChunkSize | MagazineSize | Contention\n"); for (i = 0; i < n_chunks; i++) { gint64 *vals = g_slice_get_config_state (G_SLICE_CONFIG_CONTENTION_COUNTER, i, &n); g_print (" %9" G_GINT64_FORMAT " | %9" G_GINT64_FORMAT " | %9" G_GINT64_FORMAT "\n", vals[0], vals[2], vals[1]); g_free (vals); } } else g_print ("Done.\n"); return 0; } }