pixman: Branch 'master' - 5 commits

Siarhei Siamashka siamashka at kemper.freedesktop.org
Thu Dec 6 07:34:20 PST 2012


 demos/Makefile.am           |    3 
 test/Makefile.sources       |    3 
 test/affine-test.c          |  111 +++++++++-----------
 test/alpha-loop.c           |   11 +-
 test/alphamap.c             |    2 
 test/blitters-test.c        |   60 ++++-------
 test/combiner-test.c        |    4 
 test/composite-traps-test.c |   58 +++++-----
 test/composite.c            |   12 +-
 test/glyph-test.c           |   94 ++++++++---------
 test/prng-test.c            |  172 +++++++++++++++++++++++++++++++
 test/region-contains-test.c |   28 ++---
 test/region-test.c          |   10 +
 test/rotate-test.c          |   14 +-
 test/scaling-helpers-test.c |    9 -
 test/scaling-test.c         |  129 +++++++++++------------
 test/stress-test.c          |  112 ++++++++++----------
 test/utils-prng.c           |  238 ++++++++++++++++++++++++++++++++++++++++++++
 test/utils-prng.h           |  168 +++++++++++++++++++++++++++++++
 test/utils.c                |   25 +---
 test/utils.h                |   58 +++++-----
 21 files changed, 941 insertions(+), 380 deletions(-)

New commits:
commit ebedd9a2ad8e841cd8323838b5136657d9ebb988
Author: Siarhei Siamashka <siarhei.siamashka at gmail.com>
Date:   Sun Nov 25 02:59:25 2012 +0200

    test: Get rid of the obsolete 'prng_rand_N' and 'prng_rand_u32'
    
    They are the same as 'prng_rand_n' and 'prng_rand'

diff --git a/test/affine-test.c b/test/affine-test.c
index fc2e05b..f60ec14 100644
--- a/test/affine-test.c
+++ b/test/affine-test.c
@@ -99,18 +99,18 @@ test_composite (int      testnum,
 
     if (prng_rand_n (3) > 0)
     {
-	scale_x = -65536 * 3 + prng_rand_N (65536 * 6);
+	scale_x = -65536 * 3 + prng_rand_n (65536 * 6);
 	if (prng_rand_n (2))
-	    scale_y = -65536 * 3 + prng_rand_N (65536 * 6);
+	    scale_y = -65536 * 3 + prng_rand_n (65536 * 6);
 	else
 	    scale_y = scale_x;
 	pixman_transform_init_scale (&transform, scale_x, scale_y);
     }
     if (prng_rand_n (3) > 0)
     {
-	translate_x = -65536 * 3 + prng_rand_N (6 * 65536);
+	translate_x = -65536 * 3 + prng_rand_n (6 * 65536);
 	if (prng_rand_n (2))
-	    translate_y = -65536 * 3 + prng_rand_N (6 * 65536);
+	    translate_y = -65536 * 3 + prng_rand_n (6 * 65536);
 	else
 	    translate_y = translate_x;
 	pixman_transform_translate (&transform, NULL, translate_x, translate_y);
@@ -142,8 +142,8 @@ test_composite (int      testnum,
 	    break;
 	default:
 	    /* arbitrary rotation */
-	    c = prng_rand_N (2 * 65536) - 65536;
-	    s = prng_rand_N (2 * 65536) - 65536;
+	    c = prng_rand_n (2 * 65536) - 65536;
+	    s = prng_rand_n (2 * 65536) - 65536;
 	    break;
 	}
 	pixman_transform_rotate (&transform, NULL, c, s);
diff --git a/test/combiner-test.c b/test/combiner-test.c
index 7d6feda..01f63a5 100644
--- a/test/combiner-test.c
+++ b/test/combiner-test.c
@@ -67,7 +67,7 @@ static const pixman_op_t op_list[] =
 static float
 rand_float (void)
 {
-    uint32_t u = prng_rand_u32();
+    uint32_t u = prng_rand();
 
     return *(float *)&u;
 }
diff --git a/test/composite-traps-test.c b/test/composite-traps-test.c
index 5a4a921..2983eae 100644
--- a/test/composite-traps-test.c
+++ b/test/composite-traps-test.c
@@ -37,7 +37,7 @@ destroy_bits (pixman_image_t *image, void *data)
 static pixman_fixed_t
 random_fixed (int n)
 {
-    return prng_rand_N (n << 16);
+    return prng_rand_n (n << 16);
 }
 
 /*
diff --git a/test/glyph-test.c b/test/glyph-test.c
index 7edb3be..1811add 100644
--- a/test/glyph-test.c
+++ b/test/glyph-test.c
@@ -126,10 +126,10 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
     {
 	pixman_color_t color;
 
-	color.alpha = prng_rand_u32();
-	color.red = prng_rand_u32();
-	color.green = prng_rand_u32();
-	color.blue = prng_rand_u32();
+	color.alpha = prng_rand();
+	color.red = prng_rand();
+	color.green = prng_rand();
+	color.blue = prng_rand();
 
 	return pixman_image_create_solid_fill (&color);
     }
diff --git a/test/region-contains-test.c b/test/region-contains-test.c
index c757347..096e651 100644
--- a/test/region-contains-test.c
+++ b/test/region-contains-test.c
@@ -15,10 +15,10 @@ make_random_region (pixman_region32_t *region)
 	int32_t x, y;
 	uint32_t w, h;
 
-	x = (int32_t)prng_rand_u32() >> 2;
-	y = (int32_t)prng_rand_u32() >> 2;
-	w = prng_rand_u32() >> 2;
-	h = prng_rand_u32() >> 2;
+	x = (int32_t)prng_rand() >> 2;
+	y = (int32_t)prng_rand() >> 2;
+	w = prng_rand() >> 2;
+	h = prng_rand() >> 2;
 
 	pixman_region32_union_rect (region, region, x, y, w, h);
     }
@@ -65,9 +65,9 @@ random_coord (pixman_region32_t *region, pixman_bool_t x)
     switch (prng_rand_n (5))
     {
     case 0:
-	return begin - prng_rand_u32();
+	return begin - prng_rand();
     case 1:
-	return end + prng_rand_u32 ();
+	return end + prng_rand ();
     case 2:
 	return end;
     case 3:
@@ -116,9 +116,9 @@ test_region_contains_rectangle (int i, int verbose)
     make_random_region (&region);
 
     box.x1 = random_coord (&region, TRUE);
-    box.x2 = box.x1 + prng_rand_u32 ();
+    box.x2 = box.x1 + prng_rand ();
     box.y1 = random_coord (&region, FALSE);
-    box.y2 = box.y1 + prng_rand_u32 ();
+    box.y2 = box.y1 + prng_rand ();
 
     if (verbose)
     {
diff --git a/test/scaling-helpers-test.c b/test/scaling-helpers-test.c
index 2685ae1..cd5ace0 100644
--- a/test/scaling-helpers-test.c
+++ b/test/scaling-helpers-test.c
@@ -57,10 +57,10 @@ main (void)
     {
 	int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1;
 	int32_t left_pad2, left_tz2, width2, right_tz2, right_pad2;
-	pixman_fixed_t vx = prng_rand_N(10000 << 16) - (3000 << 16);
-	int32_t width = prng_rand_N(10000);
-	int32_t source_image_width = prng_rand_N(10000) + 1;
-	pixman_fixed_t unit_x = prng_rand_N(10 << 16) + 1;
+	pixman_fixed_t vx = prng_rand_n(10000 << 16) - (3000 << 16);
+	int32_t width = prng_rand_n(10000);
+	int32_t source_image_width = prng_rand_n(10000) + 1;
+	pixman_fixed_t unit_x = prng_rand_n(10 << 16) + 1;
 	width1 = width2 = width;
 
 	bilinear_pad_repeat_get_scanline_bounds_ref (source_image_width,
diff --git a/test/scaling-test.c b/test/scaling-test.c
index 44f851c..64c12dd 100644
--- a/test/scaling-test.c
+++ b/test/scaling-test.c
@@ -161,10 +161,10 @@ test_composite (int      testnum,
 
     if (prng_rand_n (4) > 0)
     {
-	scale_x = -32768 * 3 + prng_rand_N (65536 * 5);
-	scale_y = -32768 * 3 + prng_rand_N (65536 * 5);
-	translate_x = prng_rand_N (65536);
-	translate_y = prng_rand_N (65536);
+	scale_x = -32768 * 3 + prng_rand_n (65536 * 5);
+	scale_y = -32768 * 3 + prng_rand_n (65536 * 5);
+	translate_x = prng_rand_n (65536);
+	translate_y = prng_rand_n (65536);
 	pixman_transform_init_scale (&transform, scale_x, scale_y);
 	pixman_transform_translate (&transform, NULL, translate_x, translate_y);
 	pixman_image_set_transform (src_img, &transform);
@@ -172,10 +172,10 @@ test_composite (int      testnum,
 
     if (prng_rand_n (2) > 0)
     {
-	mask_scale_x = -32768 * 3 + prng_rand_N (65536 * 5);
-	mask_scale_y = -32768 * 3 + prng_rand_N (65536 * 5);
-	mask_translate_x = prng_rand_N (65536);
-	mask_translate_y = prng_rand_N (65536);
+	mask_scale_x = -32768 * 3 + prng_rand_n (65536 * 5);
+	mask_scale_y = -32768 * 3 + prng_rand_n (65536 * 5);
+	mask_translate_x = prng_rand_n (65536);
+	mask_translate_y = prng_rand_n (65536);
 	pixman_transform_init_scale (&transform, mask_scale_x, mask_scale_y);
 	pixman_transform_translate (&transform, NULL, mask_translate_x, mask_translate_y);
 	pixman_image_set_transform (mask_img, &transform);
diff --git a/test/stress-test.c b/test/stress-test.c
index 8b99904..ee55c21 100644
--- a/test/stress-test.c
+++ b/test/stress-test.c
@@ -96,7 +96,7 @@ get_size (void)
 	return 65536;
 
     case 7:
-	return prng_rand_N (64000) + 63000;
+	return prng_rand_n (64000) + 63000;
     }
 }
 
@@ -164,7 +164,7 @@ real_writer (void *src, uint32_t value, int size)
 static uint32_t
 fake_reader (const void *src, int size)
 {
-    uint32_t r = prng_rand_u32 ();
+    uint32_t r = prng_rand ();
 
     assert (size == 1 || size == 2 || size == 4);
 
@@ -184,7 +184,7 @@ log_rand (void)
 
     mask = (1 << prng_rand_n (10)) - 1;
 
-    return (prng_rand_u32 () & mask) - (mask >> 1);
+    return (prng_rand () & mask) - (mask >> 1);
 }
 
 static int32_t
@@ -334,7 +334,7 @@ create_random_bits_image (void)
 	    int i;
 
 	    for (i = 0; i < width * height; ++i)
-		coefficients[i + 2] = prng_rand_u32();
+		coefficients[i + 2] = prng_rand();
 
 	    coefficients[0] = width << 16;
 	    coefficients[1] = height << 16;
@@ -508,22 +508,22 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
 	    {
 	    case 0:
 		/* rotation */
-		c = prng_rand_N (2 * 65536) - 65536;
-		s = prng_rand_N (2 * 65536) - 65536;
+		c = prng_rand_n (2 * 65536) - 65536;
+		s = prng_rand_n (2 * 65536) - 65536;
 		pixman_transform_rotate (&xform, NULL, c, s);
 		break;
 
 	    case 1:
 		/* translation */
-		tx = prng_rand_u32();
-		ty = prng_rand_u32();
+		tx = prng_rand();
+		ty = prng_rand();
 		pixman_transform_translate (&xform, NULL, tx, ty);
 		break;
 
 	    case 2:
 		/* scale */
-		sx = prng_rand_u32();
-		sy = prng_rand_u32();
+		sx = prng_rand();
+		sy = prng_rand();
 		pixman_transform_scale (&xform, NULL, sx, sy);
 		break;
 
@@ -533,7 +533,7 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
 		    /* random */
 		    for (i = 0; i < 3; ++i)
 			for (j = 0; j < 3; ++j)
-			    xform.matrix[i][j] = prng_rand_u32();
+			    xform.matrix[i][j] = prng_rand();
 		    break;
 		}
 		else if (prng_rand_n (16) == 0)
diff --git a/test/utils.c b/test/utils.c
index dd0e556..66c8dcb 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -682,7 +682,7 @@ get_random_seed (void)
     t.d = gettime();
     prng_srand (t.u32);
 
-    return prng_rand_u32 ();
+    return prng_rand ();
 }
 
 #ifdef HAVE_SIGACTION
diff --git a/test/utils.h b/test/utils.h
index f054887..78cf0d1 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -46,18 +46,6 @@ prng_rand_n (int max)
     return prng_rand () % max;
 }
 
-static inline uint32_t
-prng_rand_N (int max)
-{
-    return prng_rand () % max;
-}
-
-static inline uint32_t
-prng_rand_u32 (void)
-{
-    return prng_rand ();
-}
-
 static inline void
 prng_randmemset (void *buffer, size_t size, prng_randmemset_flags_t flags)
 {
commit b31a696263f1ae9aebb9bb21b93a0c15453bf611
Author: Siarhei Siamashka <siarhei.siamashka at gmail.com>
Date:   Sun Nov 25 02:50:35 2012 +0200

    test: Switch to the new PRNG instead of old LCG
    
    Wallclock time for running pixman "make check" (compile time not included):
    
    ----------------------------+----------------+-----------------------------+
                                | old PRNG (LCG) |   new PRNG (Bob Jenkins)    |
           Processor type       +----------------+------------+----------------+
                                |    gcc 4.5     |  gcc 4.5   | gcc 4.7 (simd) |
    ----------------------------+----------------+------------+----------------+
    quad Intel Core i7  @2.8GHz |    0m49.494s   |  0m43.722s |    0m37.560s   |
    dual ARM Cortex-A15 @1.7GHz |     5m8.465s   |  4m37.375s |    3m45.819s   |
         IBM Cell PPU   @3.2GHz |    23m0.821s   | 20m38.316s |   16m37.513s   |
    ----------------------------+----------------+------------+----------------+
    
    But some tests got a particularly large boost. For example benchmarking and
    profiling blitters-test on Core i7:
    
    === before ===
    
    $ time ./blitters-test
    
    real    0m10.907s
    user    0m55.650s
    sys     0m0.000s
    
      70.45%  blitters-test  blitters-test       [.] create_random_image
      15.81%  blitters-test  blitters-test       [.] compute_crc32_for_image_internal
       2.26%  blitters-test  blitters-test       [.] _pixman_implementation_lookup_composite
       1.07%  blitters-test  libc-2.15.so        [.] _int_free
       0.89%  blitters-test  libc-2.15.so        [.] malloc_consolidate
       0.87%  blitters-test  libc-2.15.so        [.] _int_malloc
       0.75%  blitters-test  blitters-test       [.] combine_conjoint_general_u
       0.61%  blitters-test  blitters-test       [.] combine_disjoint_general_u
       0.40%  blitters-test  blitters-test       [.] test_composite
       0.31%  blitters-test  libc-2.15.so        [.] _int_memalign
       0.31%  blitters-test  blitters-test       [.] _pixman_bits_image_setup_accessors
       0.28%  blitters-test  libc-2.15.so        [.] malloc
    
    === after ===
    
    $ time ./blitters-test
    
    real    0m3.655s
    user    0m20.550s
    sys     0m0.000s
    
      41.77%  blitters-test.n  blitters-test.new  [.] compute_crc32_for_image_internal
      15.77%  blitters-test.n  blitters-test.new  [.] prng_randmemset_r
       6.15%  blitters-test.n  blitters-test.new  [.] _pixman_implementation_lookup_composite
       3.09%  blitters-test.n  libc-2.15.so       [.] _int_free
       2.68%  blitters-test.n  libc-2.15.so       [.] malloc_consolidate
       2.39%  blitters-test.n  libc-2.15.so       [.] _int_malloc
       2.27%  blitters-test.n  blitters-test.new  [.] create_random_image
       2.22%  blitters-test.n  blitters-test.new  [.] combine_conjoint_general_u
       1.52%  blitters-test.n  blitters-test.new  [.] combine_disjoint_general_u
       1.40%  blitters-test.n  blitters-test.new  [.] test_composite
       1.02%  blitters-test.n  blitters-test.new  [.] prng_srand_r
       1.00%  blitters-test.n  blitters-test.new  [.] _pixman_image_validate
       0.96%  blitters-test.n  blitters-test.new  [.] _pixman_bits_image_setup_accessors
       0.90%  blitters-test.n  libc-2.15.so       [.] malloc

diff --git a/demos/Makefile.am b/demos/Makefile.am
index f324f5f..96c43f0 100644
--- a/demos/Makefile.am
+++ b/demos/Makefile.am
@@ -6,7 +6,8 @@ AM_LDFLAGS = $(OPENMP_CFLAGS)
 LDADD = $(top_builddir)/pixman/libpixman-1.la -lm $(GTK_LIBS) $(PNG_LIBS)
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(GTK_CFLAGS) $(PNG_CFLAGS)
 
-GTK_UTILS = gtk-utils.c gtk-utils.h ../test/utils.c ../test/utils.h
+GTK_UTILS = gtk-utils.c gtk-utils.h ../test/utils.c ../test/utils.h \
+            ../test/utils-prng.c ../test/utils-prng.h
 
 DEMOS =				\
 	clip-test		\
diff --git a/test/affine-test.c b/test/affine-test.c
index d94023b..fc2e05b 100644
--- a/test/affine-test.c
+++ b/test/affine-test.c
@@ -77,11 +77,8 @@ test_composite (int      testnum,
     srcbuf = (uint32_t *)malloc (src_stride * src_height);
     dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
 
-    for (i = 0; i < src_stride * src_height; i++)
-	*((uint8_t *)srcbuf + i) = prng_rand_n (256);
-
-    for (i = 0; i < dst_stride * dst_height; i++)
-	*((uint8_t *)dstbuf + i) = prng_rand_n (256);
+    prng_randmemset (srcbuf, src_stride * src_height, 0);
+    prng_randmemset (dstbuf, dst_stride * dst_height, 0);
 
     src_fmt = src_bpp == 4 ? (prng_rand_n (2) == 0 ?
                               PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
@@ -310,11 +307,11 @@ test_composite (int      testnum,
 }
 
 #if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x344413F0
+#define CHECKSUM 0x97097336
 #elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0xC8181A76
+#define CHECKSUM 0x31D2DC21
 #elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0xD672A457
+#define CHECKSUM 0x8B925154
 #else
 #define CHECKSUM 0x00000000
 #endif
diff --git a/test/alpha-loop.c b/test/alpha-loop.c
index e4d90a9..eca7615 100644
--- a/test/alpha-loop.c
+++ b/test/alpha-loop.c
@@ -8,9 +8,14 @@
 int
 main (int argc, char **argv)
 {
-    uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
-    uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
-    uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+    uint8_t *alpha;
+    uint32_t *src, *dest;
+
+    prng_srand (0);
+
+    alpha = make_random_bytes (WIDTH * HEIGHT);
+    src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+    dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
 
     pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH);
     pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
diff --git a/test/alphamap.c b/test/alphamap.c
index 0c5757e..1a6fca5 100644
--- a/test/alphamap.c
+++ b/test/alphamap.c
@@ -307,6 +307,8 @@ main (int argc, char **argv)
 {
     int i, j, a, b, x, y;
 
+    prng_srand (0);
+
     for (i = 0; i < ARRAY_LENGTH (formats); ++i)
     {
 	for (j = 0; j < ARRAY_LENGTH (formats); ++j)
diff --git a/test/blitters-test.c b/test/blitters-test.c
index b0115d4..9bde99c 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -25,7 +25,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
 		     int                   max_extra_stride,
 		     pixman_format_code_t *used_fmt)
 {
-    int n = 0, i, width, height, stride;
+    int n = 0, width, height, stride;
     pixman_format_code_t fmt;
     uint32_t *buf;
     pixman_image_t *img;
@@ -46,15 +46,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
     /* do the allocation */
     buf = aligned_malloc (64, stride * height);
 
-    /* initialize image with random data */
-    for (i = 0; i < stride * height; i++)
-    {
-	/* generation is biased to having more 0 or 255 bytes as
-	 * they are more likely to be special-cased in code
-	 */
-	*((uint8_t *)buf + i) = prng_rand_n (4) ? prng_rand_n (256) :
-	    (prng_rand_n (2) ? 0 : 255);
-    }
+    prng_randmemset (buf, stride * height, RANDMEMSET_MORE_00_AND_FF);
 
     img = pixman_image_create_bits (fmt, width, height, buf, stride);
 
@@ -390,6 +382,8 @@ main (int argc, const char *argv[])
 {
     int i;
 
+    prng_srand (0);
+
     for (i = 1; i <= 8; i++)
     {
 	initialize_palette (&(rgb_palette[i]), i, TRUE);
@@ -397,6 +391,6 @@ main (int argc, const char *argv[])
     }
 
     return fuzzer_test_main("blitters", 2000000,
-			    0x46136E0A,
+			    0xD8265D5E,
 			    test_composite, argc, argv);
 }
diff --git a/test/composite-traps-test.c b/test/composite-traps-test.c
index efb3c30..5a4a921 100644
--- a/test/composite-traps-test.c
+++ b/test/composite-traps-test.c
@@ -251,6 +251,6 @@ test_composite (int      testnum,
 int
 main (int argc, const char *argv[])
 {
-    return fuzzer_test_main("composite traps", 40000, 0x33BFAA55,
+    return fuzzer_test_main("composite traps", 40000, 0x749BCC57,
 			    test_composite, argc, argv);
 }
diff --git a/test/glyph-test.c b/test/glyph-test.c
index 2fcc69c..7edb3be 100644
--- a/test/glyph-test.c
+++ b/test/glyph-test.c
@@ -153,14 +153,8 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
     }
     else
     {
-	uint8_t *d8;
-
 	data = malloc (stride * height);
-
-	d8 = (uint8_t *)data;
-	for (i = 0; i < height * stride; ++i)
-	    d8[i] = prng_rand_n (256);
-
+	prng_randmemset (data, height * stride, 0);
 	destroy = destroy_malloced;
     }
 
@@ -333,6 +327,6 @@ int
 main (int argc, const char *argv[])
 {
     return fuzzer_test_main ("glyph", 30000,	
-			     0x79E74996,
+			     0xFA478A79,
 			     test_glyphs, argc, argv);
 }
diff --git a/test/region-contains-test.c b/test/region-contains-test.c
index aca24ad..c757347 100644
--- a/test/region-contains-test.c
+++ b/test/region-contains-test.c
@@ -163,7 +163,7 @@ main (int argc, const char *argv[])
 {
     return fuzzer_test_main ("region_contains",
 			     1000000,
-			     0xD2BF8C73,
+			     0x548E0F3F,
 			     test_region_contains_rectangle,
 			     argc, argv);
 }
diff --git a/test/region-test.c b/test/region-test.c
index 87010f7..bfc219b 100644
--- a/test/region-test.c
+++ b/test/region-test.c
@@ -32,6 +32,8 @@ main ()
 	0xffff
     };
 
+    prng_srand (0);
+
     /* This used to go into an infinite loop before pixman-region.c
      * was fixed to not use explict "short" variables
      */
diff --git a/test/rotate-test.c b/test/rotate-test.c
index 0fe9301..9d2a620 100644
--- a/test/rotate-test.c
+++ b/test/rotate-test.c
@@ -63,10 +63,8 @@ make_image (void)
     pixman_format_code_t format = RANDOM_FORMAT();
     uint32_t *bytes = malloc (WIDTH * HEIGHT * 4);
     pixman_image_t *image;
-    int i;
 
-    for (i = 0; i < WIDTH * HEIGHT * 4; ++i)
-	((uint8_t *)bytes)[i] = prng_rand_n (256);
+    prng_randmemset (bytes, WIDTH * HEIGHT * 4, 0);
 
     image = pixman_image_create_bits (
 	format, WIDTH, HEIGHT, bytes, WIDTH * 4);
@@ -108,6 +106,6 @@ int
 main (int argc, const char *argv[])
 {
     return fuzzer_test_main ("rotate", 15000,
-			     0x5236FD9F,
+			     0xECF5E426,
 			     test_transform, argc, argv);
 }
diff --git a/test/scaling-helpers-test.c b/test/scaling-helpers-test.c
index a706020..2685ae1 100644
--- a/test/scaling-helpers-test.c
+++ b/test/scaling-helpers-test.c
@@ -52,6 +52,7 @@ int
 main (void)
 {
     int i;
+    prng_srand (0);
     for (i = 0; i < 10000; i++)
     {
 	int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1;
diff --git a/test/scaling-test.c b/test/scaling-test.c
index cfe9b52..44f851c 100644
--- a/test/scaling-test.c
+++ b/test/scaling-test.c
@@ -140,14 +140,9 @@ test_composite (int      testnum,
     maskbuf = (uint32_t *)malloc (mask_stride * mask_height);
     dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
 
-    for (i = 0; i < src_stride * src_height; i++)
-	*((uint8_t *)srcbuf + i) = prng_rand_n (256);
-
-    for (i = 0; i < mask_stride * mask_height; i++)
-	*((uint8_t *)maskbuf + i) = prng_rand_n (256);
-
-    for (i = 0; i < dst_stride * dst_height; i++)
-	*((uint8_t *)dstbuf + i) = prng_rand_n (256);
+    prng_randmemset (srcbuf, src_stride * src_height, 0);
+    prng_randmemset (maskbuf, mask_stride * mask_height, 0);
+    prng_randmemset (dstbuf, dst_stride * dst_height, 0);
 
     src_fmt = get_format (src_bpp);
     dst_fmt = get_format (dst_bpp);
@@ -380,11 +375,11 @@ test_composite (int      testnum,
 }
 
 #if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x107B67ED
+#define CHECKSUM 0x9096E6B6
 #elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x30EC0CF0
+#define CHECKSUM 0xCE8EC6BA
 #elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0x87B496BC
+#define CHECKSUM 0xAB1D39BE
 #else
 #define CHECKSUM 0x00000000
 #endif
diff --git a/test/utils.c b/test/utils.c
index c82ba2b..dd0e556 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -27,10 +27,11 @@
 #include <png.h>
 #endif
 
-/* Random number seed
+/* Random number generator state
  */
 
-uint32_t prng_seed;
+prng_t prng_state_data;
+prng_t *prng_state;
 
 /*----------------------------------------------------------------------------*\
  *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
@@ -423,13 +424,11 @@ uint8_t *
 make_random_bytes (int n_bytes)
 {
     uint8_t *bytes = fence_malloc (n_bytes);
-    int i;
 
     if (!bytes)
 	return NULL;
 
-    for (i = 0; i < n_bytes; ++i)
-	bytes[i] = prng_rand () & 0xff;
+    prng_randmemset (bytes, n_bytes, 0);
 
     return bytes;
 }
diff --git a/test/utils.h b/test/utils.h
index ec4c4ad..f054887 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -4,6 +4,7 @@
 
 #include <assert.h>
 #include "pixman-private.h" /* For 'inline' definition */
+#include "utils-prng.h"
 
 #define ARRAY_LENGTH(A) ((int) (sizeof (A) / sizeof ((A) [0])))
 
@@ -11,22 +12,32 @@
  * taken from POSIX.1-2001 example
  */
 
-extern uint32_t prng_seed;
+extern prng_t prng_state_data;
+extern prng_t *prng_state;
 #ifdef USE_OPENMP
-#pragma omp threadprivate(prng_seed)
+#pragma omp threadprivate(prng_state_data)
+#pragma omp threadprivate(prng_state)
 #endif
 
 static inline uint32_t
 prng_rand (void)
 {
-    prng_seed = prng_seed * 1103515245 + 12345;
-    return ((uint32_t)(prng_seed / 65536) % 32768);
+    return prng_rand_r (prng_state);
 }
 
 static inline void
 prng_srand (uint32_t seed)
 {
-    prng_seed = seed;
+    if (!prng_state)
+    {
+        /* Without setting a seed, PRNG does not work properly (is just
+         * returning zeros). So we only initialize the pointer here to
+         * make sure that 'prng_srand' is always called before any
+         * other 'prng_*' function. The wrongdoers violating this order
+         * will get a segfault. */
+        prng_state = &prng_state_data;
+    }
+    prng_srand_r (prng_state, seed);
 }
 
 static inline uint32_t
@@ -38,22 +49,19 @@ prng_rand_n (int max)
 static inline uint32_t
 prng_rand_N (int max)
 {
-    uint32_t lo = prng_rand ();
-    uint32_t hi = prng_rand () << 15;
-    return (lo | hi) % max;
+    return prng_rand () % max;
 }
 
 static inline uint32_t
 prng_rand_u32 (void)
 {
-    /* This uses the 10/11 most significant bits from the 3 lcg results
-     * (and mixes them with the low from the adjacent one).
-     */
-    uint32_t lo = prng_rand() >> -(32 - 15 - 11 * 2);
-    uint32_t mid = prng_rand() << (32 - 15 - 11 * 1);
-    uint32_t hi = prng_rand() << (32 - 15 - 11 * 0);
-
-    return (hi ^ mid ^ lo);
+    return prng_rand ();
+}
+
+static inline void
+prng_randmemset (void *buffer, size_t size, prng_randmemset_flags_t flags)
+{
+    prng_randmemset_r (prng_state, buffer, size, flags);
 }
 
 /* CRC 32 computation
commit 309e66f047cab0951d8e42628dcd181e2d14c58d
Author: Siarhei Siamashka <siarhei.siamashka at gmail.com>
Date:   Sat Nov 24 23:22:48 2012 +0200

    test: Search/replace 'lcg_*' -> 'prng_*'
    
    The 'lcg' prefix is going to be misleading if we replace
    PRNG algorithm.

diff --git a/test/affine-test.c b/test/affine-test.c
index daa86c8..d94023b 100644
--- a/test/affine-test.c
+++ b/test/affine-test.c
@@ -48,18 +48,18 @@ test_composite (int      testnum,
     uint32_t           crc32;
     FLOAT_REGS_CORRUPTION_DETECTOR_START ();
 
-    lcg_srand (testnum);
+    prng_srand (testnum);
 
-    src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
-    dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
-    op = (lcg_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
+    src_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
+    dst_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
+    op = (prng_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER;
 
-    src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
-    src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
-    dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
-    dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
-    src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
-    dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
+    src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
+    src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
+    dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
+    dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
+    src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
+    dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
 
     if (src_stride & 3)
 	src_stride += 2;
@@ -67,26 +67,26 @@ test_composite (int      testnum,
     if (dst_stride & 3)
 	dst_stride += 2;
 
-    src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
-    src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
-    dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
-    dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
-    w = lcg_rand_n (dst_width * 3 / 2 - dst_x);
-    h = lcg_rand_n (dst_height * 3 / 2 - dst_y);
+    src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
+    src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
+    dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
+    dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
+    w = prng_rand_n (dst_width * 3 / 2 - dst_x);
+    h = prng_rand_n (dst_height * 3 / 2 - dst_y);
 
     srcbuf = (uint32_t *)malloc (src_stride * src_height);
     dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
 
     for (i = 0; i < src_stride * src_height; i++)
-	*((uint8_t *)srcbuf + i) = lcg_rand_n (256);
+	*((uint8_t *)srcbuf + i) = prng_rand_n (256);
 
     for (i = 0; i < dst_stride * dst_height; i++)
-	*((uint8_t *)dstbuf + i) = lcg_rand_n (256);
+	*((uint8_t *)dstbuf + i) = prng_rand_n (256);
 
-    src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ?
+    src_fmt = src_bpp == 4 ? (prng_rand_n (2) == 0 ?
                               PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
 
-    dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ?
+    dst_fmt = dst_bpp == 4 ? (prng_rand_n (2) == 0 ?
                               PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
 
     src_img = pixman_image_create_bits (
@@ -100,29 +100,29 @@ test_composite (int      testnum,
 
     pixman_transform_init_identity (&transform);
 
-    if (lcg_rand_n (3) > 0)
+    if (prng_rand_n (3) > 0)
     {
-	scale_x = -65536 * 3 + lcg_rand_N (65536 * 6);
-	if (lcg_rand_n (2))
-	    scale_y = -65536 * 3 + lcg_rand_N (65536 * 6);
+	scale_x = -65536 * 3 + prng_rand_N (65536 * 6);
+	if (prng_rand_n (2))
+	    scale_y = -65536 * 3 + prng_rand_N (65536 * 6);
 	else
 	    scale_y = scale_x;
 	pixman_transform_init_scale (&transform, scale_x, scale_y);
     }
-    if (lcg_rand_n (3) > 0)
+    if (prng_rand_n (3) > 0)
     {
-	translate_x = -65536 * 3 + lcg_rand_N (6 * 65536);
-	if (lcg_rand_n (2))
-	    translate_y = -65536 * 3 + lcg_rand_N (6 * 65536);
+	translate_x = -65536 * 3 + prng_rand_N (6 * 65536);
+	if (prng_rand_n (2))
+	    translate_y = -65536 * 3 + prng_rand_N (6 * 65536);
 	else
 	    translate_y = translate_x;
 	pixman_transform_translate (&transform, NULL, translate_x, translate_y);
     }
 
-    if (lcg_rand_n (4) > 0)
+    if (prng_rand_n (4) > 0)
     {
 	int c, s, tx = 0, ty = 0;
-	switch (lcg_rand_n (4))
+	switch (prng_rand_n (4))
 	{
 	case 0:
 	    /* 90 degrees */
@@ -145,32 +145,32 @@ test_composite (int      testnum,
 	    break;
 	default:
 	    /* arbitrary rotation */
-	    c = lcg_rand_N (2 * 65536) - 65536;
-	    s = lcg_rand_N (2 * 65536) - 65536;
+	    c = prng_rand_N (2 * 65536) - 65536;
+	    s = prng_rand_N (2 * 65536) - 65536;
 	    break;
 	}
 	pixman_transform_rotate (&transform, NULL, c, s);
 	pixman_transform_translate (&transform, NULL, tx, ty);
     }
 
-    if (lcg_rand_n (8) == 0)
+    if (prng_rand_n (8) == 0)
     {
 	/* Flip random bits */
 	int maxflipcount = 8;
 	while (maxflipcount--)
 	{
-	    int i = lcg_rand_n (2);
-	    int j = lcg_rand_n (3);
-	    int bitnum = lcg_rand_n (32);
+	    int i = prng_rand_n (2);
+	    int j = prng_rand_n (3);
+	    int bitnum = prng_rand_n (32);
 	    transform.matrix[i][j] ^= 1 << bitnum;
-	    if (lcg_rand_n (2))
+	    if (prng_rand_n (2))
 		break;
 	}
     }
 
     pixman_image_set_transform (src_img, &transform);
 
-    switch (lcg_rand_n (4))
+    switch (prng_rand_n (4))
     {
     case 0:
 	repeat = PIXMAN_REPEAT_NONE;
@@ -193,7 +193,7 @@ test_composite (int      testnum,
     }
     pixman_image_set_repeat (src_img, repeat);
 
-    if (lcg_rand_n (2))
+    if (prng_rand_n (2))
 	pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
     else
 	pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0);
@@ -220,19 +220,19 @@ test_composite (int      testnum,
 	printf ("w=%d, h=%d\n", w, h);
     }
 
-    if (lcg_rand_n (8) == 0)
+    if (prng_rand_n (8) == 0)
     {
 	pixman_box16_t clip_boxes[2];
-	int            n = lcg_rand_n (2) + 1;
+	int            n = prng_rand_n (2) + 1;
 
 	for (i = 0; i < n; i++)
 	{
-	    clip_boxes[i].x1 = lcg_rand_n (src_width);
-	    clip_boxes[i].y1 = lcg_rand_n (src_height);
+	    clip_boxes[i].x1 = prng_rand_n (src_width);
+	    clip_boxes[i].y1 = prng_rand_n (src_height);
 	    clip_boxes[i].x2 =
-		clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
+		clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
 	    clip_boxes[i].y2 =
-		clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
+		clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
 
 	    if (verbose)
 	    {
@@ -248,18 +248,18 @@ test_composite (int      testnum,
 	pixman_region_fini (&clip);
     }
 
-    if (lcg_rand_n (8) == 0)
+    if (prng_rand_n (8) == 0)
     {
 	pixman_box16_t clip_boxes[2];
-	int            n = lcg_rand_n (2) + 1;
+	int            n = prng_rand_n (2) + 1;
 	for (i = 0; i < n; i++)
 	{
-	    clip_boxes[i].x1 = lcg_rand_n (dst_width);
-	    clip_boxes[i].y1 = lcg_rand_n (dst_height);
+	    clip_boxes[i].x1 = prng_rand_n (dst_width);
+	    clip_boxes[i].y1 = prng_rand_n (dst_height);
 	    clip_boxes[i].x2 =
-		clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
+		clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
 	    clip_boxes[i].y2 =
-		clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);
+		clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
 
 	    if (verbose)
 	    {
diff --git a/test/blitters-test.c b/test/blitters-test.c
index 30d6912..b0115d4 100644
--- a/test/blitters-test.c
+++ b/test/blitters-test.c
@@ -33,14 +33,14 @@ create_random_image (pixman_format_code_t *allowed_formats,
     while (allowed_formats[n] != PIXMAN_null)
 	n++;
 
-    if (n > N_MOST_LIKELY_FORMATS && lcg_rand_n (4) != 0)
+    if (n > N_MOST_LIKELY_FORMATS && prng_rand_n (4) != 0)
 	n = N_MOST_LIKELY_FORMATS;
-    fmt = allowed_formats[lcg_rand_n (n)];
+    fmt = allowed_formats[prng_rand_n (n)];
 
-    width = lcg_rand_n (max_width) + 1;
-    height = lcg_rand_n (max_height) + 1;
+    width = prng_rand_n (max_width) + 1;
+    height = prng_rand_n (max_height) + 1;
     stride = (width * PIXMAN_FORMAT_BPP (fmt) + 7) / 8 +
-	lcg_rand_n (max_extra_stride + 1);
+	prng_rand_n (max_extra_stride + 1);
     stride = (stride + 3) & ~3;
 
     /* do the allocation */
@@ -52,8 +52,8 @@ create_random_image (pixman_format_code_t *allowed_formats,
 	/* generation is biased to having more 0 or 255 bytes as
 	 * they are more likely to be special-cased in code
 	 */
-	*((uint8_t *)buf + i) = lcg_rand_n (4) ? lcg_rand_n (256) :
-	    (lcg_rand_n (2) ? 0 : 255);
+	*((uint8_t *)buf + i) = prng_rand_n (4) ? prng_rand_n (256) :
+	    (prng_rand_n (2) ? 0 : 255);
     }
 
     img = pixman_image_create_bits (fmt, width, height, buf, stride);
@@ -67,7 +67,7 @@ create_random_image (pixman_format_code_t *allowed_formats,
 	pixman_image_set_indexed (img, &(y_palette[PIXMAN_FORMAT_BPP (fmt)]));
     }
 
-    if (lcg_rand_n (16) == 0)
+    if (prng_rand_n (16) == 0)
 	pixman_image_set_filter (img, PIXMAN_FILTER_BILINEAR, NULL, 0);
 
     image_endian_swap (img);
@@ -251,11 +251,11 @@ test_composite (int testnum, int verbose)
     if (max_extra_stride > 8)
 	max_extra_stride = 8;
 
-    lcg_srand (testnum);
+    prng_srand (testnum);
 
-    op = op_list[lcg_rand_n (ARRAY_LENGTH (op_list))];
+    op = op_list[prng_rand_n (ARRAY_LENGTH (op_list))];
 
-    if (lcg_rand_n (8))
+    if (prng_rand_n (8))
     {
 	/* normal image */
 	src_img = create_random_image (img_fmt_list, max_width, max_height,
@@ -284,10 +284,10 @@ test_composite (int testnum, int verbose)
     dstbuf = pixman_image_get_data (dst_img);
     srcbuf = pixman_image_get_data (src_img);
 
-    src_x = lcg_rand_n (src_width);
-    src_y = lcg_rand_n (src_height);
-    dst_x = lcg_rand_n (dst_width);
-    dst_y = lcg_rand_n (dst_height);
+    src_x = prng_rand_n (src_width);
+    src_y = prng_rand_n (src_height);
+    dst_x = prng_rand_n (dst_width);
+    dst_y = prng_rand_n (dst_height);
 
     mask_img = NULL;
     mask_fmt = PIXMAN_null;
@@ -296,10 +296,10 @@ test_composite (int testnum, int verbose)
     maskbuf = NULL;
 
     if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
-	(lcg_rand_n (4) == 0))
+	(prng_rand_n (4) == 0))
     {
 	/* PIXBUF */
-	mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
+	mask_fmt = prng_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
 	mask_img = pixman_image_create_bits (mask_fmt,
 	                                     src_width,
 	                                     src_height,
@@ -309,9 +309,9 @@ test_composite (int testnum, int verbose)
 	mask_y = src_y;
 	maskbuf = srcbuf;
     }
-    else if (lcg_rand_n (2))
+    else if (prng_rand_n (2))
     {
-	if (lcg_rand_n (2))
+	if (prng_rand_n (2))
 	{
 	    mask_img = create_random_image (mask_fmt_list, max_width, max_height,
 					   max_extra_stride, &mask_fmt);
@@ -324,16 +324,16 @@ test_composite (int testnum, int verbose)
 	    pixman_image_set_repeat (mask_img, PIXMAN_REPEAT_NORMAL);
 	}
 
-	if (lcg_rand_n (2))
+	if (prng_rand_n (2))
 	    pixman_image_set_component_alpha (mask_img, 1);
 
-	mask_x = lcg_rand_n (pixman_image_get_width (mask_img));
-	mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
+	mask_x = prng_rand_n (pixman_image_get_width (mask_img));
+	mask_y = prng_rand_n (pixman_image_get_height (mask_img));
     }
 
 
-    w = lcg_rand_n (dst_width - dst_x + 1);
-    h = lcg_rand_n (dst_height - dst_y + 1);
+    w = prng_rand_n (dst_width - dst_x + 1);
+    h = prng_rand_n (dst_height - dst_y + 1);
 
     if (verbose)
     {
diff --git a/test/combiner-test.c b/test/combiner-test.c
index c438ae6..7d6feda 100644
--- a/test/combiner-test.c
+++ b/test/combiner-test.c
@@ -67,7 +67,7 @@ static const pixman_op_t op_list[] =
 static float
 rand_float (void)
 {
-    uint32_t u = lcg_rand_u32();
+    uint32_t u = prng_rand_u32();
 
     return *(float *)&u;
 }
@@ -123,7 +123,7 @@ main ()
     
     impl = _pixman_internal_only_get_implementation();
     
-    lcg_srand (0);
+    prng_srand (0);
 
     for (i = 0; i < ARRAY_LENGTH (op_list); ++i)
     {
diff --git a/test/composite-traps-test.c b/test/composite-traps-test.c
index 9fc94a4..efb3c30 100644
--- a/test/composite-traps-test.c
+++ b/test/composite-traps-test.c
@@ -26,7 +26,7 @@ static pixman_op_t operators[] =
 };
 
 #define RANDOM_ELT(array)						\
-    ((array)[lcg_rand_n(ARRAY_LENGTH((array)))])
+    ((array)[prng_rand_n(ARRAY_LENGTH((array)))])
 
 static void
 destroy_bits (pixman_image_t *image, void *data)
@@ -37,7 +37,7 @@ destroy_bits (pixman_image_t *image, void *data)
 static pixman_fixed_t
 random_fixed (int n)
 {
-    return lcg_rand_N (n << 16);
+    return prng_rand_N (n << 16);
 }
 
 /*
@@ -75,17 +75,17 @@ test_composite (int      testnum,
     
     FLOAT_REGS_CORRUPTION_DETECTOR_START ();
 
-    lcg_srand (testnum);
+    prng_srand (testnum);
 
     op = RANDOM_ELT (operators);
     mask_format = RANDOM_ELT (mask_formats);
 
     /* Create source image */
     
-    if (lcg_rand_n (4) == 0)
+    if (prng_rand_n (4) == 0)
     {
 	src_img = pixman_image_create_solid_fill (
-	    &(colors[lcg_rand_n (ARRAY_LENGTH (colors))]));
+	    &(colors[prng_rand_n (ARRAY_LENGTH (colors))]));
 
 	src_x = 10;
 	src_y = 234;
@@ -94,13 +94,13 @@ test_composite (int      testnum,
     {
 	pixman_format_code_t src_format = RANDOM_ELT(formats);
 	int src_bpp = (PIXMAN_FORMAT_BPP (src_format) + 7) / 8;
-	int src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
-	int src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
-	int src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
+	int src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
+	int src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
+	int src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
 	uint32_t *bits;
 
-	src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
-	src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
+	src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
+	src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
 
 	src_stride = (src_stride + 3) & ~3;
 	
@@ -111,19 +111,19 @@ test_composite (int      testnum,
 
 	pixman_image_set_destroy_function (src_img, destroy_bits, bits);
 
-	if (lcg_rand_n (8) == 0)
+	if (prng_rand_n (8) == 0)
 	{
 	    pixman_box16_t clip_boxes[2];
-	    int            n = lcg_rand_n (2) + 1;
+	    int            n = prng_rand_n (2) + 1;
 	    
 	    for (i = 0; i < n; i++)
 	    {
-		clip_boxes[i].x1 = lcg_rand_n (src_width);
-		clip_boxes[i].y1 = lcg_rand_n (src_height);
+		clip_boxes[i].x1 = prng_rand_n (src_width);
+		clip_boxes[i].y1 = prng_rand_n (src_height);
 		clip_boxes[i].x2 =
-		    clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
+		    clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
 		clip_boxes[i].y2 =
-		    clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
+		    clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
 		
 		if (verbose)
 		{
@@ -146,15 +146,15 @@ test_composite (int      testnum,
     {
 	dst_format = RANDOM_ELT(formats);
 	dst_bpp = (PIXMAN_FORMAT_BPP (dst_format) + 7) / 8;
-	dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
-	dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
-	dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
+	dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
+	dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
+	dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
 	dst_stride = (dst_stride + 3) & ~3;
 	
 	dst_bits = (uint32_t *)make_random_bytes (dst_stride * dst_height);
 
-	dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
-	dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
+	dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
+	dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
 	
 	dst_img = pixman_image_create_bits (
 	    dst_format, dst_width, dst_height, dst_bits, dst_stride);
@@ -166,7 +166,7 @@ test_composite (int      testnum,
     {
 	int i;
 
-	n_traps = lcg_rand_n (25);
+	n_traps = prng_rand_n (25);
 	traps = fence_malloc (n_traps * sizeof (pixman_trapezoid_t));
 
 	for (i = 0; i < n_traps; ++i)
@@ -186,18 +186,18 @@ test_composite (int      testnum,
 	}
     }
     
-    if (lcg_rand_n (8) == 0)
+    if (prng_rand_n (8) == 0)
     {
 	pixman_box16_t clip_boxes[2];
-	int            n = lcg_rand_n (2) + 1;
+	int            n = prng_rand_n (2) + 1;
 	for (i = 0; i < n; i++)
 	{
-	    clip_boxes[i].x1 = lcg_rand_n (dst_width);
-	    clip_boxes[i].y1 = lcg_rand_n (dst_height);
+	    clip_boxes[i].x1 = prng_rand_n (dst_width);
+	    clip_boxes[i].y1 = prng_rand_n (dst_height);
 	    clip_boxes[i].x2 =
-		clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
+		clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
 	    clip_boxes[i].y2 =
-		clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);
+		clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
 
 	    if (verbose)
 	    {
diff --git a/test/composite.c b/test/composite.c
index 2930fb7..09752c5 100644
--- a/test/composite.c
+++ b/test/composite.c
@@ -725,19 +725,19 @@ image_fini (image_t *info)
 static int
 random_size (void)
 {
-    return lcg_rand_n (ARRAY_LENGTH (sizes));
+    return prng_rand_n (ARRAY_LENGTH (sizes));
 }
 
 static int
 random_color (void)
 {
-    return lcg_rand_n (ARRAY_LENGTH (colors));
+    return prng_rand_n (ARRAY_LENGTH (colors));
 }
 
 static int
 random_format (void)
 {
-    return lcg_rand_n (ARRAY_LENGTH (formats));
+    return prng_rand_n (ARRAY_LENGTH (formats));
 }
 
 static pixman_bool_t
@@ -748,15 +748,15 @@ run_test (uint32_t seed)
     int ca;
     int ok;
 
-    lcg_srand (seed);
+    prng_srand (seed);
 
     image_init (&dst, random_color(), random_format(), 1);
     image_init (&src, random_color(), random_format(), random_size());
     image_init (&mask, random_color(), random_format(), random_size());
 
-    op = &(operators [lcg_rand_n (ARRAY_LENGTH (operators))]);
+    op = &(operators [prng_rand_n (ARRAY_LENGTH (operators))]);
 
-    ca = lcg_rand_n (3);
+    ca = prng_rand_n (3);
 
     switch (ca)
     {
diff --git a/test/glyph-test.c b/test/glyph-test.c
index 501cc2e..2fcc69c 100644
--- a/test/glyph-test.c
+++ b/test/glyph-test.c
@@ -107,7 +107,7 @@ random_format (const pixman_format_code_t *formats)
     i = 0;
     while (formats[i] != PIXMAN_null)
 	++i;
-    return formats[lcg_rand_n (i)];
+    return formats[prng_rand_n (i)];
 }
 
 static pixman_image_t *
@@ -122,27 +122,27 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
     int i;
     pixman_image_destroy_func_t destroy;
 
-    if ((flags & ALLOW_SOLID) && lcg_rand_n (4) == 0)
+    if ((flags & ALLOW_SOLID) && prng_rand_n (4) == 0)
     {
 	pixman_color_t color;
 
-	color.alpha = lcg_rand_u32();
-	color.red = lcg_rand_u32();
-	color.green = lcg_rand_u32();
-	color.blue = lcg_rand_u32();
+	color.alpha = prng_rand_u32();
+	color.red = prng_rand_u32();
+	color.green = prng_rand_u32();
+	color.blue = prng_rand_u32();
 
 	return pixman_image_create_solid_fill (&color);
     }
 
-    width = lcg_rand_n (max_size) + 1;
-    height = lcg_rand_n (max_size) + 1;
+    width = prng_rand_n (max_size) + 1;
+    height = prng_rand_n (max_size) + 1;
     format = random_format (formats);
 
     bpp = PIXMAN_FORMAT_BPP (format);
-    stride = (width * bpp + 7) / 8 + lcg_rand_n (17);
+    stride = (width * bpp + 7) / 8 + prng_rand_n (17);
     stride = (stride + 3) & ~3;
 
-    if (lcg_rand_n (64) == 0)
+    if (prng_rand_n (64) == 0)
     {
 	if (!(data = (uint32_t *)make_random_bytes (stride * height)))
 	{
@@ -159,7 +159,7 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
 
 	d8 = (uint8_t *)data;
 	for (i = 0; i < height * stride; ++i)
-	    d8[i] = lcg_rand_n (256);
+	    d8[i] = prng_rand_n (256);
 
 	destroy = destroy_malloced;
     }
@@ -167,20 +167,20 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
     image = pixman_image_create_bits (format, width, height, data, stride);
     pixman_image_set_destroy_function (image, destroy, data);
 
-    if ((flags & ALLOW_CLIPPED) && lcg_rand_n (8) == 0)
+    if ((flags & ALLOW_CLIPPED) && prng_rand_n (8) == 0)
     {
 	pixman_box16_t clip_boxes[8];
 	pixman_region16_t clip;
-	int n = lcg_rand_n (8) + 1;
+	int n = prng_rand_n (8) + 1;
 
 	for (i = 0; i < n; i++)
 	{
-	    clip_boxes[i].x1 = lcg_rand_n (width);
-	    clip_boxes[i].y1 = lcg_rand_n (height);
+	    clip_boxes[i].x1 = prng_rand_n (width);
+	    clip_boxes[i].y1 = prng_rand_n (height);
 	    clip_boxes[i].x2 =
-		clip_boxes[i].x1 + lcg_rand_n (width - clip_boxes[i].x1);
+		clip_boxes[i].x1 + prng_rand_n (width - clip_boxes[i].x1);
 	    clip_boxes[i].y2 =
-		clip_boxes[i].y1 + lcg_rand_n (height - clip_boxes[i].y1);
+		clip_boxes[i].y1 + prng_rand_n (height - clip_boxes[i].y1);
 	}
 
 	pixman_region_init_rects (&clip, clip_boxes, n);
@@ -188,27 +188,27 @@ create_image (int max_size, const pixman_format_code_t *formats, uint32_t flags)
 	pixman_region_fini (&clip);
     }
 
-    if ((flags & ALLOW_SOURCE_CLIPPING) && lcg_rand_n (4) == 0)
+    if ((flags & ALLOW_SOURCE_CLIPPING) && prng_rand_n (4) == 0)
     {
 	pixman_image_set_source_clipping (image, TRUE);
 	pixman_image_set_has_client_clip (image, TRUE);
     }
 
-    if ((flags & ALLOW_ALPHA_MAP) && lcg_rand_n (16) == 0)
+    if ((flags & ALLOW_ALPHA_MAP) && prng_rand_n (16) == 0)
     {
 	pixman_image_t *alpha_map;
 	int alpha_x, alpha_y;
 
-	alpha_x = lcg_rand_n (width);
-	alpha_y = lcg_rand_n (height);
+	alpha_x = prng_rand_n (width);
+	alpha_y = prng_rand_n (height);
 	alpha_map =
 	    create_image (max_size, formats, (flags & ~(ALLOW_ALPHA_MAP | ALLOW_SOLID)));
 	pixman_image_set_alpha_map (image, alpha_map, alpha_x, alpha_y);
 	pixman_image_unref (alpha_map);
     }
 
-    if ((flags & ALLOW_REPEAT) && lcg_rand_n (2) == 0)
-	pixman_image_set_repeat (image, lcg_rand_n (4));
+    if ((flags & ALLOW_REPEAT) && prng_rand_n (2) == 0)
+	pixman_image_set_repeat (image, prng_rand_n (4));
 
     image_endian_swap (image);
 
@@ -230,7 +230,7 @@ test_glyphs (int testnum, int verbose)
     int n_glyphs, i;
     pixman_glyph_cache_t *cache;
 
-    lcg_srand (testnum);
+    prng_srand (testnum);
 
     cache = pixman_glyph_cache_create ();
 
@@ -245,13 +245,13 @@ test_glyphs (int testnum, int verbose)
 
     pixman_glyph_cache_freeze (cache);
 
-    n_glyphs = lcg_rand_n (MAX_GLYPHS);
+    n_glyphs = prng_rand_n (MAX_GLYPHS);
     for (i = 0; i < n_glyphs; ++i)
 	glyph_images[i] = create_image (32, glyph_formats, 0);
 
     for (i = 0; i < 4 * n_glyphs; ++i)
     {
-	int g = lcg_rand_n (n_glyphs);
+	int g = prng_rand_n (n_glyphs);
 	pixman_image_t *glyph_img = glyph_images[g];
 	void *key1 = KEY1 (glyph_img);
 	void *key2 = KEY2 (glyph_img);
@@ -264,21 +264,21 @@ test_glyphs (int testnum, int verbose)
 	}
 
 	glyphs[i].glyph = glyph;
-	glyphs[i].x = lcg_rand_n (128);
-	glyphs[i].y = lcg_rand_n (128);
+	glyphs[i].x = prng_rand_n (128);
+	glyphs[i].y = prng_rand_n (128);
     }
 
-    if (lcg_rand_n (2) == 0)
+    if (prng_rand_n (2) == 0)
     {
-	int src_x = lcg_rand_n (300) - 150;
-	int src_y = lcg_rand_n (300) - 150;
-	int mask_x = lcg_rand_n (64) - 32;
-	int mask_y = lcg_rand_n (64) - 32;
-	int dest_x = lcg_rand_n (64) - 32;
-	int dest_y = lcg_rand_n (64) - 32;
-	int width = lcg_rand_n (64);
-	int height = lcg_rand_n (64);
-	pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))];
+	int src_x = prng_rand_n (300) - 150;
+	int src_y = prng_rand_n (300) - 150;
+	int mask_x = prng_rand_n (64) - 32;
+	int mask_y = prng_rand_n (64) - 32;
+	int dest_x = prng_rand_n (64) - 32;
+	int dest_y = prng_rand_n (64) - 32;
+	int width = prng_rand_n (64);
+	int height = prng_rand_n (64);
+	pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))];
 	pixman_format_code_t format = random_format (glyph_formats);
 
 	pixman_composite_glyphs (
@@ -292,11 +292,11 @@ test_glyphs (int testnum, int verbose)
     }
     else
     {
-	pixman_op_t op = operators[lcg_rand_n (ARRAY_LENGTH (operators))];
-	int src_x = lcg_rand_n (300) - 150;
-	int src_y = lcg_rand_n (300) - 150;
-	int dest_x = lcg_rand_n (64) - 32;
-	int dest_y = lcg_rand_n (64) - 32;
+	pixman_op_t op = operators[prng_rand_n (ARRAY_LENGTH (operators))];
+	int src_x = prng_rand_n (300) - 150;
+	int src_y = prng_rand_n (300) - 150;
+	int dest_x = prng_rand_n (64) - 32;
+	int dest_y = prng_rand_n (64) - 32;
 
 	pixman_composite_glyphs_no_mask (
 	    op, source, dest,
diff --git a/test/region-contains-test.c b/test/region-contains-test.c
index 9524e28..aca24ad 100644
--- a/test/region-contains-test.c
+++ b/test/region-contains-test.c
@@ -9,16 +9,16 @@ make_random_region (pixman_region32_t *region)
 
     pixman_region32_init (region);
 
-    n_boxes = lcg_rand_n (64);
+    n_boxes = prng_rand_n (64);
     while (n_boxes--)
     {
 	int32_t x, y;
 	uint32_t w, h;
 
-	x = (int32_t)lcg_rand_u32() >> 2;
-	y = (int32_t)lcg_rand_u32() >> 2;
-	w = lcg_rand_u32() >> 2;
-	h = lcg_rand_u32() >> 2;
+	x = (int32_t)prng_rand_u32() >> 2;
+	y = (int32_t)prng_rand_u32() >> 2;
+	w = prng_rand_u32() >> 2;
+	h = prng_rand_u32() >> 2;
 
 	pixman_region32_union_rect (region, region, x, y, w, h);
     }
@@ -37,12 +37,12 @@ random_coord (pixman_region32_t *region, pixman_bool_t x)
     int n_boxes;
     int begin, end;
 
-    if (lcg_rand_n (14))
+    if (prng_rand_n (14))
     {
 	bb = pixman_region32_rectangles (region, &n_boxes);
 	if (n_boxes == 0)
 	    goto use_extent;
-	b = bb + lcg_rand_n (n_boxes);
+	b = bb + prng_rand_n (n_boxes);
     }
     else
     {
@@ -62,12 +62,12 @@ random_coord (pixman_region32_t *region, pixman_bool_t x)
 	end = b->y2;
     }
 
-    switch (lcg_rand_n (5))
+    switch (prng_rand_n (5))
     {
     case 0:
-	return begin - lcg_rand_u32();
+	return begin - prng_rand_u32();
     case 1:
-	return end + lcg_rand_u32 ();
+	return end + prng_rand_u32 ();
     case 2:
 	return end;
     case 3:
@@ -111,14 +111,14 @@ test_region_contains_rectangle (int i, int verbose)
     pixman_region32_t region;
     uint32_t r, r1, r2, r3, r4, crc32;
 
-    lcg_srand (i);
+    prng_srand (i);
 
     make_random_region (&region);
 
     box.x1 = random_coord (&region, TRUE);
-    box.x2 = box.x1 + lcg_rand_u32 ();
+    box.x2 = box.x1 + prng_rand_u32 ();
     box.y1 = random_coord (&region, FALSE);
-    box.y2 = box.y1 + lcg_rand_u32 ();
+    box.y2 = box.y1 + prng_rand_u32 ();
 
     if (verbose)
     {
diff --git a/test/region-test.c b/test/region-test.c
index 9d5a41e..87010f7 100644
--- a/test/region-test.c
+++ b/test/region-test.c
@@ -91,10 +91,10 @@ main ()
 	/* Add some random rectangles */
 	for (j = 0; j < 64; j++)
 	    pixman_region32_union_rect (&r1, &r1,
-					lcg_rand_n (image_size),
-					lcg_rand_n (image_size),
-					lcg_rand_n (25),
-					lcg_rand_n (25));
+					prng_rand_n (image_size),
+					prng_rand_n (image_size),
+					prng_rand_n (25),
+					prng_rand_n (25));
 
 	/* Clip to image size */
 	pixman_region32_init_rect (&r2, 0, 0, image_size, image_size);
diff --git a/test/rotate-test.c b/test/rotate-test.c
index a0488ef..0fe9301 100644
--- a/test/rotate-test.c
+++ b/test/rotate-test.c
@@ -43,13 +43,13 @@ static const pixman_transform_t transforms[] =
 };
 
 #define RANDOM_FORMAT()							\
-    (formats[lcg_rand_n (ARRAY_LENGTH (formats))])
+    (formats[prng_rand_n (ARRAY_LENGTH (formats))])
 
 #define RANDOM_OP()							\
-    (ops[lcg_rand_n (ARRAY_LENGTH (ops))])
+    (ops[prng_rand_n (ARRAY_LENGTH (ops))])
 
 #define RANDOM_TRANSFORM()						\
-    (&(transforms[lcg_rand_n (ARRAY_LENGTH (transforms))]))
+    (&(transforms[prng_rand_n (ARRAY_LENGTH (transforms))]))
 
 static void
 on_destroy (pixman_image_t *image, void *data)
@@ -66,7 +66,7 @@ make_image (void)
     int i;
 
     for (i = 0; i < WIDTH * HEIGHT * 4; ++i)
-	((uint8_t *)bytes)[i] = lcg_rand_n (256);
+	((uint8_t *)bytes)[i] = prng_rand_n (256);
 
     image = pixman_image_create_bits (
 	format, WIDTH, HEIGHT, bytes, WIDTH * 4);
@@ -86,7 +86,7 @@ test_transform (int testnum, int verbose)
     pixman_image_t *src, *dest;
     uint32_t crc;
 
-    lcg_srand (testnum);
+    prng_srand (testnum);
     
     src = make_image ();
     dest = make_image ();
diff --git a/test/scaling-helpers-test.c b/test/scaling-helpers-test.c
index 33ec47c..a706020 100644
--- a/test/scaling-helpers-test.c
+++ b/test/scaling-helpers-test.c
@@ -56,10 +56,10 @@ main (void)
     {
 	int32_t left_pad1, left_tz1, width1, right_tz1, right_pad1;
 	int32_t left_pad2, left_tz2, width2, right_tz2, right_pad2;
-	pixman_fixed_t vx = lcg_rand_N(10000 << 16) - (3000 << 16);
-	int32_t width = lcg_rand_N(10000);
-	int32_t source_image_width = lcg_rand_N(10000) + 1;
-	pixman_fixed_t unit_x = lcg_rand_N(10 << 16) + 1;
+	pixman_fixed_t vx = prng_rand_N(10000 << 16) - (3000 << 16);
+	int32_t width = prng_rand_N(10000);
+	int32_t source_image_width = prng_rand_N(10000) + 1;
+	pixman_fixed_t unit_x = prng_rand_N(10 << 16) + 1;
 	width1 = width2 = width;
 
 	bilinear_pad_repeat_get_scanline_bounds_ref (source_image_width,
diff --git a/test/scaling-test.c b/test/scaling-test.c
index 0354103..cfe9b52 100644
--- a/test/scaling-test.c
+++ b/test/scaling-test.c
@@ -26,7 +26,7 @@ get_format (int bpp)
 {
     if (bpp == 4)
     {
-	switch (lcg_rand_n (4))
+	switch (prng_rand_n (4))
 	{
 	default:
 	case 0:
@@ -80,11 +80,11 @@ test_composite (int      testnum,
     uint32_t           crc32;
     FLOAT_REGS_CORRUPTION_DETECTOR_START ();
 
-    lcg_srand (testnum);
+    prng_srand (testnum);
 
-    src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
-    dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4;
-    switch (lcg_rand_n (3))
+    src_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
+    dst_bpp = (prng_rand_n (2) == 0) ? 2 : 4;
+    switch (prng_rand_n (3))
     {
     case 0:
 	op = PIXMAN_OP_SRC;
@@ -97,24 +97,24 @@ test_composite (int      testnum,
 	break;
     }
 
-    src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
-    src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
+    src_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
+    src_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
 
-    if (lcg_rand_n (2))
+    if (prng_rand_n (2))
     {
-	mask_width = lcg_rand_n (MAX_SRC_WIDTH) + 1;
-	mask_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1;
+	mask_width = prng_rand_n (MAX_SRC_WIDTH) + 1;
+	mask_height = prng_rand_n (MAX_SRC_HEIGHT) + 1;
     }
     else
     {
 	mask_width = mask_height = 1;
     }
 
-    dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1;
-    dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1;
-    src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp;
-    mask_stride = mask_width * mask_bpp + lcg_rand_n (MAX_STRIDE) * mask_bpp;
-    dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp;
+    dst_width = prng_rand_n (MAX_DST_WIDTH) + 1;
+    dst_height = prng_rand_n (MAX_DST_HEIGHT) + 1;
+    src_stride = src_width * src_bpp + prng_rand_n (MAX_STRIDE) * src_bpp;
+    mask_stride = mask_width * mask_bpp + prng_rand_n (MAX_STRIDE) * mask_bpp;
+    dst_stride = dst_width * dst_bpp + prng_rand_n (MAX_STRIDE) * dst_bpp;
 
     if (src_stride & 3)
 	src_stride += 2;
@@ -127,27 +127,27 @@ test_composite (int      testnum,
     if (dst_stride & 3)
 	dst_stride += 2;
 
-    src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2);
-    src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2);
-    mask_x = -(mask_width / 4) + lcg_rand_n (mask_width * 3 / 2);
-    mask_y = -(mask_height / 4) + lcg_rand_n (mask_height * 3 / 2);
-    dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2);
-    dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2);
-    w = lcg_rand_n (dst_width * 3 / 2 - dst_x);
-    h = lcg_rand_n (dst_height * 3 / 2 - dst_y);
+    src_x = -(src_width / 4) + prng_rand_n (src_width * 3 / 2);
+    src_y = -(src_height / 4) + prng_rand_n (src_height * 3 / 2);
+    mask_x = -(mask_width / 4) + prng_rand_n (mask_width * 3 / 2);
+    mask_y = -(mask_height / 4) + prng_rand_n (mask_height * 3 / 2);
+    dst_x = -(dst_width / 4) + prng_rand_n (dst_width * 3 / 2);
+    dst_y = -(dst_height / 4) + prng_rand_n (dst_height * 3 / 2);
+    w = prng_rand_n (dst_width * 3 / 2 - dst_x);
+    h = prng_rand_n (dst_height * 3 / 2 - dst_y);
 
     srcbuf = (uint32_t *)malloc (src_stride * src_height);
     maskbuf = (uint32_t *)malloc (mask_stride * mask_height);
     dstbuf = (uint32_t *)malloc (dst_stride * dst_height);
 
     for (i = 0; i < src_stride * src_height; i++)
-	*((uint8_t *)srcbuf + i) = lcg_rand_n (256);
+	*((uint8_t *)srcbuf + i) = prng_rand_n (256);
 
     for (i = 0; i < mask_stride * mask_height; i++)
-	*((uint8_t *)maskbuf + i) = lcg_rand_n (256);
+	*((uint8_t *)maskbuf + i) = prng_rand_n (256);
 
     for (i = 0; i < dst_stride * dst_height; i++)
-	*((uint8_t *)dstbuf + i) = lcg_rand_n (256);
+	*((uint8_t *)dstbuf + i) = prng_rand_n (256);
 
     src_fmt = get_format (src_bpp);
     dst_fmt = get_format (dst_bpp);
@@ -164,29 +164,29 @@ test_composite (int      testnum,
     image_endian_swap (src_img);
     image_endian_swap (dst_img);
 
-    if (lcg_rand_n (4) > 0)
+    if (prng_rand_n (4) > 0)
     {
-	scale_x = -32768 * 3 + lcg_rand_N (65536 * 5);
-	scale_y = -32768 * 3 + lcg_rand_N (65536 * 5);
-	translate_x = lcg_rand_N (65536);
-	translate_y = lcg_rand_N (65536);
+	scale_x = -32768 * 3 + prng_rand_N (65536 * 5);
+	scale_y = -32768 * 3 + prng_rand_N (65536 * 5);
+	translate_x = prng_rand_N (65536);
+	translate_y = prng_rand_N (65536);
 	pixman_transform_init_scale (&transform, scale_x, scale_y);
 	pixman_transform_translate (&transform, NULL, translate_x, translate_y);
 	pixman_image_set_transform (src_img, &transform);
     }
 
-    if (lcg_rand_n (2) > 0)
+    if (prng_rand_n (2) > 0)
     {
-	mask_scale_x = -32768 * 3 + lcg_rand_N (65536 * 5);
-	mask_scale_y = -32768 * 3 + lcg_rand_N (65536 * 5);
-	mask_translate_x = lcg_rand_N (65536);
-	mask_translate_y = lcg_rand_N (65536);
+	mask_scale_x = -32768 * 3 + prng_rand_N (65536 * 5);
+	mask_scale_y = -32768 * 3 + prng_rand_N (65536 * 5);
+	mask_translate_x = prng_rand_N (65536);
+	mask_translate_y = prng_rand_N (65536);
 	pixman_transform_init_scale (&transform, mask_scale_x, mask_scale_y);
 	pixman_transform_translate (&transform, NULL, mask_translate_x, mask_translate_y);
 	pixman_image_set_transform (mask_img, &transform);
     }
 
-    switch (lcg_rand_n (4))
+    switch (prng_rand_n (4))
     {
     case 0:
 	mask_repeat = PIXMAN_REPEAT_NONE;
@@ -209,7 +209,7 @@ test_composite (int      testnum,
     }
     pixman_image_set_repeat (mask_img, mask_repeat);
 
-    switch (lcg_rand_n (4))
+    switch (prng_rand_n (4))
     {
     case 0:
 	repeat = PIXMAN_REPEAT_NONE;
@@ -232,12 +232,12 @@ test_composite (int      testnum,
     }
     pixman_image_set_repeat (src_img, repeat);
 
-    if (lcg_rand_n (2))
+    if (prng_rand_n (2))
 	pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0);
     else
 	pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0);
 
-    if (lcg_rand_n (2))
+    if (prng_rand_n (2))
 	pixman_image_set_filter (mask_img, PIXMAN_FILTER_NEAREST, NULL, 0);
     else
 	pixman_image_set_filter (mask_img, PIXMAN_FILTER_BILINEAR, NULL, 0);
@@ -256,19 +256,19 @@ test_composite (int      testnum,
 	printf ("w=%d, h=%d\n", w, h);
     }
 
-    if (lcg_rand_n (8) == 0)
+    if (prng_rand_n (8) == 0)
     {
 	pixman_box16_t clip_boxes[2];
-	int            n = lcg_rand_n (2) + 1;
+	int            n = prng_rand_n (2) + 1;
 
 	for (i = 0; i < n; i++)
 	{
-	    clip_boxes[i].x1 = lcg_rand_n (src_width);
-	    clip_boxes[i].y1 = lcg_rand_n (src_height);
+	    clip_boxes[i].x1 = prng_rand_n (src_width);
+	    clip_boxes[i].y1 = prng_rand_n (src_height);
 	    clip_boxes[i].x2 =
-		clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1);
+		clip_boxes[i].x1 + prng_rand_n (src_width - clip_boxes[i].x1);
 	    clip_boxes[i].y2 =
-		clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1);
+		clip_boxes[i].y1 + prng_rand_n (src_height - clip_boxes[i].y1);
 
 	    if (verbose)
 	    {
@@ -284,19 +284,19 @@ test_composite (int      testnum,
 	pixman_region_fini (&clip);
     }
 
-    if (lcg_rand_n (8) == 0)
+    if (prng_rand_n (8) == 0)
     {
 	pixman_box16_t clip_boxes[2];
-	int            n = lcg_rand_n (2) + 1;
+	int            n = prng_rand_n (2) + 1;
 
 	for (i = 0; i < n; i++)
 	{
-	    clip_boxes[i].x1 = lcg_rand_n (mask_width);
-	    clip_boxes[i].y1 = lcg_rand_n (mask_height);
+	    clip_boxes[i].x1 = prng_rand_n (mask_width);
+	    clip_boxes[i].y1 = prng_rand_n (mask_height);
 	    clip_boxes[i].x2 =
-		clip_boxes[i].x1 + lcg_rand_n (mask_width - clip_boxes[i].x1);
+		clip_boxes[i].x1 + prng_rand_n (mask_width - clip_boxes[i].x1);
 	    clip_boxes[i].y2 =
-		clip_boxes[i].y1 + lcg_rand_n (mask_height - clip_boxes[i].y1);
+		clip_boxes[i].y1 + prng_rand_n (mask_height - clip_boxes[i].y1);
 
 	    if (verbose)
 	    {
@@ -312,18 +312,18 @@ test_composite (int      testnum,
 	pixman_region_fini (&clip);
     }
 
-    if (lcg_rand_n (8) == 0)
+    if (prng_rand_n (8) == 0)
     {
 	pixman_box16_t clip_boxes[2];
-	int            n = lcg_rand_n (2) + 1;
+	int            n = prng_rand_n (2) + 1;
 	for (i = 0; i < n; i++)
 	{
-	    clip_boxes[i].x1 = lcg_rand_n (dst_width);
-	    clip_boxes[i].y1 = lcg_rand_n (dst_height);
+	    clip_boxes[i].x1 = prng_rand_n (dst_width);
+	    clip_boxes[i].y1 = prng_rand_n (dst_height);
 	    clip_boxes[i].x2 =
-		clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1);
+		clip_boxes[i].x1 + prng_rand_n (dst_width - clip_boxes[i].x1);
 	    clip_boxes[i].y2 =
-		clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1);
+		clip_boxes[i].y1 + prng_rand_n (dst_height - clip_boxes[i].y1);
 
 	    if (verbose)
 	    {
@@ -337,7 +337,7 @@ test_composite (int      testnum,
 	pixman_region_fini (&clip);
     }
 
-    if (lcg_rand_n (2) == 0)
+    if (prng_rand_n (2) == 0)
 	pixman_image_composite (op, src_img, NULL, dst_img,
                             src_x, src_y, 0, 0, dst_x, dst_y, w, h);
     else
diff --git a/test/stress-test.c b/test/stress-test.c
index 059250d..8b99904 100644
--- a/test/stress-test.c
+++ b/test/stress-test.c
@@ -74,7 +74,7 @@ static pixman_filter_t filters[] =
 static int
 get_size (void)
 {
-    switch (lcg_rand_n (28))
+    switch (prng_rand_n (28))
     {
     case 0:
 	return 1;
@@ -84,10 +84,10 @@ get_size (void)
 
     default:
     case 2:
-	return lcg_rand_n (100);
+	return prng_rand_n (100);
 
     case 4:
-	return lcg_rand_n (2000) + 1000;
+	return prng_rand_n (2000) + 1000;
 
     case 5:
 	return 65535;
@@ -96,7 +96,7 @@ get_size (void)
 	return 65536;
 
     case 7:
-	return lcg_rand_N (64000) + 63000;
+	return prng_rand_N (64000) + 63000;
     }
 }
 
@@ -164,7 +164,7 @@ real_writer (void *src, uint32_t value, int size)
 static uint32_t
 fake_reader (const void *src, int size)
 {
-    uint32_t r = lcg_rand_u32 ();
+    uint32_t r = prng_rand_u32 ();
 
     assert (size == 1 || size == 2 || size == 4);
 
@@ -182,16 +182,16 @@ log_rand (void)
 {
     uint32_t mask;
 
-    mask = (1 << lcg_rand_n (10)) - 1;
+    mask = (1 << prng_rand_n (10)) - 1;
 
-    return (lcg_rand_u32 () & mask) - (mask >> 1);
+    return (prng_rand_u32 () & mask) - (mask >> 1);
 }
 
 static int32_t
 rand_x (pixman_image_t *image)
 {
     if (image->type == BITS)
-	return lcg_rand_n (image->bits.width);
+	return prng_rand_n (image->bits.width);
     else
 	return log_rand ();
 }
@@ -200,7 +200,7 @@ static int32_t
 rand_y (pixman_image_t *image)
 {
     if (image->type == BITS)
-	return lcg_rand_n (image->bits.height);
+	return prng_rand_n (image->bits.height);
     else
 	return log_rand ();
 }
@@ -220,7 +220,7 @@ create_random_bits_image (void)
     int n_coefficients = 0;
 
     /* format */
-    format = image_formats[lcg_rand_n (ARRAY_LENGTH (image_formats))];
+    format = image_formats[prng_rand_n (ARRAY_LENGTH (image_formats))];
 
     indexed = NULL;
     if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_COLOR)
@@ -246,7 +246,7 @@ create_random_bits_image (void)
 
     while ((uint64_t)width * height > 200000)
     {
-	if (lcg_rand_n(2) == 0)
+	if (prng_rand_n(2) == 0)
 	    height = 200000 / width;
 	else
 	    width = 200000 / height;
@@ -258,11 +258,11 @@ create_random_bits_image (void)
 	width = 1;
 
     /* bits */
-    switch (lcg_rand_n (7))
+    switch (prng_rand_n (7))
     {
     default:
     case 0:
-	stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+	stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17);
 	stride = (stride + 3) & (~3);
 	bits = (uint32_t *)make_random_bytes (height * stride);
 	break;
@@ -273,7 +273,7 @@ create_random_bits_image (void)
 	break;
 
     case 2: /* Zero-filled */
-	stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+	stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17);
 	stride = (stride + 3) & (~3);
 	bits = fence_malloc (height * stride);
 	if (!bits)
@@ -282,7 +282,7 @@ create_random_bits_image (void)
 	break;
 
     case 3: /* Filled with 0xFF */
-	stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+	stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17);
 	stride = (stride + 3) & (~3);
 	bits = fence_malloc (height * stride);
 	if (!bits)
@@ -298,7 +298,7 @@ create_random_bits_image (void)
 	break;
 
     case 5: /* bits is a real pointer, has read/write functions */
-	stride = width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17);
+	stride = width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17);
 	stride = (stride + 3) & (~3);
 	bits = fence_malloc (height * stride);
 	if (!bits)
@@ -309,7 +309,7 @@ create_random_bits_image (void)
 	break;
 
     case 6: /* bits is a real pointer, stride is negative */
-	stride = (width * PIXMAN_FORMAT_BPP (format) + lcg_rand_n (17));
+	stride = (width * PIXMAN_FORMAT_BPP (format) + prng_rand_n (17));
 	stride = (stride + 3) & (~3);
 	bits = (uint32_t *)make_random_bytes (height * stride);
 	if (!bits)
@@ -320,11 +320,11 @@ create_random_bits_image (void)
     }
 
     /* Filter */
-    filter = filters[lcg_rand_n (ARRAY_LENGTH (filters))];
+    filter = filters[prng_rand_n (ARRAY_LENGTH (filters))];
     if (filter == PIXMAN_FILTER_CONVOLUTION)
     {
-	int width = lcg_rand_n (3);
-	int height = lcg_rand_n (4);
+	int width = prng_rand_n (3);
+	int height = prng_rand_n (4);
 
 	n_coefficients = width * height + 2;
 	coefficients = malloc (n_coefficients * sizeof (pixman_fixed_t));
@@ -334,7 +334,7 @@ create_random_bits_image (void)
 	    int i;
 
 	    for (i = 0; i < width * height; ++i)
-		coefficients[i + 2] = lcg_rand_u32();
+		coefficients[i + 2] = prng_rand_u32();
 
 	    coefficients[0] = width << 16;
 	    coefficients[1] = height << 16;
@@ -380,11 +380,11 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
     /* Set properties that are generic to all images */
 
     /* Repeat */
-    repeat = repeats[lcg_rand_n (ARRAY_LENGTH (repeats))];
+    repeat = repeats[prng_rand_n (ARRAY_LENGTH (repeats))];
     pixman_image_set_repeat (image, repeat);
 
     /* Alpha map */
-    if (allow_alpha_map && lcg_rand_n (4) == 0)
+    if (allow_alpha_map && prng_rand_n (4) == 0)
     {
 	pixman_image_t *alpha_map;
 	int16_t x, y;
@@ -405,17 +405,17 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
     }
 
     /* Component alpha */
-    pixman_image_set_component_alpha (image, lcg_rand_n (3) == 0);
+    pixman_image_set_component_alpha (image, prng_rand_n (3) == 0);
 
     /* Clip region */
-    if (lcg_rand_n (8) < 2)
+    if (prng_rand_n (8) < 2)
     {
 	pixman_region32_t region;
 	int i, n_rects;
 
 	pixman_region32_init (&region);
 
-	switch (lcg_rand_n (12))
+	switch (prng_rand_n (12))
 	{
 	case 0:
 	    n_rects = 0;
@@ -434,7 +434,7 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
 	    break;
 
 	default:
-	    n_rects = lcg_rand_n (100);
+	    n_rects = prng_rand_n (100);
 	    break;
 	}
 
@@ -452,7 +452,7 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
 		&region, &region, x, y, width, height);
 	}
 
-	if (image->type == BITS && lcg_rand_n (8) != 0)
+	if (image->type == BITS && prng_rand_n (8) != 0)
 	{
 	    uint32_t width, height;
 	    int x, y;
@@ -463,10 +463,10 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
 	     */
 	    for (i = 0; i < 5; ++i)
 	    {
-		x = lcg_rand_n (2 * image->bits.width) - image->bits.width;
-		y = lcg_rand_n (2 * image->bits.height) - image->bits.height;
-		width = lcg_rand_n (image->bits.width) - x + 10;
-		height = lcg_rand_n (image->bits.height) - y + 10;
+		x = prng_rand_n (2 * image->bits.width) - image->bits.width;
+		y = prng_rand_n (2 * image->bits.height) - image->bits.height;
+		width = prng_rand_n (image->bits.width) - x + 10;
+		height = prng_rand_n (image->bits.height) - y + 10;
 
 		if (width + x < x)
 		    width = INT32_MAX - x;
@@ -484,13 +484,13 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
     }
 
     /* Whether source clipping is enabled */
-    pixman_image_set_source_clipping (image, !!lcg_rand_n (2));
+    pixman_image_set_source_clipping (image, !!prng_rand_n (2));
 
     /* Client clip */
-    pixman_image_set_has_client_clip (image, !!lcg_rand_n (2));
+    pixman_image_set_has_client_clip (image, !!prng_rand_n (2));
 
     /* Transform */
-    if (lcg_rand_n (5) < 2)
+    if (prng_rand_n (5) < 2)
     {
 	pixman_transform_t xform;
 	int i, j, k;
@@ -504,39 +504,39 @@ set_general_properties (pixman_image_t *image, pixman_bool_t allow_alpha_map)
 
 	for (k = 0; k < 3; ++k)
 	{
-	    switch (lcg_rand_n (4))
+	    switch (prng_rand_n (4))
 	    {
 	    case 0:
 		/* rotation */
-		c = lcg_rand_N (2 * 65536) - 65536;
-		s = lcg_rand_N (2 * 65536) - 65536;
+		c = prng_rand_N (2 * 65536) - 65536;
+		s = prng_rand_N (2 * 65536) - 65536;
 		pixman_transform_rotate (&xform, NULL, c, s);
 		break;
 
 	    case 1:
 		/* translation */
-		tx = lcg_rand_u32();
-		ty = lcg_rand_u32();
+		tx = prng_rand_u32();
+		ty = prng_rand_u32();
 		pixman_transform_translate (&xform, NULL, tx, ty);
 		break;
 
 	    case 2:
 		/* scale */
-		sx = lcg_rand_u32();
-		sy = lcg_rand_u32();
+		sx = prng_rand_u32();
+		sy = prng_rand_u32();
 		pixman_transform_scale (&xform, NULL, sx, sy);
 		break;
 
 	    case 3:
-		if (lcg_rand_n (16) == 0)
+		if (prng_rand_n (16) == 0)
 		{
 		    /* random */
 		    for (i = 0; i < 3; ++i)
 			for (j = 0; j < 3; ++j)
-			    xform.matrix[i][j] = lcg_rand_u32();
+			    xform.matrix[i][j] = prng_rand_u32();
 		    break;
 		}
-		else if (lcg_rand_n (16) == 0)
+		else if (prng_rand_n (16) == 0)
 		{
 		    /* zero */
 		    memset (&xform, 0, sizeof xform);
@@ -554,10 +554,10 @@ random_color (void)
 {
     pixman_color_t color =
     {
-	lcg_rand() & 0xffff,
-	lcg_rand() & 0xffff,
-	lcg_rand() & 0xffff,
-	lcg_rand() & 0xffff,
+	prng_rand() & 0xffff,
+	prng_rand() & 0xffff,
+	prng_rand() & 0xffff,
+	prng_rand() & 0xffff,
     };
 
     return color;
@@ -581,7 +581,7 @@ create_random_stops (int *n_stops)
     int i;
     pixman_gradient_stop_t *stops;
 
-    *n_stops = lcg_rand_n (50) + 1;
+    *n_stops = prng_rand_n (50) + 1;
 
     step = pixman_fixed_1 / *n_stops;
 
@@ -646,8 +646,8 @@ create_random_radial_image (void)
 
     inner_c = create_random_point();
     outer_c = create_random_point();
-    inner_r = lcg_rand();
-    outer_r = lcg_rand();
+    inner_r = prng_rand();
+    outer_r = prng_rand();
 
     stops = create_random_stops (&n_stops);
 
@@ -672,7 +672,7 @@ create_random_conical_image (void)
     pixman_image_t *result;
 
     c = create_random_point();
-    angle = lcg_rand();
+    angle = prng_rand();
 
     stops = create_random_stops (&n_stops);
 
@@ -691,7 +691,7 @@ create_random_image (void)
 {
     pixman_image_t *result;
 
-    switch (lcg_rand_n (5))
+    switch (prng_rand_n (5))
     {
     default:
     case 0:
@@ -793,7 +793,7 @@ run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod)
 	    printf ("Seed 0x%08x\n", seed);
     }
 	    
-    lcg_srand (seed);
+    prng_srand (seed);
 
     source = create_random_image ();
     mask   = create_random_image ();
@@ -803,7 +803,7 @@ run_test (uint32_t seed, pixman_bool_t verbose, uint32_t mod)
     {
 	set_general_properties (dest, TRUE);
 
-	op = op_list [lcg_rand_n (ARRAY_LENGTH (op_list))];
+	op = op_list [prng_rand_n (ARRAY_LENGTH (op_list))];
 
 	pixman_image_composite32 (op,
 				  source, mask, dest,
diff --git a/test/utils.c b/test/utils.c
index 00e74e5..c82ba2b 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -30,7 +30,7 @@
 /* Random number seed
  */
 
-uint32_t lcg_seed;
+uint32_t prng_seed;
 
 /*----------------------------------------------------------------------------*\
  *  CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29.
@@ -429,7 +429,7 @@ make_random_bytes (int n_bytes)
 	return NULL;
 
     for (i = 0; i < n_bytes; ++i)
-	bytes[i] = lcg_rand () & 0xff;
+	bytes[i] = prng_rand () & 0xff;
 
     return bytes;
 }
@@ -681,9 +681,9 @@ get_random_seed (void)
 {
     union { double d; uint32_t u32; } t;
     t.d = gettime();
-    lcg_srand (t.u32);
+    prng_srand (t.u32);
 
-    return lcg_rand_u32 ();
+    return prng_rand_u32 ();
 }
 
 #ifdef HAVE_SIGACTION
@@ -777,7 +777,7 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
     uint32_t mask = (1 << depth) - 1;
 
     for (i = 0; i < 32768; ++i)
-	palette->ent[i] = lcg_rand() & mask;
+	palette->ent[i] = prng_rand() & mask;
 
     memset (palette->rgba, 0, sizeof (palette->rgba));
 
@@ -797,7 +797,7 @@ initialize_palette (pixman_indexed_t *palette, uint32_t depth, int is_rgb)
 	{
 	    uint32_t old_idx;
 
-	    rgba24 = lcg_rand();
+	    rgba24 = prng_rand();
 	    i15 = CONVERT_15 (rgba24, is_rgb);
 
 	    old_idx = palette->ent[i15];
diff --git a/test/utils.h b/test/utils.h
index fa05587..ec4c4ad 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -11,47 +11,47 @@
  * taken from POSIX.1-2001 example
  */
 
-extern uint32_t lcg_seed;
+extern uint32_t prng_seed;
 #ifdef USE_OPENMP
-#pragma omp threadprivate(lcg_seed)
+#pragma omp threadprivate(prng_seed)
 #endif
 
 static inline uint32_t
-lcg_rand (void)
+prng_rand (void)
 {
-    lcg_seed = lcg_seed * 1103515245 + 12345;
-    return ((uint32_t)(lcg_seed / 65536) % 32768);
+    prng_seed = prng_seed * 1103515245 + 12345;
+    return ((uint32_t)(prng_seed / 65536) % 32768);
 }
 
 static inline void
-lcg_srand (uint32_t seed)
+prng_srand (uint32_t seed)
 {
-    lcg_seed = seed;
+    prng_seed = seed;
 }
 
 static inline uint32_t
-lcg_rand_n (int max)
+prng_rand_n (int max)
 {
-    return lcg_rand () % max;
+    return prng_rand () % max;
 }
 
 static inline uint32_t
-lcg_rand_N (int max)
+prng_rand_N (int max)
 {
-    uint32_t lo = lcg_rand ();
-    uint32_t hi = lcg_rand () << 15;
+    uint32_t lo = prng_rand ();
+    uint32_t hi = prng_rand () << 15;
     return (lo | hi) % max;
 }
 
 static inline uint32_t
-lcg_rand_u32 (void)
+prng_rand_u32 (void)
 {
     /* This uses the 10/11 most significant bits from the 3 lcg results
      * (and mixes them with the low from the adjacent one).
      */
-    uint32_t lo = lcg_rand() >> -(32 - 15 - 11 * 2);
-    uint32_t mid = lcg_rand() << (32 - 15 - 11 * 1);
-    uint32_t hi = lcg_rand() << (32 - 15 - 11 * 0);
+    uint32_t lo = prng_rand() >> -(32 - 15 - 11 * 2);
+    uint32_t mid = prng_rand() << (32 - 15 - 11 * 1);
+    uint32_t hi = prng_rand() << (32 - 15 - 11 * 0);
 
     return (hi ^ mid ^ lo);
 }
commit d6545a2fc6f65c4959c6f85a15e95675347c0940
Author: Siarhei Siamashka <siarhei.siamashka at gmail.com>
Date:   Sat Nov 24 19:43:41 2012 +0200

    test: Added a better PRNG (pseudorandom number generator)
    
    This adds a fast SIMD-optimized variant of a small noncryptographic
    PRNG originally developed by Bob Jenkins:
        http://www.burtleburtle.net/bob/rand/smallprng.html
    
    The generated pseudorandom data is good enough to pass "Big Crush"
    tests from TestU01 (http://en.wikipedia.org/wiki/TestU01).
    
    SIMD code uses http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
    which is a GCC specific extension. There is also a slower alternative
    code path, which should work with any C compiler.
    
    The performance of filling buffer with random data:
       Intel Core i7  @2.8GHz (SSE2)     : ~5.9 GB/s
       ARM Cortex-A15 @1.7GHz (NEON)     : ~2.2 GB/s
       IBM Cell PPU   @3.2GHz (Altivec)  : ~1.7 GB/s

diff --git a/test/Makefile.sources b/test/Makefile.sources
index 0778971..8c0b505 100644
--- a/test/Makefile.sources
+++ b/test/Makefile.sources
@@ -1,5 +1,6 @@
 # Tests (sorted by expected completion time)
 TESTPROGRAMS =			\
+	prng-test		\
 	a1-trap-test		\
 	pdf-op-test		\
 	region-test		\
@@ -33,8 +34,10 @@ BENCHMARKS =			\
 # Utility functions
 libutils_sources =		\
 	utils.c			\
+	utils-prng.c		\
 	$(NULL)
 
 libutils_headers =		\
 	utils.h			\
+	utils-prng.h		\
 	$(NULL)
diff --git a/test/prng-test.c b/test/prng-test.c
new file mode 100644
index 0000000..0a3ad5e
--- /dev/null
+++ b/test/prng-test.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka at gmail.com>
+ *
+ * Based on the public domain implementation of small noncryptographic PRNG
+ * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include "utils-prng.h"
+#include "utils.h"
+
+/* The original code from http://www.burtleburtle.net/bob/rand/smallprng.html */
+
+typedef uint32_t u4;
+typedef struct ranctx { u4 a; u4 b; u4 c; u4 d; } ranctx;
+
+#define rot(x,k) (((x)<<(k))|((x)>>(32-(k))))
+u4 ranval( ranctx *x ) {
+    u4 e = x->a - rot(x->b, 27);
+    x->a = x->b ^ rot(x->c, 17);
+    x->b = x->c + x->d;
+    x->c = x->d + e;
+    x->d = e + x->a;
+    return x->d;
+}
+
+void raninit( ranctx *x, u4 seed ) {
+    u4 i;
+    x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
+    for (i=0; i<20; ++i) {
+        (void)ranval(x);
+    }
+}
+
+/*****************************************************************************/
+
+#define BUFSIZE (8 * 1024 * 1024)
+#define N 50
+
+void bench (void)
+{
+    double t1, t2;
+    int i;
+    prng_t prng;
+    uint8_t *buf = aligned_malloc (16, BUFSIZE + 1);
+
+    prng_srand_r (&prng, 1234);
+    t1 = gettime();
+    for (i = 0; i < N; i++)
+        prng_randmemset_r (&prng, buf, BUFSIZE, 0);
+    t2 = gettime();
+    printf ("aligned randmemset                    : %.2f MB/s\n",
+            (double)BUFSIZE * N / 1000000. / (t2 - t1));
+
+    t1 = gettime();
+    for (i = 0; i < N; i++)
+        prng_randmemset_r (&prng, buf + 1, BUFSIZE, 0);
+    t2 = gettime();
+    printf ("unaligned randmemset                  : %.2f MB/s\n",
+            (double)BUFSIZE * N / 1000000. / (t2 - t1));
+
+    t1 = gettime();
+    for (i = 0; i < N; i++)
+    {
+        prng_randmemset_r (&prng, buf, BUFSIZE, RANDMEMSET_MORE_00_AND_FF);
+    }
+    t2 = gettime ();
+    printf ("aligned randmemset (more 00 and FF)   : %.2f MB/s\n",
+            (double)BUFSIZE * N / 1000000. / (t2 - t1));
+
+    t1 = gettime();
+    for (i = 0; i < N; i++)
+    {
+        prng_randmemset_r (&prng, buf + 1, BUFSIZE, RANDMEMSET_MORE_00_AND_FF);
+    }
+    t2 = gettime ();
+    printf ("unaligned randmemset (more 00 and FF) : %.2f MB/s\n",
+            (double)BUFSIZE * N / 1000000. / (t2 - t1));
+
+    free (buf);
+}
+
+#define SMALLBUFSIZE 100
+
+int main (int argc, char *argv[])
+{
+    const uint32_t ref_crc[RANDMEMSET_MORE_00_AND_FF + 1] =
+    {
+        0xBA06763D, 0x103FC550, 0x8B59ABA5, 0xD82A0F39
+    };
+    uint32_t crc1, crc2;
+    uint32_t ref, seed, seed0, seed1, seed2, seed3;
+    prng_rand_128_data_t buf;
+    uint8_t *bytebuf = aligned_malloc(16, SMALLBUFSIZE + 1);
+    ranctx x;
+    prng_t prng;
+    prng_randmemset_flags_t flags;
+
+    if (argc > 1 && strcmp(argv[1], "-bench") == 0)
+    {
+        bench ();
+        return 0;
+    }
+
+    /* basic test */
+    raninit (&x, 0);
+    prng_srand_r (&prng, 0);
+    assert (ranval (&x) == prng_rand_r (&prng));
+
+    /* test for simd code */
+    seed = 0;
+    prng_srand_r (&prng, seed);
+    seed0 = (seed = seed * 1103515245 + 12345);
+    seed1 = (seed = seed * 1103515245 + 12345);
+    seed2 = (seed = seed * 1103515245 + 12345);
+    seed3 = (seed = seed * 1103515245 + 12345);
+    prng_rand_128_r (&prng, &buf);
+
+    raninit (&x, seed0);
+    ref = ranval (&x);
+    assert (ref == buf.w[0]);
+
+    raninit (&x, seed1);
+    ref = ranval (&x);
+    assert (ref == buf.w[1]);
+
+    raninit (&x, seed2);
+    ref = ranval (&x);
+    assert (ref == buf.w[2]);
+
+    raninit (&x, seed3);
+    ref = ranval (&x);
+    assert (ref == buf.w[3]);
+
+    /* test for randmemset */
+    for (flags = 0; flags <= RANDMEMSET_MORE_00_AND_FF; flags++)
+    {
+        prng_srand_r (&prng, 1234);
+        prng_randmemset_r (&prng, bytebuf, 16, flags);
+        prng_randmemset_r (&prng, bytebuf + 16, SMALLBUFSIZE - 17, flags);
+        crc1 = compute_crc32 (0, bytebuf, SMALLBUFSIZE - 1);
+        prng_srand_r (&prng, 1234);
+        prng_randmemset_r (&prng, bytebuf + 1, SMALLBUFSIZE - 1, flags);
+        crc2 = compute_crc32 (0, bytebuf + 1, SMALLBUFSIZE - 1);
+        assert (ref_crc[flags] == crc1);
+        assert (ref_crc[flags] == crc2);
+    }
+
+    free (bytebuf);
+
+    return 0;
+}
diff --git a/test/utils-prng.c b/test/utils-prng.c
new file mode 100644
index 0000000..7c2dd6a
--- /dev/null
+++ b/test/utils-prng.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka at gmail.com>
+ *
+ * Based on the public domain implementation of small noncryptographic PRNG
+ * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "utils.h"
+#include "utils-prng.h"
+
+void smallprng_srand_r (smallprng_t *x, uint32_t seed)
+{
+    uint32_t i;
+    x->a = 0xf1ea5eed, x->b = x->c = x->d = seed;
+    for (i = 0; i < 20; ++i)
+        smallprng_rand_r (x);
+}
+
+/*
+ * Set a 32-bit seed for PRNG
+ *
+ * LCG is used here for generating independent seeds for different
+ * smallprng instances (in the case if smallprng is also used for
+ * generating these seeds, "Big Crush" test from TestU01 detects
+ * some problems in the glued 'prng_rand_128_r' output data).
+ * Actually we might be even better using some cryptographic
+ * hash for this purpose, but LCG seems to be also enough for
+ * passing "Big Crush".
+ */
+void prng_srand_r (prng_t *x, uint32_t seed)
+{
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+    int i;
+    prng_rand_128_data_t dummy;
+    smallprng_srand_r (&x->p0, seed);
+    x->a[0] = x->a[1] = x->a[2] = x->a[3] = 0xf1ea5eed;
+    x->b[0] = x->c[0] = x->d[0] = (seed = seed * 1103515245 + 12345);
+    x->b[1] = x->c[1] = x->d[1] = (seed = seed * 1103515245 + 12345);
+    x->b[2] = x->c[2] = x->d[2] = (seed = seed * 1103515245 + 12345);
+    x->b[3] = x->c[3] = x->d[3] = (seed = seed * 1103515245 + 12345);
+    for (i = 0; i < 20; ++i)
+        prng_rand_128_r (x, &dummy);
+#else
+    smallprng_srand_r (&x->p0, seed);
+    smallprng_srand_r (&x->p1, (seed = seed * 1103515245 + 12345));
+    smallprng_srand_r (&x->p2, (seed = seed * 1103515245 + 12345));
+    smallprng_srand_r (&x->p3, (seed = seed * 1103515245 + 12345));
+    smallprng_srand_r (&x->p4, (seed = seed * 1103515245 + 12345));
+#endif
+}
+
+static force_inline void
+store_rand_128_data (void *addr, prng_rand_128_data_t *d, int aligned)
+{
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+    if (aligned)
+    {
+        *(uint8x16 *)addr = d->vb;
+        return;
+    }
+#endif
+    /* we could try something better for unaligned writes (packed attribute),
+     * but GCC is not very reliable: http://gcc.gnu.org/PR55454 */
+    memcpy (addr, d, 16);
+}
+
+/*
+ * Helper function and the actual code for "prng_randmemset_r" function
+ */
+static force_inline void
+randmemset_internal (prng_t                  *prng,
+                     uint8_t                 *buf,
+                     size_t                   size,
+                     prng_randmemset_flags_t  flags,
+                     int                      aligned)
+{
+    prng_t local_prng = *prng;
+    prng_rand_128_data_t randdata;
+
+    while (size >= 16)
+    {
+        prng_rand_128_data_t t;
+        if (flags == 0)
+        {
+            prng_rand_128_r (&local_prng, &randdata);
+        }
+        else
+        {
+            prng_rand_128_r (&local_prng, &t);
+            prng_rand_128_r (&local_prng, &randdata);
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+            if (flags & RANDMEMSET_MORE_FF)
+            {
+                const uint8x16 const_C0 =
+                {
+                    0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
+                    0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0
+                };
+                randdata.vb |= (t.vb >= const_C0);
+            }
+            if (flags & RANDMEMSET_MORE_00)
+            {
+                const uint8x16 const_40 =
+                {
+                    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
+                    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
+                };
+                randdata.vb &= (t.vb >= const_40);
+            }
+#else
+            #define PROCESS_ONE_LANE(i)                                       \
+                if (flags & RANDMEMSET_MORE_FF)                               \
+                {                                                             \
+                    uint32_t mask_ff = (t.w[i] & (t.w[i] << 1)) & 0x80808080; \
+                    mask_ff |= mask_ff >> 1;                                  \
+                    mask_ff |= mask_ff >> 2;                                  \
+                    mask_ff |= mask_ff >> 4;                                  \
+                    randdata.w[i] |= mask_ff;                                 \
+                }                                                             \
+                if (flags & RANDMEMSET_MORE_00)                               \
+                {                                                             \
+                    uint32_t mask_00 = (t.w[i] | (t.w[i] << 1)) & 0x80808080; \
+                    mask_00 |= mask_00 >> 1;                                  \
+                    mask_00 |= mask_00 >> 2;                                  \
+                    mask_00 |= mask_00 >> 4;                                  \
+                    randdata.w[i] &= mask_00;                                 \
+                }
+
+            PROCESS_ONE_LANE (0)
+            PROCESS_ONE_LANE (1)
+            PROCESS_ONE_LANE (2)
+            PROCESS_ONE_LANE (3)
+#endif
+        }
+        if (is_little_endian ())
+        {
+            store_rand_128_data (buf, &randdata, aligned);
+            buf += 16;
+        }
+        else
+        {
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+            const uint8x16 bswap_shufflemask =
+            {
+                3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
+            };
+            randdata.vb = __builtin_shuffle (randdata.vb, bswap_shufflemask);
+            store_rand_128_data (buf, &randdata, aligned);
+            buf += 16;
+#else
+            uint8_t t1, t2, t3, t4;
+            #define STORE_ONE_LANE(i)                                         \
+                t1 = randdata.b[i * 4 + 3];                                   \
+                t2 = randdata.b[i * 4 + 2];                                   \
+                t3 = randdata.b[i * 4 + 1];                                   \
+                t4 = randdata.b[i * 4 + 0];                                   \
+                *buf++ = t1;                                                  \
+                *buf++ = t2;                                                  \
+                *buf++ = t3;                                                  \
+                *buf++ = t4;
+
+            STORE_ONE_LANE (0)
+            STORE_ONE_LANE (1)
+            STORE_ONE_LANE (2)
+            STORE_ONE_LANE (3)
+#endif
+        }
+        size -= 16;
+    }
+    while (size > 0)
+    {
+        uint8_t randbyte = prng_rand_r (&local_prng) & 0xFF;
+        if (flags != 0)
+        {
+            uint8_t t = prng_rand_r (&local_prng) & 0xFF;
+            if ((flags & RANDMEMSET_MORE_FF) && (t >= 0xC0))
+                randbyte = 0xFF;
+            if ((flags & RANDMEMSET_MORE_00) && (t < 0x40))
+                randbyte = 0x00;
+        }
+        *buf++ = randbyte;
+        size--;
+    }
+    *prng = local_prng;
+}
+
+/*
+ * Fill memory buffer with random data. Flags argument may be used
+ * to tweak some statistics properties:
+ *    RANDMEMSET_MORE_00 - set ~25% of bytes to 0x00
+ *    RANDMEMSET_MORE_FF - set ~25% of bytes to 0xFF
+ */
+void prng_randmemset_r (prng_t                  *prng,
+                        void                    *voidbuf,
+                        size_t                   size,
+                        prng_randmemset_flags_t  flags)
+{
+    uint8_t *buf = (uint8_t *)voidbuf;
+    if ((uintptr_t)buf & 15)
+    {
+        /* unaligned buffer */
+        if (flags == 0)
+            randmemset_internal (prng, buf, size, 0, 0);
+        else if (flags == RANDMEMSET_MORE_00_AND_FF)
+            randmemset_internal (prng, buf, size, RANDMEMSET_MORE_00_AND_FF, 0);
+        else
+            randmemset_internal (prng, buf, size, flags, 0);
+    }
+    else
+    {
+        /* aligned buffer */
+        if (flags == 0)
+            randmemset_internal (prng, buf, size, 0, 1);
+        else if (flags == RANDMEMSET_MORE_00_AND_FF)
+            randmemset_internal (prng, buf, size, RANDMEMSET_MORE_00_AND_FF, 1);
+        else
+            randmemset_internal (prng, buf, size, flags, 1);
+    }
+}
diff --git a/test/utils-prng.h b/test/utils-prng.h
new file mode 100644
index 0000000..285107f
--- /dev/null
+++ b/test/utils-prng.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright © 2012 Siarhei Siamashka <siarhei.siamashka at gmail.com>
+ *
+ * Based on the public domain implementation of small noncryptographic PRNG
+ * authored by Bob Jenkins: http://burtleburtle.net/bob/rand/smallprng.html
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __UTILS_PRNG_H__
+#define __UTILS_PRNG_H__
+
+/*
+ * This file provides a fast SIMD-optimized noncryptographic PRNG (pseudorandom
+ * number generator), with the output good enough to pass "Big Crush" tests
+ * from TestU01 (http://en.wikipedia.org/wiki/TestU01).
+ *
+ * SIMD code uses http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html
+ * which is a GCC specific extension. There is also a slower alternative
+ * code path, which should work with any C compiler.
+ *
+ * The "prng_t" structure keeps the internal state of the random number
+ * generator. It is possible to have multiple instances of the random number
+ * generator active at the same time, in this case each of them needs to have
+ * its own "prng_t". All the functions take a pointer to "prng_t"
+ * as the first argument.
+ *
+ * Functions:
+ *
+ * ----------------------------------------------------------------------------
+ * void prng_srand_r (prng_t *prng, uint32_t seed);
+ *
+ * Initialize the pseudorandom number generator. The sequence of preudorandom
+ * numbers is deterministic and only depends on "seed". Any two generators
+ * initialized with the same seed will produce exactly the same sequence.
+ *
+ * ----------------------------------------------------------------------------
+ * uint32_t prng_rand_r (prng_t *prng);
+ *
+ * Generate a single uniformly distributed 32-bit pseudorandom value.
+ *
+ * ----------------------------------------------------------------------------
+ * void prng_randmemset_r (prng_t                  *prng,
+ *                         void                    *buffer,
+ *                         size_t                   size,
+ *                         prng_randmemset_flags_t  flags);
+ *
+ * Fills the memory buffer "buffer" with "size" bytes of pseudorandom data.
+ * The "flags" argument may be used to tweak some statistics properties:
+ *    RANDMEMSET_MORE_00 - set ~25% of bytes to 0x00
+ *    RANDMEMSET_MORE_FF - set ~25% of bytes to 0xFF
+ * The flags can be combined. This allows a bit better simulation of typical
+ * pixel data, which normally contains a lot of fully transparent or fully
+ * opaque pixels.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "pixman-private.h"
+
+/*****************************************************************************/
+
+#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+#define GCC_VECTOR_EXTENSIONS_SUPPORTED
+typedef uint32_t uint32x4 __attribute__ ((vector_size(16)));
+typedef uint8_t  uint8x16 __attribute__ ((vector_size(16)));
+#endif
+
+typedef struct
+{
+    uint32_t a, b, c, d;
+} smallprng_t;
+
+typedef struct
+{
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+    uint32x4 a, b, c, d;
+#else
+    smallprng_t p1, p2, p3, p4;
+#endif
+    smallprng_t p0;
+} prng_t;
+
+typedef union
+{
+    uint8_t  b[16];
+    uint32_t w[4];
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+    uint8x16 vb;
+    uint32x4 vw;
+#endif
+} prng_rand_128_data_t;
+
+/*****************************************************************************/
+
+static force_inline uint32_t
+smallprng_rand_r (smallprng_t *x)
+{
+    uint32_t e = x->a - ((x->b << 27) + (x->b >> (32 - 27)));
+    x->a = x->b ^ ((x->c << 17) ^ (x->c >> (32 - 17)));
+    x->b = x->c + x->d;
+    x->c = x->d + e;
+    x->d = e + x->a;
+    return x->d;
+}
+
+/* Generate 4 bytes (32-bits) of random data */
+static force_inline uint32_t
+prng_rand_r (prng_t *x)
+{
+    return smallprng_rand_r (&x->p0);
+}
+
+/* Generate 16 bytes (128-bits) of random data */
+static force_inline void
+prng_rand_128_r (prng_t *x, prng_rand_128_data_t *data)
+{
+#ifdef GCC_VECTOR_EXTENSIONS_SUPPORTED
+    uint32x4 e = x->a - ((x->b << 27) + (x->b >> (32 - 27)));
+    x->a = x->b ^ ((x->c << 17) ^ (x->c >> (32 - 17)));
+    x->b = x->c + x->d;
+    x->c = x->d + e;
+    x->d = e + x->a;
+    data->vw = x->d;
+#else
+    data->w[0] = smallprng_rand_r (&x->p1);
+    data->w[1] = smallprng_rand_r (&x->p2);
+    data->w[2] = smallprng_rand_r (&x->p3);
+    data->w[3] = smallprng_rand_r (&x->p4);
+#endif
+}
+
+typedef enum
+{
+    RANDMEMSET_MORE_00        = 1, /* ~25% chance for 0x00 bytes */
+    RANDMEMSET_MORE_FF        = 2, /* ~25% chance for 0xFF bytes */
+    RANDMEMSET_MORE_00_AND_FF = (RANDMEMSET_MORE_00 | RANDMEMSET_MORE_FF)
+} prng_randmemset_flags_t;
+
+/* Set the 32-bit seed for PRNG */
+void prng_srand_r (prng_t *prng, uint32_t seed);
+
+/* Fill memory buffer with random data */
+void prng_randmemset_r (prng_t                  *prng,
+                        void                    *buffer,
+                        size_t                   size,
+                        prng_randmemset_flags_t  flags);
+
+#endif
commit 41f98a07fc3235b64713a39238238801304ac346
Author: Siarhei Siamashka <siarhei.siamashka at gmail.com>
Date:   Fri Nov 23 09:07:23 2012 +0200

    test: Change is_little_endian() into inline function
    
    Also dropped redundant volatile keyword because any object
    can be accessed via char* pointer without breaking aliasing
    rules. The compilers are able to optimize this function to either
    constant 0 or 1.

diff --git a/test/utils.c b/test/utils.c
index c887a6d..00e74e5 100644
--- a/test/utils.c
+++ b/test/utils.c
@@ -237,14 +237,6 @@ compute_crc32_for_image (uint32_t        crc32,
     return crc32;
 }
 
-pixman_bool_t
-is_little_endian (void)
-{
-    volatile uint16_t endian_check_var = 0x1234;
-
-    return (*(volatile uint8_t *)&endian_check_var == 0x34);
-}
-
 /* perform endian conversion of pixel data
  */
 void
diff --git a/test/utils.h b/test/utils.h
index f7ea34c..fa05587 100644
--- a/test/utils.h
+++ b/test/utils.h
@@ -69,8 +69,12 @@ compute_crc32_for_image (uint32_t        in_crc32,
 
 /* Returns TRUE if running on a little endian system
  */
-pixman_bool_t
-is_little_endian (void);
+static force_inline pixman_bool_t
+is_little_endian (void)
+{
+    unsigned long endian_check_var = 1;
+    return *(unsigned char *)&endian_check_var == 1;
+}
 
 /* perform endian conversion of pixel data
  */


More information about the xorg-commit mailing list