void libat_store (size_t n, void *mptr, void *vptr, int smodel) { switch (n) { case 0: return; case 1: EXACT(1); goto L4; case 2: EXACT(2); goto L4; case 4: EXACT(4); goto L8; case 8: EXACT(8); goto L16; case 16: EXACT(16); break; case 3: L4: LARGER(4); /* FALLTHRU */ case 5 ... 7: L8: LARGER(8); /* FALLTHRU */ case 9 ... 15: L16: LARGER(16); break; } pre_seq_barrier (smodel); libat_lock_n (mptr, n); memcpy (mptr, vptr, n); libat_unlock_n (mptr, n); post_seq_barrier (smodel); }
void libat_load (size_t n, void *mptr, void *rptr, int smodel) { union max_size_u u; uintptr_t r, a; switch (n) { case 0: return; case 1: EXACT(1); goto L4; case 2: EXACT(2); goto L4; case 4: EXACT(4); goto L8; case 8: EXACT(8); goto L16; case 16: EXACT(16); break; case 3: L4: LARGER(4); /* FALLTHRU */ case 5 ... 7: L8: LARGER(8); /* FALLTHRU */ case 9 ... 15: L16: LARGER(16); break; Lfinish: memcpy (rptr, u.b + r, n); return; } pre_seq_barrier (smodel); libat_lock_n (mptr, n); memcpy (rptr, mptr, n); libat_unlock_n (mptr, n); post_seq_barrier (smodel); }
void SIZE(libat_store) (UTYPE *mptr, UTYPE newval, int smodel) { UWORD magic; pre_seq_barrier (smodel); magic = protect_start (mptr); *mptr = newval; protect_end (mptr, magic); post_seq_barrier (smodel); }
UTYPE SIZE(libat_load) (UTYPE *mptr, int smodel) { UTYPE ret; UWORD magic; pre_seq_barrier (smodel); magic = protect_start (mptr); ret = *mptr; protect_end (mptr, magic); post_seq_barrier (smodel); return ret; }
bool SIZE(libat_test_and_set) (UTYPE *mptr, int smodel) { UTYPE oldval; UWORD magic; pre_seq_barrier (smodel); magic = protect_start (mptr); oldval = *mptr; *mptr = __GCC_ATOMIC_TEST_AND_SET_TRUEVAL; protect_end (mptr, magic); post_seq_barrier (smodel); return oldval != 0; }
UTYPE SIZE(libat_exchange) (UTYPE *mptr, UTYPE newval, int smodel UNUSED) { UTYPE oldval; UWORD magic; pre_seq_barrier (smodel); magic = protect_start (mptr); oldval = *mptr; *mptr = newval; protect_end (mptr, magic); post_seq_barrier (smodel); return oldval; }
UTYPE SIZE(C3(libat_,NAME,_fetch)) (UTYPE *mptr, UTYPE opval, int smodel UNUSED) { UTYPE ret; UWORD magic; pre_seq_barrier (smodel); magic = protect_start (mptr); ret = OP (*mptr, opval); *mptr = ret; protect_end (mptr, magic); post_seq_barrier (smodel); return ret; }
void libat_exchange (size_t n, void *mptr, void *vptr, void *rptr, int smodel) { union max_size_u u, v; uintptr_t r, a; switch (n) { case 0: return; case 1: EXACT(1); goto L4; case 2: EXACT(2); goto L4; case 4: EXACT(4); goto L8; case 8: EXACT(8); goto L16; case 16: EXACT(16); break; case 3: L4: LARGER(4); /* FALLTHRU */ case 5 ... 7: L8: LARGER(8); /* FALLTHRU */ case 9 ... 15: L16: LARGER(16); break; Lfinish: post_barrier (smodel); memcpy (rptr, u.b + r, n); return; } pre_seq_barrier (smodel); libat_lock_n (mptr, n); if (vptr != rptr) { memcpy (rptr, mptr, n); memcpy (mptr, vptr, n); } else libat_exchange_large_inplace (n, mptr, vptr); libat_unlock_n (mptr, n); post_seq_barrier (smodel); }
bool SIZE(libat_compare_exchange) (UTYPE *mptr, UTYPE *eptr, UTYPE newval, int smodel, int fmodel UNUSED) { UTYPE oldval; UWORD magic; bool ret; pre_seq_barrier (smodel); magic = protect_start (mptr); oldval = *mptr; ret = (oldval == *eptr); if (ret) *mptr = newval; else *eptr = oldval; protect_end (mptr, magic); post_seq_barrier (smodel); return ret; }