• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "utils.h"
2 
3 #if !defined (HAVE_PTHREADS) && !defined (_WIN32)
4 
main()5 int main ()
6 {
7     printf ("Skipped thread-test - pthreads or Windows Threads not supported\n");
8     return 0;
9 }
10 
11 #else
12 
13 #include <stdlib.h>
14 
15 #ifdef HAVE_PTHREADS
16 # include <pthread.h>
17 #elif defined (_WIN32)
18 # define WIN32_LEAN_AND_MEAN
19 # include <windows.h>
20 #endif
21 
22 #define THREADS 16
23 
24 typedef struct
25 {
26     int       thread_no;
27     uint32_t *dst_buf;
28     prng_t    prng_state;
29 #if defined (_WIN32) && !defined (HAVE_PTHREADS)
30     uint32_t  crc32;
31 #endif
32 } info_t;
33 
34 static const pixman_op_t operators[] =
35 {
36     PIXMAN_OP_SRC,
37     PIXMAN_OP_OVER,
38     PIXMAN_OP_ADD,
39     PIXMAN_OP_CLEAR,
40     PIXMAN_OP_SRC,
41     PIXMAN_OP_DST,
42     PIXMAN_OP_OVER,
43     PIXMAN_OP_OVER_REVERSE,
44     PIXMAN_OP_IN,
45     PIXMAN_OP_IN_REVERSE,
46     PIXMAN_OP_OUT,
47     PIXMAN_OP_OUT_REVERSE,
48     PIXMAN_OP_ATOP,
49     PIXMAN_OP_ATOP_REVERSE,
50     PIXMAN_OP_XOR,
51     PIXMAN_OP_ADD,
52     PIXMAN_OP_MULTIPLY,
53     PIXMAN_OP_SCREEN,
54     PIXMAN_OP_OVERLAY,
55     PIXMAN_OP_DARKEN,
56     PIXMAN_OP_LIGHTEN,
57     PIXMAN_OP_HARD_LIGHT,
58     PIXMAN_OP_DIFFERENCE,
59     PIXMAN_OP_EXCLUSION,
60 };
61 
62 static const pixman_format_code_t formats[] =
63 {
64     PIXMAN_a8r8g8b8,
65     PIXMAN_r5g6b5,
66     PIXMAN_a8,
67     PIXMAN_a4,
68     PIXMAN_a1,
69     PIXMAN_b5g6r5,
70     PIXMAN_r8g8b8a8,
71     PIXMAN_a4r4g4b4
72 };
73 
74 #define N_ROUNDS 8192
75 
76 #define RAND_ELT(arr)							\
77     arr[prng_rand_r(&info->prng_state) % ARRAY_LENGTH (arr)]
78 
79 #define DEST_WIDTH (7)
80 
81 #ifdef HAVE_PTHREADS
82 static void *
thread(void * data)83 thread (void *data)
84 #elif defined (_WIN32)
85 DWORD WINAPI
86 thread (LPVOID data)
87 #endif
88 {
89     info_t *info = data;
90     uint32_t crc32 = 0x0;
91     uint32_t src_buf[64];
92     pixman_image_t *dst_img, *src_img;
93     int i;
94 
95     prng_srand_r (&info->prng_state, info->thread_no);
96 
97     for (i = 0; i < N_ROUNDS; ++i)
98     {
99 	pixman_op_t op;
100 	int rand1, rand2;
101 
102 	prng_randmemset_r (&info->prng_state, info->dst_buf,
103 			   DEST_WIDTH * sizeof (uint32_t), 0);
104 	prng_randmemset_r (&info->prng_state, src_buf,
105 			   sizeof (src_buf), 0);
106 
107 	src_img = pixman_image_create_bits (
108 	    RAND_ELT (formats), 4, 4, src_buf, 16);
109 	dst_img = pixman_image_create_bits (
110 	    RAND_ELT (formats), DEST_WIDTH, 1, info->dst_buf,
111 	    DEST_WIDTH * sizeof (uint32_t));
112 
113 	image_endian_swap (src_img);
114 	image_endian_swap (dst_img);
115 
116 	rand2 = prng_rand_r (&info->prng_state) % 4;
117 	rand1 = prng_rand_r (&info->prng_state) % 4;
118 	op = RAND_ELT (operators);
119 
120 	pixman_image_composite32 (
121 	    op,
122 	    src_img, NULL, dst_img,
123 	    rand1, rand2, 0, 0, 0, 0, DEST_WIDTH, 1);
124 
125 	crc32 = compute_crc32_for_image (crc32, dst_img);
126 
127 	pixman_image_unref (src_img);
128 	pixman_image_unref (dst_img);
129     }
130 
131 #ifdef HAVE_PTHREADS
132     return (void *)(uintptr_t)crc32;
133 #elif defined (_WIN32)
134     info->crc32 = crc32;
135     return 0;
136 #endif
137 }
138 
139 static inline uint32_t
byteswap32(uint32_t x)140 byteswap32 (uint32_t x)
141 {
142     return ((x & ((uint32_t)0xFF << 24)) >> 24) |
143            ((x & ((uint32_t)0xFF << 16)) >>  8) |
144            ((x & ((uint32_t)0xFF <<  8)) <<  8) |
145            ((x & ((uint32_t)0xFF <<  0)) << 24);
146 }
147 
148 int
main(void)149 main (void)
150 {
151     uint32_t dest[THREADS * DEST_WIDTH];
152     info_t info[THREADS] = { { 0 } };
153 
154 #ifdef HAVE_PTHREADS
155     pthread_t threads[THREADS];
156     void *retvals[THREADS];
157 #elif defined (_WIN32)
158     HANDLE  hThreadArray[THREADS];
159     DWORD   dwThreadIdArray[THREADS];
160 #endif
161 
162     uint32_t crc32s[THREADS], crc32;
163     int i;
164 
165     for (i = 0; i < THREADS; ++i)
166     {
167 	info[i].thread_no = i;
168 	info[i].dst_buf = &dest[i * DEST_WIDTH];
169     }
170 
171 #ifdef HAVE_PTHREADS
172     for (i = 0; i < THREADS; ++i)
173       pthread_create (&threads[i], NULL, thread, &info[i]);
174 
175     for (i = 0; i < THREADS; ++i)
176 	  pthread_join (threads[i], &retvals[i]);
177 
178     for (i = 0; i < THREADS; ++i)
179     {
180 	crc32s[i] = (uintptr_t)retvals[i];
181 
182 	if (is_little_endian())
183 	    crc32s[i] = byteswap32 (crc32s[i]);
184     }
185 
186 #elif defined (_WIN32)
187     for (i = 0; i < THREADS; ++i)
188       {
189         hThreadArray[i] = CreateThread(NULL,
190                                        0,
191                                        thread,
192                                        &info[i],
193                                        0,
194                                        &dwThreadIdArray[i]);
195         if (hThreadArray[i] == NULL)
196           {
197             printf ("Windows thread creation failed!\n");
198             return 1;
199           }
200       }
201     for (i = 0; i < THREADS; ++i)
202       {
203         WaitForSingleObject (hThreadArray[i], INFINITE);
204         CloseHandle(hThreadArray[i]);
205       }
206 
207     for (i = 0; i < THREADS; ++i)
208       {
209         crc32s[i] = info[i].crc32;
210 
211         if (is_little_endian())
212           crc32s[i] = byteswap32 (crc32s[i]);
213       }
214 #endif
215 
216     crc32 = compute_crc32 (0, crc32s, sizeof crc32s);
217 
218 #define EXPECTED 0x82C4D9FB
219 
220     if (crc32 != EXPECTED)
221     {
222 	printf ("thread-test failed. Got checksum 0x%08X, expected 0x%08X\n",
223 		crc32, EXPECTED);
224 	return 1;
225     }
226 
227     return 0;
228 }
229 
230 #endif
231 
232