mirror of
https://github.com/autc04/Retro68.git
synced 2024-09-08 20:55:01 +00:00
129 lines
3.0 KiB
C
129 lines
3.0 KiB
C
|
/* { dg-do run } */
|
|||
|
|
|||
|
#include <stdlib.h>
|
|||
|
#include <string.h>
|
|||
|
#include <stdbool.h>
|
|||
|
|
|||
|
/* Avoid using the builtins, calling directly to the library functions
|
|||
|
of the same name, so that we get direct access to the size_t and
|
|||
|
don't have to create myriad types of different sizes. */
|
|||
|
|
|||
|
#define C2_(X,Y) X ## Y
|
|||
|
#define C2(X,Y) C2_(X,Y)
|
|||
|
|
|||
|
#define S2(X) #X
|
|||
|
#define S(X) S2(X)
|
|||
|
|
|||
|
#define ASMNAME(X) __asm__(S(C2(__USER_LABEL_PREFIX__,X)))
|
|||
|
#define MAN(X) ASMNAME(C2(__atomic_,X))
|
|||
|
|
|||
|
void libat_load (size_t, void *, void *, int) MAN(load);
|
|||
|
void libat_store (size_t, void *, void *, int) MAN(store);
|
|||
|
void libat_exchange (size_t, void *, void *, void *, int) MAN(exchange);
|
|||
|
bool libat_compare_exchange (size_t, void *, void *, void *, int, int)
|
|||
|
MAN(compare_exchange);
|
|||
|
bool libat_is_lock_free (size_t, void *) MAN(is_lock_free);
|
|||
|
|
|||
|
|
|||
|
#define ALIGN 16
|
|||
|
#define MAX 4*ALIGN
|
|||
|
|
|||
|
static char a[MAX];
|
|||
|
static char b[MAX];
|
|||
|
static char c[MAX];
|
|||
|
static char pa[MAX];
|
|||
|
static char pb[MAX];
|
|||
|
|
|||
|
static void test_load(void)
|
|||
|
{
|
|||
|
int i, j;
|
|||
|
for (i = ALIGN; i < 2*ALIGN; ++i)
|
|||
|
for (j = 1; j <= 2*ALIGN; ++j)
|
|||
|
{
|
|||
|
memcpy(b, pa, MAX);
|
|||
|
memcpy(b + i, pb, j);
|
|||
|
libat_load (j, b + i, a, 0);
|
|||
|
if (memcmp (a, pb, j) != 0) abort ();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void test_store(void)
|
|||
|
{
|
|||
|
int i, j;
|
|||
|
for (i = ALIGN; i < 2*ALIGN; ++i)
|
|||
|
for (j = 1; j <= 2*ALIGN; ++j)
|
|||
|
{
|
|||
|
memcpy(a, pa, MAX);
|
|||
|
memcpy(b, pa, MAX);
|
|||
|
memcpy(b + i, pb, j);
|
|||
|
libat_store (j, a + i, pb, 0);
|
|||
|
if (memcmp (a, b, MAX) != 0) abort ();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void test_exch(void)
|
|||
|
{
|
|||
|
int i, j;
|
|||
|
for (i = ALIGN; i < 2 * ALIGN; ++i)
|
|||
|
for (j = 1; j <= 2*ALIGN; ++j)
|
|||
|
{
|
|||
|
memcpy(a, pa, MAX);
|
|||
|
memcpy(b, pa, MAX);
|
|||
|
memcpy(b + i, pb, j);
|
|||
|
libat_exchange (j, a + i, pb, c, 0);
|
|||
|
if (memcmp (a, b, MAX) != 0) abort ();
|
|||
|
if (memcmp (c, pa + i, j) != 0) abort ();
|
|||
|
|
|||
|
memcpy(a, pa, MAX);
|
|||
|
memcpy(c, pb, MAX);
|
|||
|
libat_exchange (j, a + i, c + i, c + i, 0);
|
|||
|
memcpy(b, pa, MAX);
|
|||
|
memcpy(b + i, pb + i, j);
|
|||
|
if (memcmp (b, a, MAX) != 0) abort ();
|
|||
|
memcpy(b, pb, MAX);
|
|||
|
memcpy(b + i, pa + i, j);
|
|||
|
if (memcmp (b, c, MAX) != 0) abort ();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static void test_cas(void)
|
|||
|
{
|
|||
|
int i, j;
|
|||
|
for (i = ALIGN; i < 2 * ALIGN; ++i)
|
|||
|
for (j = 1; j <= 2*ALIGN; ++j)
|
|||
|
{
|
|||
|
memcpy(a, pa, MAX);
|
|||
|
memcpy(b, pa, MAX);
|
|||
|
memcpy(c, pa, MAX);
|
|||
|
memcpy(b + i, pb, j);
|
|||
|
if (!libat_compare_exchange (j, a + i, c + i, pb, 0, 0)) abort ();
|
|||
|
if (memcmp (c, pa, MAX) != 0) abort ();
|
|||
|
if (memcmp (a, b, MAX) != 0) abort ();
|
|||
|
|
|||
|
memcpy(a, pb, MAX);
|
|||
|
memcpy(b, pa, MAX);
|
|||
|
memcpy(c, pa, MAX);
|
|||
|
memcpy(b + i, pb + i, j);
|
|||
|
if (libat_compare_exchange (j, a + i, c + i, pb, 0, 0)) abort ();
|
|||
|
if (memcmp (a, pb, MAX) != 0) abort ();
|
|||
|
if (memcmp (b, c, MAX) != 0) abort ();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int main (void)
|
|||
|
{
|
|||
|
int i;
|
|||
|
for (i = 0; i < MAX; ++i)
|
|||
|
{
|
|||
|
pa[i] = i * 2;
|
|||
|
pb[i] = i * 2 + 1;
|
|||
|
}
|
|||
|
|
|||
|
test_load ();
|
|||
|
test_store ();
|
|||
|
test_exch ();
|
|||
|
test_cas ();
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|