<div dir="ltr"><div><div><div><div><div><div>I have some work on memleak related issues:<br><br><a href="http://cgit.freedesktop.org/~ranma42/pixman/commit/?h=wip/simpleops-to-master&id=77db90242f7b7f12c5792480a10eb3a448e6c55f">http://cgit.freedesktop.org/~ranma42/pixman/commit/?h=wip/simpleops-to-master&id=77db90242f7b7f12c5792480a10eb3a448e6c55f</a><br>
and<br></div><a href="http://cgit.freedesktop.org/~ranma42/pixman/commit/?h=wip/simpleops-to-master&id=ca41228a66fe9bbec354cdef034c144ce1619793">http://cgit.freedesktop.org/~ranma42/pixman/commit/?h=wip/simpleops-to-master&id=ca41228a66fe9bbec354cdef034c144ce1619793</a><br>
<br></div>Do you think it might be worth to revive it and cleanup for review & merge?<br></div>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).<br>
</div>Would it be ok to have it as dependency?<br></div><br></div>Andrea<br><div><div><div><div><div><br><br></div></div></div></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Sep 28, 2013 at 5:38 PM, Sĝren Sandmann <span dir="ltr"><<a href="mailto:sandmann@cs.au.dk" target="_blank">sandmann@cs.au.dk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Sĝren Sandmann Pedersen <<a href="mailto:ssp@redhat.com">ssp@redhat.com</a>><br>
<br>
This test program allocates an array of 16 uint32_ts and spawns 16<br>
threads that each use one of the allocated uint32_ts as destination<br>
for a large number of composite operations. Each thread then checks<br>
whether the results have the right crc32 checksum.<br>
<br>
The purpose of this test is catch errors where memory outside images<br>
is read and then written back. Such out-of-bounds accesses are broken<br>
when multiple threads are involved.<br>
---<br>
 test/Makefile.am      |    6 +-<br>
 test/Makefile.sources |    1 +<br>
 test/thread-test.c    |  183 +++++++++++++++++++++++++++++++++++++++++++++++++<br>
 3 files changed, 187 insertions(+), 3 deletions(-)<br>
 create mode 100644 test/thread-test.c<br>
<br>
diff --git a/test/Makefile.am b/test/Makefile.am<br>
index 5d901d5..80f3537 100644<br>
--- a/test/Makefile.am<br>
+++ b/test/Makefile.am<br>
@@ -1,8 +1,8 @@<br>
 include $(top_srcdir)/test/Makefile.sources<br>
<br>
-AM_CFLAGS = $(OPENMP_CFLAGS)<br>
-AM_LDFLAGS = $(OPENMP_CFLAGS) $(TESTPROGS_EXTRA_LDFLAGS)<br>
-LDADD = <a href="http://libutils.la" target="_blank">libutils.la</a> $(top_builddir)/pixman/<a href="http://libpixman-1.la" target="_blank">libpixman-1.la</a> -lm  $(PNG_LIBS)<br>
+AM_CFLAGS = $(OPENMP_CFLAGS) $(PTHREAD_CFLAGS)$<br>
+AM_LDFLAGS = $(OPENMP_CFLAGS) $(TESTPROGS_EXTRA_LDFLAGS) $(PTHREAD_LDFLAGS)<br>
+LDADD = <a href="http://libutils.la" target="_blank">libutils.la</a> $(top_builddir)/pixman/<a href="http://libpixman-1.la" target="_blank">libpixman-1.la</a> -lm  $(PNG_LIBS) $(PTHREAD_LIBS)<br>
 AM_CPPFLAGS = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman $(PNG_CFLAGS)<br>
<br>
 libutils_la_SOURCES = $(libutils_sources) $(libutils_headers)<br>
diff --git a/test/Makefile.sources b/test/Makefile.sources<br>
index 2fabdb5..2ae5d9f 100644<br>
--- a/test/Makefile.sources<br>
+++ b/test/Makefile.sources<br>
@@ -13,6 +13,7 @@ TESTPROGRAMS =                        \<br>
        infinite-loop           \<br>
        trap-crasher            \<br>
        alpha-loop              \<br>
+       thread-test             \<br>
        scaling-crash-test      \<br>
        scaling-helpers-test    \<br>
        gradient-crash-test     \<br>
diff --git a/test/thread-test.c b/test/thread-test.c<br>
new file mode 100644<br>
index 0000000..917f417<br>
--- /dev/null<br>
+++ b/test/thread-test.c<br>
@@ -0,0 +1,183 @@<br>
+#include <config.h><br>
+<br>
+#ifndef HAVE_PTHREADS<br>
+<br>
+int main ()<br>
+{<br>
+    printf ("Skipped thread-test - pthreads not supported\n");<br>
+    return 0;<br>
+}<br>
+<br>
+#else<br>
+<br>
+#include <stdlib.h><br>
+#include <pthread.h><br>
+#include "utils.h"<br>
+<br>
+typedef struct<br>
+{<br>
+    int thread_no;<br>
+    uint32_t *dest;<br>
+    uint32_t crc32;<br>
+} info_t;<br>
+<br>
+static const pixman_op_t operators[] =<br>
+{<br>
+    PIXMAN_OP_SRC,<br>
+    PIXMAN_OP_OVER,<br>
+    PIXMAN_OP_ADD,<br>
+    PIXMAN_OP_CLEAR,<br>
+    PIXMAN_OP_SRC,<br>
+    PIXMAN_OP_DST,<br>
+    PIXMAN_OP_OVER,<br>
+    PIXMAN_OP_OVER_REVERSE,<br>
+    PIXMAN_OP_IN,<br>
+    PIXMAN_OP_IN_REVERSE,<br>
+    PIXMAN_OP_OUT,<br>
+    PIXMAN_OP_OUT_REVERSE,<br>
+    PIXMAN_OP_ATOP,<br>
+    PIXMAN_OP_ATOP_REVERSE,<br>
+    PIXMAN_OP_XOR,<br>
+    PIXMAN_OP_ADD,<br>
+    PIXMAN_OP_SATURATE,<br>
+    PIXMAN_OP_DISJOINT_CLEAR,<br>
+    PIXMAN_OP_DISJOINT_SRC,<br>
+    PIXMAN_OP_DISJOINT_DST,<br>
+    PIXMAN_OP_DISJOINT_OVER,<br>
+    PIXMAN_OP_DISJOINT_OVER_REVERSE,<br>
+    PIXMAN_OP_DISJOINT_IN,<br>
+    PIXMAN_OP_DISJOINT_IN_REVERSE,<br>
+    PIXMAN_OP_DISJOINT_OUT,<br>
+    PIXMAN_OP_DISJOINT_OUT_REVERSE,<br>
+    PIXMAN_OP_DISJOINT_ATOP,<br>
+    PIXMAN_OP_DISJOINT_ATOP_REVERSE,<br>
+    PIXMAN_OP_DISJOINT_XOR,<br>
+    PIXMAN_OP_CONJOINT_CLEAR,<br>
+    PIXMAN_OP_CONJOINT_SRC,<br>
+    PIXMAN_OP_CONJOINT_DST,<br>
+    PIXMAN_OP_CONJOINT_OVER,<br>
+    PIXMAN_OP_CONJOINT_OVER_REVERSE,<br>
+    PIXMAN_OP_CONJOINT_IN,<br>
+    PIXMAN_OP_CONJOINT_IN_REVERSE,<br>
+    PIXMAN_OP_CONJOINT_OUT,<br>
+    PIXMAN_OP_CONJOINT_OUT_REVERSE,<br>
+    PIXMAN_OP_CONJOINT_ATOP,<br>
+    PIXMAN_OP_CONJOINT_ATOP_REVERSE,<br>
+    PIXMAN_OP_CONJOINT_XOR,<br>
+    PIXMAN_OP_MULTIPLY,<br>
+    PIXMAN_OP_SCREEN,<br>
+    PIXMAN_OP_OVERLAY,<br>
+    PIXMAN_OP_DARKEN,<br>
+    PIXMAN_OP_LIGHTEN,<br>
+    PIXMAN_OP_COLOR_DODGE,<br>
+    PIXMAN_OP_COLOR_BURN,<br>
+    PIXMAN_OP_HARD_LIGHT,<br>
+    PIXMAN_OP_DIFFERENCE,<br>
+    PIXMAN_OP_EXCLUSION,<br>
+};<br>
+<br>
+static const pixman_format_code_t formats[] =<br>
+{<br>
+    PIXMAN_a8r8g8b8,<br>
+    PIXMAN_r5g6b5,<br>
+    PIXMAN_a8,<br>
+    PIXMAN_a4,<br>
+    PIXMAN_a1,<br>
+    PIXMAN_b5g6r5,<br>
+    PIXMAN_r8g8b8a8,<br>
+    PIXMAN_a4r4g4b4<br>
+};<br>
+<br>
+#define N_ROUNDS 32768<br>
+<br>
+#define RAND_ELT(arr)                                                  \<br>
+    arr[prng_rand() % ARRAY_LENGTH (arr)]<br>
+<br>
+static void *<br>
+thread (void *data)<br>
+{<br>
+    info_t *info = data;<br>
+    uint32_t crc32 = 0x0;<br>
+    uint32_t src_buf[64];<br>
+    pixman_image_t *dst_img, *src_img;<br>
+    int i;<br>
+<br>
+    prng_srand (info->thread_no);<br>
+<br>
+    for (i = 0; i < N_ROUNDS; ++i)<br>
+    {<br>
+       *info->dest = prng_rand();<br>
+<br>
+       prng_randmemset (src_buf, sizeof (src_buf), 0);<br>
+<br>
+       src_img = pixman_image_create_bits (<br>
+           RAND_ELT (formats), 4, 4, src_buf, 16);<br>
+       dst_img = pixman_image_create_bits (<br>
+           RAND_ELT (formats), 1, 1, info->dest, 4);<br>
+<br>
+       pixman_image_composite32 (<br>
+           RAND_ELT (operators),<br>
+           src_img, NULL, dst_img,<br>
+           prng_rand() % 4, prng_rand() % 4, 0, 0, 0, 0, 1, 1);<br>
+<br>
+       crc32 = compute_crc32_for_image (crc32, dst_img);<br>
+<br>
+       pixman_image_unref (src_img);<br>
+       pixman_image_unref (dst_img);<br>
+    }<br>
+<br>
+    if (crc32 != info->crc32)<br>
+    {<br>
+       printf ("%d failed. Got checksum %8x, expected %8x\n",<br>
+               info->thread_no, crc32, info->crc32);<br>
+<br>
+       return (void *)1;<br>
+    }<br>
+<br>
+    return (void *)0;<br>
+}<br>
+<br>
+static const uint32_t crcs[16] =<br>
+{<br>
+    0xb42c65bb, 0xe158c0b7, 0x264b1740, 0xfebca54f,<br>
+    0xa6d752fe, 0x505b761a, 0x904c6244, 0xebc8a645,<br>
+    0x95d05ba0, 0xadee4db2, 0xb38ef0c2, 0x6d97958b,<br>
+    0x24c08d73, 0x3b0396b8, 0x117f98d4, 0xe1ab6e51,<br>
+};<br>
+<br>
+int<br>
+main ()<br>
+{<br>
+    uint32_t dest[16];<br>
+    info_t info[16] = { { 0 } };<br>
+    pthread_t threads[16];<br>
+    void *retvals[16];<br>
+    int i;<br>
+<br>
+    for (i = 0; i < 16; ++i)<br>
+    {<br>
+       info[i].thread_no = i;<br>
+       info[i].dest = &dest[i];<br>
+       info[i].crc32 = crcs[i];<br>
+    }<br>
+<br>
+    for (i = 0; i < 16; ++i)<br>
+       pthread_create (&threads[i], NULL, thread, &info[i]);<br>
+<br>
+    for (i = 0; i < 16; ++i)<br>
+       pthread_join (threads[i], &retvals[i]);<br>
+<br>
+    for (i = 0; i < 16; ++i)<br>
+    {<br>
+       if (retvals[i] != (void *)0)<br>
+       {<br>
+           printf ("thread-test failed\n");<br>
+           return 1;<br>
+       }<br>
+    }<br>
+<br>
+    return 0;<br>
+}<br>
+<br>
+#endif<br>
+<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.1<br>
<br>
_______________________________________________<br>
Pixman mailing list<br>
<a href="mailto:Pixman@lists.freedesktop.org">Pixman@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/pixman" target="_blank">http://lists.freedesktop.org/mailman/listinfo/pixman</a><br>
</font></span></blockquote></div><br></div>