Blame test/thread-test.c

Packit 030a23
#include "utils.h"
Packit 030a23
Packit 030a23
#ifndef HAVE_PTHREADS
Packit 030a23
Packit 030a23
int main ()
Packit 030a23
{
Packit 030a23
    printf ("Skipped thread-test - pthreads not supported\n");
Packit 030a23
    return 0;
Packit 030a23
}
Packit 030a23
Packit 030a23
#else
Packit 030a23
Packit 030a23
#include <stdlib.h>
Packit 030a23
#include <pthread.h>
Packit 030a23
Packit 030a23
typedef struct
Packit 030a23
{
Packit 030a23
    int       thread_no;
Packit 030a23
    uint32_t *dst_buf;
Packit 030a23
    prng_t    prng_state;
Packit 030a23
} info_t;
Packit 030a23
Packit 030a23
static const pixman_op_t operators[] = 
Packit 030a23
{
Packit 030a23
    PIXMAN_OP_SRC,
Packit 030a23
    PIXMAN_OP_OVER,
Packit 030a23
    PIXMAN_OP_ADD,
Packit 030a23
    PIXMAN_OP_CLEAR,
Packit 030a23
    PIXMAN_OP_SRC,
Packit 030a23
    PIXMAN_OP_DST,
Packit 030a23
    PIXMAN_OP_OVER,
Packit 030a23
    PIXMAN_OP_OVER_REVERSE,
Packit 030a23
    PIXMAN_OP_IN,
Packit 030a23
    PIXMAN_OP_IN_REVERSE,
Packit 030a23
    PIXMAN_OP_OUT,
Packit 030a23
    PIXMAN_OP_OUT_REVERSE,
Packit 030a23
    PIXMAN_OP_ATOP,
Packit 030a23
    PIXMAN_OP_ATOP_REVERSE,
Packit 030a23
    PIXMAN_OP_XOR,
Packit 030a23
    PIXMAN_OP_ADD,
Packit 030a23
    PIXMAN_OP_MULTIPLY,
Packit 030a23
    PIXMAN_OP_SCREEN,
Packit 030a23
    PIXMAN_OP_OVERLAY,
Packit 030a23
    PIXMAN_OP_DARKEN,
Packit 030a23
    PIXMAN_OP_LIGHTEN,
Packit 030a23
    PIXMAN_OP_HARD_LIGHT,
Packit 030a23
    PIXMAN_OP_DIFFERENCE,
Packit 030a23
    PIXMAN_OP_EXCLUSION,
Packit 030a23
};
Packit 030a23
Packit 030a23
static const pixman_format_code_t formats[] =
Packit 030a23
{
Packit 030a23
    PIXMAN_a8r8g8b8,
Packit 030a23
    PIXMAN_r5g6b5,
Packit 030a23
    PIXMAN_a8,
Packit 030a23
    PIXMAN_a4,
Packit 030a23
    PIXMAN_a1,
Packit 030a23
    PIXMAN_b5g6r5,
Packit 030a23
    PIXMAN_r8g8b8a8,
Packit 030a23
    PIXMAN_a4r4g4b4
Packit 030a23
};
Packit 030a23
Packit 030a23
#define N_ROUNDS 8192
Packit 030a23
Packit 030a23
#define RAND_ELT(arr)							\
Packit 030a23
    arr[prng_rand_r(&info->prng_state) % ARRAY_LENGTH (arr)]
Packit 030a23
Packit 030a23
#define DEST_WIDTH (7)
Packit 030a23
Packit 030a23
static void *
Packit 030a23
thread (void *data)
Packit 030a23
{
Packit 030a23
    info_t *info = data;
Packit 030a23
    uint32_t crc32 = 0x0;
Packit 030a23
    uint32_t src_buf[64];
Packit 030a23
    pixman_image_t *dst_img, *src_img;
Packit 030a23
    int i;
Packit 030a23
Packit 030a23
    prng_srand_r (&info->prng_state, info->thread_no);
Packit 030a23
Packit 030a23
    for (i = 0; i < N_ROUNDS; ++i)
Packit 030a23
    {
Packit 030a23
	pixman_op_t op;
Packit 030a23
	int rand1, rand2;
Packit 030a23
Packit 030a23
	prng_randmemset_r (&info->prng_state, info->dst_buf,
Packit 030a23
			   DEST_WIDTH * sizeof (uint32_t), 0);
Packit 030a23
	prng_randmemset_r (&info->prng_state, src_buf,
Packit 030a23
			   sizeof (src_buf), 0);
Packit 030a23
Packit 030a23
	src_img = pixman_image_create_bits (
Packit 030a23
	    RAND_ELT (formats), 4, 4, src_buf, 16);
Packit 030a23
	dst_img = pixman_image_create_bits (
Packit 030a23
	    RAND_ELT (formats), DEST_WIDTH, 1, info->dst_buf,
Packit 030a23
	    DEST_WIDTH * sizeof (uint32_t));
Packit 030a23
Packit 030a23
	image_endian_swap (src_img);
Packit 030a23
	image_endian_swap (dst_img);
Packit 030a23
	
Packit 030a23
	rand2 = prng_rand_r (&info->prng_state) % 4;
Packit 030a23
	rand1 = prng_rand_r (&info->prng_state) % 4;
Packit 030a23
	op = RAND_ELT (operators);
Packit 030a23
Packit 030a23
	pixman_image_composite32 (
Packit 030a23
	    op,
Packit 030a23
	    src_img, NULL, dst_img,
Packit 030a23
	    rand1, rand2, 0, 0, 0, 0, DEST_WIDTH, 1);
Packit 030a23
Packit 030a23
	crc32 = compute_crc32_for_image (crc32, dst_img);
Packit 030a23
Packit 030a23
	pixman_image_unref (src_img);
Packit 030a23
	pixman_image_unref (dst_img);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    return (void *)(uintptr_t)crc32;
Packit 030a23
}
Packit 030a23
Packit 030a23
static inline uint32_t
Packit 030a23
byteswap32 (uint32_t x)
Packit 030a23
{
Packit 030a23
    return ((x & ((uint32_t)0xFF << 24)) >> 24) |
Packit 030a23
           ((x & ((uint32_t)0xFF << 16)) >>  8) |
Packit 030a23
           ((x & ((uint32_t)0xFF <<  8)) <<  8) |
Packit 030a23
           ((x & ((uint32_t)0xFF <<  0)) << 24);
Packit 030a23
}
Packit 030a23
Packit 030a23
int
Packit 030a23
main (void)
Packit 030a23
{
Packit 030a23
    uint32_t dest[16 * DEST_WIDTH];
Packit 030a23
    info_t info[16] = { { 0 } };
Packit 030a23
    pthread_t threads[16];
Packit 030a23
    void *retvals[16];
Packit 030a23
    uint32_t crc32s[16], crc32;
Packit 030a23
    int i;
Packit 030a23
Packit 030a23
    for (i = 0; i < 16; ++i)
Packit 030a23
    {
Packit 030a23
	info[i].thread_no = i;
Packit 030a23
	info[i].dst_buf = &dest[i * DEST_WIDTH];
Packit 030a23
    }
Packit 030a23
Packit 030a23
    for (i = 0; i < 16; ++i)
Packit 030a23
	pthread_create (&threads[i], NULL, thread, &info[i]);
Packit 030a23
Packit 030a23
    for (i = 0; i < 16; ++i)
Packit 030a23
	pthread_join (threads[i], &retvals[i]);
Packit 030a23
Packit 030a23
    for (i = 0; i < 16; ++i)
Packit 030a23
    {
Packit 030a23
	crc32s[i] = (uintptr_t)retvals[i];
Packit 030a23
Packit 030a23
	if (is_little_endian())
Packit 030a23
	    crc32s[i] = byteswap32 (crc32s[i]);
Packit 030a23
    }
Packit 030a23
Packit 030a23
    crc32 = compute_crc32 (0, crc32s, sizeof crc32s);
Packit 030a23
Packit 030a23
#define EXPECTED 0x82C4D9FB
Packit 030a23
Packit 030a23
    if (crc32 != EXPECTED)
Packit 030a23
    {
Packit 030a23
	printf ("thread-test failed. Got checksum 0x%08X, expected 0x%08X\n",
Packit 030a23
		crc32, EXPECTED);
Packit 030a23
	return 1;
Packit 030a23
    }
Packit 030a23
Packit 030a23
    return 0;
Packit 030a23
}
Packit 030a23
Packit 030a23
#endif
Packit 030a23