// rvatomics.c — las tres primitivas de hardware, compiladas para RISC-V.
// No se ejecuta: se compila con el compilador cruzado para ver qué
// instrucciones genera cada una (make rv deja el resultado en rvatomics.s).
//
//   test_and_set      -> amoswap.w.aq   (intercambio atómico)
//   compare_and_swap  -> lazo lr.w / sc.w   (load-reserved, store-conditional)
//   fetch_and_add     -> amoadd.w       (suma atómica)

// TestAndSet: escribe 1 y devuelve el valor viejo.
int test_and_set(int *p) {
    return __atomic_exchange_n(p, 1, __ATOMIC_ACQUIRE);
}

// CompareAndSwap: si *p == expected, escribe new. Devuelve el valor viejo.
int compare_and_swap(int *p, int expected, int new) {
    __atomic_compare_exchange_n(p, &expected, new, 0, __ATOMIC_ACQ_REL,
                                __ATOMIC_ACQUIRE);
    return expected; // queda con el valor que había en *p
}

// FetchAndAdd: suma 1 y devuelve el valor viejo (el "ticket").
int fetch_and_add(int *p) {
    return __atomic_fetch_add(p, 1, __ATOMIC_RELAXED);
}
