Add qemu 2.4.0
[kvmfornfv.git] / qemu / pixman / test / thread-test.c
1 #include "utils.h"
2
3 #ifndef HAVE_PTHREADS
4
5 int main ()
6 {
7     printf ("Skipped thread-test - pthreads not supported\n");
8     return 0;
9 }
10
11 #else
12
13 #include <stdlib.h>
14 #include <pthread.h>
15
16 typedef struct
17 {
18     int       thread_no;
19     uint32_t *dst_buf;
20     prng_t    prng_state;
21 } info_t;
22
23 static const pixman_op_t operators[] = 
24 {
25     PIXMAN_OP_SRC,
26     PIXMAN_OP_OVER,
27     PIXMAN_OP_ADD,
28     PIXMAN_OP_CLEAR,
29     PIXMAN_OP_SRC,
30     PIXMAN_OP_DST,
31     PIXMAN_OP_OVER,
32     PIXMAN_OP_OVER_REVERSE,
33     PIXMAN_OP_IN,
34     PIXMAN_OP_IN_REVERSE,
35     PIXMAN_OP_OUT,
36     PIXMAN_OP_OUT_REVERSE,
37     PIXMAN_OP_ATOP,
38     PIXMAN_OP_ATOP_REVERSE,
39     PIXMAN_OP_XOR,
40     PIXMAN_OP_ADD,
41     PIXMAN_OP_SATURATE,
42     PIXMAN_OP_DISJOINT_CLEAR,
43     PIXMAN_OP_DISJOINT_SRC,
44     PIXMAN_OP_DISJOINT_DST,
45     PIXMAN_OP_DISJOINT_OVER,
46     PIXMAN_OP_DISJOINT_OVER_REVERSE,
47     PIXMAN_OP_DISJOINT_IN,
48     PIXMAN_OP_DISJOINT_IN_REVERSE,
49     PIXMAN_OP_DISJOINT_OUT,
50     PIXMAN_OP_DISJOINT_OUT_REVERSE,
51     PIXMAN_OP_DISJOINT_ATOP,
52     PIXMAN_OP_DISJOINT_ATOP_REVERSE,
53     PIXMAN_OP_DISJOINT_XOR,
54     PIXMAN_OP_CONJOINT_CLEAR,
55     PIXMAN_OP_CONJOINT_SRC,
56     PIXMAN_OP_CONJOINT_DST,
57     PIXMAN_OP_CONJOINT_OVER,
58     PIXMAN_OP_CONJOINT_OVER_REVERSE,
59     PIXMAN_OP_CONJOINT_IN,
60     PIXMAN_OP_CONJOINT_IN_REVERSE,
61     PIXMAN_OP_CONJOINT_OUT,
62     PIXMAN_OP_CONJOINT_OUT_REVERSE,
63     PIXMAN_OP_CONJOINT_ATOP,
64     PIXMAN_OP_CONJOINT_ATOP_REVERSE,
65     PIXMAN_OP_CONJOINT_XOR,
66     PIXMAN_OP_MULTIPLY,
67     PIXMAN_OP_SCREEN,
68     PIXMAN_OP_OVERLAY,
69     PIXMAN_OP_DARKEN,
70     PIXMAN_OP_LIGHTEN,
71     PIXMAN_OP_COLOR_DODGE,
72     PIXMAN_OP_COLOR_BURN,
73     PIXMAN_OP_HARD_LIGHT,
74     PIXMAN_OP_DIFFERENCE,
75     PIXMAN_OP_EXCLUSION,
76 };
77
78 static const pixman_format_code_t formats[] =
79 {
80     PIXMAN_a8r8g8b8,
81     PIXMAN_r5g6b5,
82     PIXMAN_a8,
83     PIXMAN_a4,
84     PIXMAN_a1,
85     PIXMAN_b5g6r5,
86     PIXMAN_r8g8b8a8,
87     PIXMAN_a4r4g4b4
88 };
89
90 #define N_ROUNDS 8192
91
92 #define RAND_ELT(arr)                                                   \
93     arr[prng_rand_r(&info->prng_state) % ARRAY_LENGTH (arr)]
94
95 #define DEST_WIDTH (7)
96
97 static void *
98 thread (void *data)
99 {
100     info_t *info = data;
101     uint32_t crc32 = 0x0;
102     uint32_t src_buf[64];
103     pixman_image_t *dst_img, *src_img;
104     int i;
105
106     prng_srand_r (&info->prng_state, info->thread_no);
107
108     for (i = 0; i < N_ROUNDS; ++i)
109     {
110         pixman_op_t op;
111         int rand1, rand2;
112
113         prng_randmemset_r (&info->prng_state, info->dst_buf,
114                            DEST_WIDTH * sizeof (uint32_t), 0);
115         prng_randmemset_r (&info->prng_state, src_buf,
116                            sizeof (src_buf), 0);
117
118         src_img = pixman_image_create_bits (
119             RAND_ELT (formats), 4, 4, src_buf, 16);
120         dst_img = pixman_image_create_bits (
121             RAND_ELT (formats), DEST_WIDTH, 1, info->dst_buf,
122             DEST_WIDTH * sizeof (uint32_t));
123
124         image_endian_swap (src_img);
125         image_endian_swap (dst_img);
126         
127         rand2 = prng_rand_r (&info->prng_state) % 4;
128         rand1 = prng_rand_r (&info->prng_state) % 4;
129         op = RAND_ELT (operators);
130
131         pixman_image_composite32 (
132             op,
133             src_img, NULL, dst_img,
134             rand1, rand2, 0, 0, 0, 0, DEST_WIDTH, 1);
135
136         crc32 = compute_crc32_for_image (crc32, dst_img);
137
138         pixman_image_unref (src_img);
139         pixman_image_unref (dst_img);
140     }
141
142     return (void *)(uintptr_t)crc32;
143 }
144
145 static inline uint32_t
146 byteswap32 (uint32_t x)
147 {
148     return ((x & ((uint32_t)0xFF << 24)) >> 24) |
149            ((x & ((uint32_t)0xFF << 16)) >>  8) |
150            ((x & ((uint32_t)0xFF <<  8)) <<  8) |
151            ((x & ((uint32_t)0xFF <<  0)) << 24);
152 }
153
154 int
155 main (void)
156 {
157     uint32_t dest[16 * DEST_WIDTH];
158     info_t info[16] = { { 0 } };
159     pthread_t threads[16];
160     void *retvals[16];
161     uint32_t crc32s[16], crc32;
162     int i;
163
164     for (i = 0; i < 16; ++i)
165     {
166         info[i].thread_no = i;
167         info[i].dst_buf = &dest[i * DEST_WIDTH];
168     }
169
170     for (i = 0; i < 16; ++i)
171         pthread_create (&threads[i], NULL, thread, &info[i]);
172
173     for (i = 0; i < 16; ++i)
174         pthread_join (threads[i], &retvals[i]);
175
176     for (i = 0; i < 16; ++i)
177     {
178         crc32s[i] = (uintptr_t)retvals[i];
179
180         if (is_little_endian())
181             crc32s[i] = byteswap32 (crc32s[i]);
182     }
183
184     crc32 = compute_crc32 (0, crc32s, sizeof crc32s);
185
186 #define EXPECTED 0xE299B18E
187
188     if (crc32 != EXPECTED)
189     {
190         printf ("thread-test failed. Got checksum 0x%08X, expected 0x%08X\n",
191                 crc32, EXPECTED);
192         return 1;
193     }
194
195     return 0;
196 }
197
198 #endif
199