Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/include/atomic.h
Show First 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | |||||
* atomic_set_long(P, V) (*(u_long *)(P) |= (V)) | * atomic_set_long(P, V) (*(u_long *)(P) |= (V)) | ||||
* atomic_clear_long(P, V) (*(u_long *)(P) &= ~(V)) | * atomic_clear_long(P, V) (*(u_long *)(P) &= ~(V)) | ||||
* atomic_add_long(P, V) (*(u_long *)(P) += (V)) | * atomic_add_long(P, V) (*(u_long *)(P) += (V)) | ||||
* atomic_subtract_long(P, V) (*(u_long *)(P) -= (V)) | * atomic_subtract_long(P, V) (*(u_long *)(P) -= (V)) | ||||
* atomic_swap_long(P, V) (return (*(u_long *)(P)); *(u_long *)(P) = (V);) | * atomic_swap_long(P, V) (return (*(u_long *)(P)); *(u_long *)(P) = (V);) | ||||
* atomic_readandclear_long(P) (return (*(u_long *)(P)); *(u_long *)(P) = 0;) | * atomic_readandclear_long(P) (return (*(u_long *)(P)); *(u_long *)(P) = 0;) | ||||
*/ | */ | ||||
/* | /* | ||||
* The above functions are expanded inline in the statically-linked | * The above functions are expanded inline in the statically-linked | ||||
* kernel. Lock prefixes are generated if an SMP kernel is being | * kernel. Lock prefixes are generated if an SMP kernel is being | ||||
* built. | * built. | ||||
* | * | ||||
* Kernel modules call real functions which are built into the kernel. | * Kernel modules call real functions which are built into the kernel. | ||||
* This allows kernel modules to be portable between UP and SMP systems. | * This allows kernel modules to be portable between UP and SMP systems. | ||||
*/ | */ | ||||
ehem_freebsd_m5p.com: This makes the second sentence of the first paragraph no longer true. The second paragraph… | |||||
#if !defined(__GNUCLIKE_ASM) | #if !defined(__GNUCLIKE_ASM) | ||||
#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ | #define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ | ||||
void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \ | void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \ | ||||
void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v) | void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v) | ||||
int atomic_cmpset_char(volatile u_char *dst, u_char expect, u_char src); | int atomic_cmpset_char(volatile u_char *dst, u_char expect, u_char src); | ||||
int atomic_cmpset_short(volatile u_short *dst, u_short expect, u_short src); | int atomic_cmpset_short(volatile u_short *dst, u_short expect, u_short src); | ||||
int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src); | int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src); | ||||
Show All 14 Lines | |||||
void atomic_thread_fence_rel(void); | void atomic_thread_fence_rel(void); | ||||
void atomic_thread_fence_seq_cst(void); | void atomic_thread_fence_seq_cst(void); | ||||
#define ATOMIC_LOAD(TYPE) \ | #define ATOMIC_LOAD(TYPE) \ | ||||
u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p) | u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p) | ||||
#define ATOMIC_STORE(TYPE) \ | #define ATOMIC_STORE(TYPE) \ | ||||
void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) | void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v) | ||||
#else /* !KLD_MODULE && __GNUCLIKE_ASM */ | #else /* !__GNUCLIKE_ASM */ | ||||
/* | /* | ||||
* For userland, always use lock prefixes so that the binaries will run | * For userland, always use lock prefixes so that the binaries will run | ||||
* on both SMP and !SMP systems. | * on both SMP and !SMP systems. | ||||
*/ | */ | ||||
#if defined(SMP) || !defined(_KERNEL) || defined(KLD_MODULE) | #if defined(SMP) || !defined(_KERNEL) || defined(KLD_MODULE) | ||||
#define MPLOCKED "lock ; " | #define MPLOCKED "lock ; " | ||||
#else | #else | ||||
#define MPLOCKED | #define MPLOCKED | ||||
#endif | #endif | ||||
/* | /* | ||||
* The assembly is volatilized to avoid code chunk removal by the compiler. | * The assembly is volatilized to avoid code chunk removal by the compiler. | ||||
* GCC aggressively reorders operations and memory clobbering is necessary | * GCC aggressively reorders operations and memory clobbering is necessary | ||||
* in order to avoid that for memory barriers. | * in order to avoid that for memory barriers. | ||||
*/ | */ | ||||
#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ | #define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \ | ||||
static __inline void \ | static __inline void \ | ||||
atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ | atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ | ||||
{ \ | { \ | ||||
__asm __volatile(MPLOCKED OP \ | __asm __volatile(MPLOCKED OP \ | ||||
Done Inline ActionsMaybe keep the space after the ; so that if anyone looks at the generated assembly it is 'lock; and' vs 'lock;and'? (In examples below you use a space in, e.g. 'lock; cmpxchg'.) Hmm, looks like you did keep the space in i386? jhb: Maybe keep the space after the ; so that if anyone looks at the generated assembly it is 'lock… | |||||
: "+m" (*p) \ | : "+m" (*p) \ | ||||
: CONS (V) \ | : CONS (V) \ | ||||
: "cc"); \ | : "cc"); \ | ||||
} \ | } \ | ||||
\ | \ | ||||
static __inline void \ | static __inline void \ | ||||
atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ | atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\ | ||||
{ \ | { \ | ||||
▲ Show 20 Lines • Show All 250 Lines • ▼ Show 20 Lines | |||||
static __inline void | static __inline void | ||||
atomic_thread_fence_seq_cst(void) | atomic_thread_fence_seq_cst(void) | ||||
{ | { | ||||
__storeload_barrier(); | __storeload_barrier(); | ||||
} | } | ||||
#endif /* KLD_MODULE || !__GNUCLIKE_ASM */ | #endif /* !__GNUCLIKE_ASM */ | ||||
ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v); | ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v); | ||||
ATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v); | ATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v); | ||||
ATOMIC_ASM(add, char, "addb %b1,%0", "iq", v); | ATOMIC_ASM(add, char, "addb %b1,%0", "iq", v); | ||||
ATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v); | ATOMIC_ASM(subtract, char, "subb %b1,%0", "iq", v); | ||||
ATOMIC_ASM(set, short, "orw %w1,%0", "ir", v); | ATOMIC_ASM(set, short, "orw %w1,%0", "ir", v); | ||||
ATOMIC_ASM(clear, short, "andw %w1,%0", "ir", ~v); | ATOMIC_ASM(clear, short, "andw %w1,%0", "ir", ~v); | ||||
▲ Show 20 Lines • Show All 245 Lines • Show Last 20 Lines |
This makes the second sentence of the first paragraph no longer true. The second paragraph became untrue at f4b3640475cec9299517289b7e8731ae26997cfc. I would tend to simply purge the comment, though it could also be adjusted.