/*
Copyright (C) 2007-2009, Parrot Foundation.
$Id: test_gcc_cmpxchg_c.in 36833 2009-02-17 20:09:26Z allison $

test for cmpxchg support with gcc-style inline ASM
*/

#include <assert.h>
#include <stdlib.h>

#include <stdio.h>

inline static void *docmpxchg(void **ptr, void *oldval, void *newval) {
    __asm__ __volatile__("lock\n"
                         "cmpxchgl %1,%2" : "=a"(oldval) : "q"(newval), "m"(*ptr), "0" (oldval)
                        : "memory");
    return oldval;
}

int
main(void)
{
    char dummy[] = "some string";
    char *oldval;
    char *newval;
    char *atomic;
    atomic = dummy;
    newval = dummy + 1;
    oldval = dummy;

    oldval = docmpxchg((void **)&atomic, oldval, newval);


#ifdef DEBUG_CMPXCHG_TEST
    printf("atomic=[%s], old=[%s], new=[%s]\n", atomic, oldval, newval);
#endif
    if (atomic != newval) {
        return EXIT_FAILURE;
    }

    oldval = docmpxchg((void **)&atomic, oldval, newval);
#ifdef DEBUG_CMPXCHG_TEST
    printf("atomic=[%s], old=[%s], new=[%s]\n", atomic, oldval, newval);
#endif
    if (oldval != newval) {
        return EXIT_FAILURE;
    }

    puts("ok");

    return EXIT_SUCCESS;
}

/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4:
 */
