/*
 * 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;
}
