#include "utils.h" #ifndef HAVE_PTHREADS int main () { printf ("Skipped thread-test - pthreads not supported\n"); return 0; } #else #include #include typedef struct { int thread_no; uint32_t *dst_buf; prng_t prng_state; } 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_MULTIPLY, PIXMAN_OP_SCREEN, PIXMAN_OP_OVERLAY, PIXMAN_OP_DARKEN, PIXMAN_OP_LIGHTEN, 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 8192 #define RAND_ELT(arr) \ arr[prng_rand_r(&info->prng_state) % ARRAY_LENGTH (arr)] #define DEST_WIDTH (7) 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_r (&info->prng_state, info->thread_no); for (i = 0; i < N_ROUNDS; ++i) { pixman_op_t op; int rand1, rand2; prng_randmemset_r (&info->prng_state, info->dst_buf, DEST_WIDTH * sizeof (uint32_t), 0); prng_randmemset_r (&info->prng_state, 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), DEST_WIDTH, 1, info->dst_buf, DEST_WIDTH * sizeof (uint32_t)); image_endian_swap (src_img); image_endian_swap (dst_img); rand2 = prng_rand_r (&info->prng_state) % 4; rand1 = prng_rand_r (&info->prng_state) % 4; op = RAND_ELT (operators); pixman_image_composite32 ( op, src_img, NULL, dst_img, rand1, rand2, 0, 0, 0, 0, DEST_WIDTH, 1); crc32 = compute_crc32_for_image (crc32, dst_img); pixman_image_unref (src_img); pixman_image_unref (dst_img); } return (void *)(uintptr_t)crc32; } static inline uint32_t byteswap32 (uint32_t x) { return ((x & ((uint32_t)0xFF << 24)) >> 24) | ((x & ((uint32_t)0xFF << 16)) >> 8) | ((x & ((uint32_t)0xFF << 8)) << 8) | ((x & ((uint32_t)0xFF << 0)) << 24); } int main (void) { uint32_t dest[16 * DEST_WIDTH]; info_t info[16] = { { 0 } }; pthread_t threads[16]; void *retvals[16]; uint32_t crc32s[16], crc32; int i; for (i = 0; i < 16; ++i) { info[i].thread_no = i; info[i].dst_buf = &dest[i * DEST_WIDTH]; } 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) { crc32s[i] = (uintptr_t)retvals[i]; if (is_little_endian()) crc32s[i] = byteswap32 (crc32s[i]); } crc32 = compute_crc32 (0, crc32s, sizeof crc32s); #define EXPECTED 0x82C4D9FB if (crc32 != EXPECTED) { printf ("thread-test failed. Got checksum 0x%08X, expected 0x%08X\n", crc32, EXPECTED); return 1; } return 0; } #endif