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

*/

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

extern int parrot_sparc_cas32(uint32_t *address, uint32_t oldval, uint32_t newval);
extern int parrot_sparc_cas64(uint64_t *address, uint64_t oldval, uint64_t newval);

#define DIAGNOSE() fprintf(stderr, "error at line %d: successp=%d/old=%llx/value=%llx\n", __LINE__, \
                           successp, (unsigned long long) oldval, (unsigned long long) value)

int main(void) {
    {
        int successp;
        uint32_t value;
        uint32_t oldval;
        value = oldval = 42;

        successp = parrot_sparc_cas32(&value, 41, 0xFFFFFFFFu);
        if (successp || value == 0xFFFFFFFFu) {
            DIAGNOSE();
            return EXIT_FAILURE;
        }

        successp = parrot_sparc_cas32(&value, oldval, 0xFFFFFFFFu);
        if (!successp || value != 0xFFFFFFFFu) {
            DIAGNOSE();
            return EXIT_FAILURE;
        }

        oldval = value;

        successp = parrot_sparc_cas32(&value, oldval, 0);
        if (!successp || value != 0) {
            DIAGNOSE();
            return EXIT_FAILURE;
        }
    }

    /* we'll only use the below functions if pointers are wide enough;
     * and they don't work when pointers aren't wide enough
     */
    if (sizeof (void *) == sizeof (uint64_t)) {
        int successp;
        uint64_t value;
        uint64_t oldval;
        value = oldval = 42;

        successp = parrot_sparc_cas64(&value, 41, 0x123456789abcdef0u);
        if (successp || value == 0x123456789abcdef0u) {
            DIAGNOSE();
            return EXIT_FAILURE;
        }

        successp = parrot_sparc_cas64(&value, oldval, 0x123456789abcdef0u);
        if (!successp || value != 0x123456789abcdef0u) {
            DIAGNOSE();
            return EXIT_FAILURE;
        }

        oldval = value;

        successp = parrot_sparc_cas64(&value, oldval, 0);
        if (!successp || value != 0) {
            DIAGNOSE();
            return EXIT_FAILURE;
        }
    }

    puts("ok");

    return EXIT_SUCCESS;
}

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