summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorTim Janik <timj@imendio.com>2006-12-28 11:50:43 +0000
committerTim Janik <timj@src.gnome.org>2006-12-28 11:50:43 +0000
commit1bd89934513921526da2d9e6463faeda8e4d76a7 (patch)
tree0e96fac634269139467ad8b1ead67d3c1b3b9267 /tests
parent636dae32c30dfacde754b9f6e6cb1bf29815bab8 (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.c30
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;