[Pixman] [PATCH 2/2] test: Add new thread-test program

Andrea Canciani ranma42 at gmail.com
Wed Oct 9 06:00:44 PDT 2013


Sorry, I didn't realize it beforehand, but I just noticed that thread-test
fails on MacOS.
This happens because it relies on the availability of OpenMP to have a
thread-local state for the prng.
Would it be ok to have each thread explicitly keep the state of its prng or
is this another element that the test is supposed to be checking?

Andrea

On Sat, Sep 28, 2013 at 5:38 PM, Søren Sandmann <sandmann at cs.au.dk> wrote:

> From: Søren Sandmann Pedersen <ssp at redhat.com>
>
> This test program allocates an array of 16 uint32_ts and spawns 16
> threads that each use one of the allocated uint32_ts as destination
> for a large number of composite operations. Each thread then checks
> whether the results have the right crc32 checksum.
>
> The purpose of this test is catch errors where memory outside images
> is read and then written back. Such out-of-bounds accesses are broken
> when multiple threads are involved.
> ---
>  test/Makefile.am      |    6 +-
>  test/Makefile.sources |    1 +
>  test/thread-test.c    |  183
> +++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 187 insertions(+), 3 deletions(-)
>  create mode 100644 test/thread-test.c
>
> diff --git a/test/Makefile.am b/test/Makefile.am
> index 5d901d5..80f3537 100644
> --- a/test/Makefile.am
> +++ b/test/Makefile.am
> @@ -1,8 +1,8 @@
>  include $(top_srcdir)/test/Makefile.sources
>
> -AM_CFLAGS = $(OPENMP_CFLAGS)
> -AM_LDFLAGS = $(OPENMP_CFLAGS) $(TESTPROGS_EXTRA_LDFLAGS)
> -LDADD = libutils.la $(top_builddir)/pixman/libpixman-1.la -lm
>  $(PNG_LIBS)
> +AM_CFLAGS = $(OPENMP_CFLAGS) $(PTHREAD_CFLAGS)$
> +AM_LDFLAGS = $(OPENMP_CFLAGS) $(TESTPROGS_EXTRA_LDFLAGS)
> $(PTHREAD_LDFLAGS)
> +LDADD = libutils.la $(top_builddir)/pixman/libpixman-1.la -lm
>  $(PNG_LIBS) $(PTHREAD_LIBS)
>  AM_CPPFLAGS = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
> $(PNG_CFLAGS)
>
>  libutils_la_SOURCES = $(libutils_sources) $(libutils_headers)
> diff --git a/test/Makefile.sources b/test/Makefile.sources
> index 2fabdb5..2ae5d9f 100644
> --- a/test/Makefile.sources
> +++ b/test/Makefile.sources
> @@ -13,6 +13,7 @@ TESTPROGRAMS =                        \
>         infinite-loop           \
>         trap-crasher            \
>         alpha-loop              \
> +       thread-test             \
>         scaling-crash-test      \
>         scaling-helpers-test    \
>         gradient-crash-test     \
> diff --git a/test/thread-test.c b/test/thread-test.c
> new file mode 100644
> index 0000000..917f417
> --- /dev/null
> +++ b/test/thread-test.c
> @@ -0,0 +1,183 @@
> +#include <config.h>
> +
> +#ifndef HAVE_PTHREADS
> +
> +int main ()
> +{
> +    printf ("Skipped thread-test - pthreads not supported\n");
> +    return 0;
> +}
> +
> +#else
> +
> +#include <stdlib.h>
> +#include <pthread.h>
> +#include "utils.h"
> +
> +typedef struct
> +{
> +    int thread_no;
> +    uint32_t *dest;
> +    uint32_t crc32;
> +} info_t;
> +
> +static const pixman_op_t operators[] =
> +{
> +    PIXMAN_OP_SRC,
> +    PIXMAN_OP_OVER,
> +    PIXMAN_OP_ADD,
> +    PIXMAN_OP_CLEAR,
> +    PIXMAN_OP_SRC,
> +    PIXMAN_OP_DST,
> +    PIXMAN_OP_OVER,
> +    PIXMAN_OP_OVER_REVERSE,
> +    PIXMAN_OP_IN,
> +    PIXMAN_OP_IN_REVERSE,
> +    PIXMAN_OP_OUT,
> +    PIXMAN_OP_OUT_REVERSE,
> +    PIXMAN_OP_ATOP,
> +    PIXMAN_OP_ATOP_REVERSE,
> +    PIXMAN_OP_XOR,
> +    PIXMAN_OP_ADD,
> +    PIXMAN_OP_SATURATE,
> +    PIXMAN_OP_DISJOINT_CLEAR,
> +    PIXMAN_OP_DISJOINT_SRC,
> +    PIXMAN_OP_DISJOINT_DST,
> +    PIXMAN_OP_DISJOINT_OVER,
> +    PIXMAN_OP_DISJOINT_OVER_REVERSE,
> +    PIXMAN_OP_DISJOINT_IN,
> +    PIXMAN_OP_DISJOINT_IN_REVERSE,
> +    PIXMAN_OP_DISJOINT_OUT,
> +    PIXMAN_OP_DISJOINT_OUT_REVERSE,
> +    PIXMAN_OP_DISJOINT_ATOP,
> +    PIXMAN_OP_DISJOINT_ATOP_REVERSE,
> +    PIXMAN_OP_DISJOINT_XOR,
> +    PIXMAN_OP_CONJOINT_CLEAR,
> +    PIXMAN_OP_CONJOINT_SRC,
> +    PIXMAN_OP_CONJOINT_DST,
> +    PIXMAN_OP_CONJOINT_OVER,
> +    PIXMAN_OP_CONJOINT_OVER_REVERSE,
> +    PIXMAN_OP_CONJOINT_IN,
> +    PIXMAN_OP_CONJOINT_IN_REVERSE,
> +    PIXMAN_OP_CONJOINT_OUT,
> +    PIXMAN_OP_CONJOINT_OUT_REVERSE,
> +    PIXMAN_OP_CONJOINT_ATOP,
> +    PIXMAN_OP_CONJOINT_ATOP_REVERSE,
> +    PIXMAN_OP_CONJOINT_XOR,
> +    PIXMAN_OP_MULTIPLY,
> +    PIXMAN_OP_SCREEN,
> +    PIXMAN_OP_OVERLAY,
> +    PIXMAN_OP_DARKEN,
> +    PIXMAN_OP_LIGHTEN,
> +    PIXMAN_OP_COLOR_DODGE,
> +    PIXMAN_OP_COLOR_BURN,
> +    PIXMAN_OP_HARD_LIGHT,
> +    PIXMAN_OP_DIFFERENCE,
> +    PIXMAN_OP_EXCLUSION,
> +};
> +
> +static const pixman_format_code_t formats[] =
> +{
> +    PIXMAN_a8r8g8b8,
> +    PIXMAN_r5g6b5,
> +    PIXMAN_a8,
> +    PIXMAN_a4,
> +    PIXMAN_a1,
> +    PIXMAN_b5g6r5,
> +    PIXMAN_r8g8b8a8,
> +    PIXMAN_a4r4g4b4
> +};
> +
> +#define N_ROUNDS 32768
> +
> +#define RAND_ELT(arr)                                                  \
> +    arr[prng_rand() % ARRAY_LENGTH (arr)]
> +
> +static void *
> +thread (void *data)
> +{
> +    info_t *info = data;
> +    uint32_t crc32 = 0x0;
> +    uint32_t src_buf[64];
> +    pixman_image_t *dst_img, *src_img;
> +    int i;
> +
> +    prng_srand (info->thread_no);
> +
> +    for (i = 0; i < N_ROUNDS; ++i)
> +    {
> +       *info->dest = prng_rand();
> +
> +       prng_randmemset (src_buf, sizeof (src_buf), 0);
> +
> +       src_img = pixman_image_create_bits (
> +           RAND_ELT (formats), 4, 4, src_buf, 16);
> +       dst_img = pixman_image_create_bits (
> +           RAND_ELT (formats), 1, 1, info->dest, 4);
> +
> +       pixman_image_composite32 (
> +           RAND_ELT (operators),
> +           src_img, NULL, dst_img,
> +           prng_rand() % 4, prng_rand() % 4, 0, 0, 0, 0, 1, 1);
> +
> +       crc32 = compute_crc32_for_image (crc32, dst_img);
> +
> +       pixman_image_unref (src_img);
> +       pixman_image_unref (dst_img);
> +    }
> +
> +    if (crc32 != info->crc32)
> +    {
> +       printf ("%d failed. Got checksum %8x, expected %8x\n",
> +               info->thread_no, crc32, info->crc32);
> +
> +       return (void *)1;
> +    }
> +
> +    return (void *)0;
> +}
> +
> +static const uint32_t crcs[16] =
> +{
> +    0xb42c65bb, 0xe158c0b7, 0x264b1740, 0xfebca54f,
> +    0xa6d752fe, 0x505b761a, 0x904c6244, 0xebc8a645,
> +    0x95d05ba0, 0xadee4db2, 0xb38ef0c2, 0x6d97958b,
> +    0x24c08d73, 0x3b0396b8, 0x117f98d4, 0xe1ab6e51,
> +};
> +
> +int
> +main ()
> +{
> +    uint32_t dest[16];
> +    info_t info[16] = { { 0 } };
> +    pthread_t threads[16];
> +    void *retvals[16];
> +    int i;
> +
> +    for (i = 0; i < 16; ++i)
> +    {
> +       info[i].thread_no = i;
> +       info[i].dest = &dest[i];
> +       info[i].crc32 = crcs[i];
> +    }
> +
> +    for (i = 0; i < 16; ++i)
> +       pthread_create (&threads[i], NULL, thread, &info[i]);
> +
> +    for (i = 0; i < 16; ++i)
> +       pthread_join (threads[i], &retvals[i]);
> +
> +    for (i = 0; i < 16; ++i)
> +    {
> +       if (retvals[i] != (void *)0)
> +       {
> +           printf ("thread-test failed\n");
> +           return 1;
> +       }
> +    }
> +
> +    return 0;
> +}
> +
> +#endif
> +
> --
> 1.7.1
>
> _______________________________________________
> Pixman mailing list
> Pixman at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/pixman
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/pixman/attachments/20131009/e0db6c8f/attachment-0001.html>


More information about the Pixman mailing list