diff options
author | Tim Janik <timj@imendio.com> | 2006-12-28 11:50:43 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 2006-12-28 11:50:43 +0000 |
commit | 1bd89934513921526da2d9e6463faeda8e4d76a7 (patch) | |
tree | 0e96fac634269139467ad8b1ead67d3c1b3b9267 /tests | |
parent | 636dae32c30dfacde754b9f6e6cb1bf29815bab8 (diff) |
implemented static debugging hash-tree to validate slice adresses and
Thu Dec 28 12:50:31 2006 Tim Janik <timj@imendio.com>
* glib/gslice.h, glib/gslice.c: implemented static debugging
hash-tree to validate slice adresses and sizes with G_SLICE=debug-blocks.
use abort() to exit in mem_error() to allow catching of these in gdb.
abort programs with a descriptive error message if g_thread_init() is
called after GSlice was in use. previously this just silently corrupted
the magazines.
* glib/ghash.c (struct _GHashNode): reordered fields to keep 8-byte
pointer alignment on 64bit systems and request smaller slice sizes
on 32bit systems.
* tests/slice-test.c: support '~' option flag to introduce slice
allocation/release corruption with a significant probability. this
allowes testing of G_SLICE=debug-blocks.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/slice-test.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/tests/slice-test.c b/tests/slice-test.c index e3e696222..b739650d1 100644 --- a/tests/slice-test.c +++ b/tests/slice-test.c @@ -26,6 +26,7 @@ static guint prime_size = 1021; // 769; // 509 static gboolean clean_memchunks = FALSE; static guint number_of_blocks = 10000; /* total number of blocks allocated */ static guint number_of_repetitions = 10000; /* number of alloc+free repetitions */ +static gboolean want_corruption = FALSE; /* --- old memchunk prototypes (memchunks.c) --- */ void old_mem_chunks_init (void); @@ -47,6 +48,18 @@ void old_mem_chunk_info (void); #endif /* --- functions --- */ +static inline int +corruption (void) +{ + if (G_UNLIKELY (want_corruption)) + { + /* corruption per call likelyness is about 1:4000000 */ + guint32 r = g_random_int() % 8000009; + return r == 277 ? +1 : r == 281 ? -1 : 0; + } + return 0; +} + static inline gpointer memchunk_alloc (GMemChunk **memchunkp, guint size) @@ -153,31 +166,31 @@ test_sliced_mem_thread (gpointer data) ss[i] = quick_rand32() % prime_size; /* allocate number_of_blocks blocks */ for (i = 0; i < number_of_blocks; i++) - ps[i] = g_slice_alloc (ss[i]); + ps[i] = g_slice_alloc (ss[i] + corruption()); for (j = 0; j < number_of_repetitions; j++) { /* free number_of_blocks/2 blocks */ for (i = 0; i < number_of_blocks; i += 2) - g_slice_free1 (ss[i], ps[i]); + g_slice_free1 (ss[i] + corruption(), ps[i] + corruption()); /* allocate number_of_blocks/2 blocks with new sizes */ for (i = 0; i < number_of_blocks; i += 2) { ss[i] = quick_rand32() % prime_size; - ps[i] = g_slice_alloc (ss[i]); + ps[i] = g_slice_alloc (ss[i] + corruption()); } } /* free number_of_blocks blocks */ for (i = 0; i < number_of_blocks; i++) - g_slice_free1 (ss[i], ps[i]); + g_slice_free1 (ss[i] + corruption(), ps[i] + corruption()); /* alloc and free many equally sized chunks in a row */ for (i = 0; i < number_of_repetitions; i++) { guint sz = quick_rand32() % prime_size; guint k = number_of_blocks / 100; for (j = 0; j < k; j++) - ps[j] = g_slice_alloc (sz); + ps[j] = g_slice_alloc (sz + corruption()); for (j = 0; j < k; j++) - g_slice_free1 (sz, ps[j]); + g_slice_free1 (sz + corruption(), ps[j] + corruption()); } g_free (ps); g_free (ss); @@ -188,7 +201,7 @@ test_sliced_mem_thread (gpointer data) static void usage (void) { - g_print ("Usage: slice-test [n_threads] [G|S|M|O][f][c] [maxblocksize] [seed]\n"); + g_print ("Usage: slice-test [n_threads] [G|S|M|O][f][c][~] [maxblocksize] [seed]\n"); } int @@ -233,6 +246,9 @@ main (int argc, case 'c': /* print contention counters */ ccounters = TRUE; break; + case '~': + want_corruption = TRUE; /* force occasional corruption */ + break; default: usage(); return 1; |