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

Andrea Canciani ranma42 at gmail.com
Sat Sep 28 10:59:00 PDT 2013


I have some work on memleak related issues:

http://cgit.freedesktop.org/~ranma42/pixman/commit/?h=wip/simpleops-to-master&id=77db90242f7b7f12c5792480a10eb3a448e6c55f
and
http://cgit.freedesktop.org/~ranma42/pixman/commit/?h=wip/simpleops-to-master&id=ca41228a66fe9bbec354cdef034c144ce1619793

Do you think it might be worth to revive it and cleanup for review & merge?
Unfortunately they depend on simpleops, a header-library I wrote to
abstract (from compiler/platform) some low-level operations, like atomic
arithmetics, mutexes, threads and library constructors/destructors.
(currently all of them except init/fini are available in C11 and the
simpleops API tries to be as similar to C11 as possible, to ease C11-based
implementations and to make it easy to get rid of the simpleops dependency
when C11 support is sufficiently widespread).
Would it be ok to have it as dependency?

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/20130928/bbe1619e/attachment-0001.html>


More information about the Pixman mailing list