Date: Mon, 4 Feb 2002 12:24:44 +0100 (CET) From: Michal Mertl <mime@traveller.cz> To: audit@freebsd.org Cc: jhb@freebsd.org, <peter.jeremy@alcatel.com.au> Subject: request for review: i386 64bit atomic patch Message-ID: <Pine.BSF.4.41.0202041221370.14840-100000@prg.traveller.cz>
next in thread | raw e-mail | index | archive | help
--- atomic.h.ori Sat Feb 2 12:31:36 2002 +++ atomic.h Mon Feb 4 12:08:05 2002 @@ -407,5 +407,162 @@ return (result); } #endif /* !defined(WANT_FUNCTIONS) */ + +#if 1 +#define _ATOMIC_HAVE_QUAD +#endif + +#ifdef _ATOMIC_HAVE_QUAD +#define atomic_set_acq_64 atomic_set_64 +#define atomic_set_rel_64 atomic_set_64 +#define atomic_clear_acq_64 atomic_clear_64 +#define atomic_clear_rel_64 atomic_clear_64 +#define atomic_add_acq_64 atomic_add_64 +#define atomic_add_rel_64 atomic_add_64 +#define atomic_subtract_acq_64 atomic_subtract_64 +#define atomic_subtract_rel_64 atomic_subtract_64 +#define atomic_cmpset_acq_64 atomic_cmpset_64 +#define atomic_cmpset_rel_64 atomic_cmpset_64 +#define atomic_readandclear_64 atomic_readandclear_64 + +#if !defined(KLD_MODULE) + +static __inline int +atomic_cmpset_64(volatile u_int64_t *dst, u_int64_t exp, u_int64_t src) +{ + int res; + + __asm __volatile ( + " " MPLOCKED " " + " cmpxchg8b %1 ; " + " setz %%al ; " + " movzbl %%al,%0 ; " + "#atomic_cmpset_64" + : "=a" (res), /* 0 */ + "+m" (*(dst)) /* 1 */ + : "a" ((u_long)exp), + "d" ((u_long)((u_long *)&exp)[1]), + "b" ((u_long)src), + "c" ((u_long)((u_long *)&src)[1]) + : "memory" ); + return res; +} + +static __inline void +atomic_store_rel_64(volatile u_int64_t *p, u_int64_t v) +{ + u_int64_t exp, src; + + do { + exp = *p; + src = v; + } while (atomic_cmpset_64(p, exp, src) == 0); +} + + +static __inline void +atomic_add_64(volatile u_int64_t *p, u_int64_t v) +{ +#if 1 +/* + * Generic implementation (below) is about 20% slower on p2. + * We may need to use this function in time-critical contexts + * (e.g. 64-bit counters). + */ + __asm __volatile ( + " movl (%0),%%eax ; " + " movl 4(%0),%%edx ; " + " 1:movl (%1),%%ebx ; " + " movl 4(%1),%%ecx ; " + " addl %%eax,%%ebx ; " + " adcl %%edx,%%ecx ; " + " " MPLOCKED " " + " cmpxchg8b (%0) ; " + " jnz 1b ; " + "#atomic_add_64" + : + : "S" (p), /* 0 */ + "D" (&v) /* 1 */ + : "eax", "ebx", "ecx", "edx", "memory" ); +#else + u_int64_t exp, src; + + do { + exp = *p; + src = exp + v; + } while (atomic_cmpset_64(p, exp, src) == 0); +#endif +} + +static __inline void +atomic_subtract_64(volatile u_int64_t *p, u_int64_t v) +{ + u_int64_t exp, src; + + do { + exp = *p; + src = exp - v; + } while (atomic_cmpset_64(p, exp, src) == 0); +} + +static __inline void +atomic_clear_64(volatile u_int64_t *p, u_int64_t v) +{ + u_int64_t exp, src, notv = ~v; + + do { + exp = *p; + src = exp & notv; + } while (atomic_cmpset_64(p, exp, src) == 0); +} + +static __inline void +atomic_set_64(volatile u_int64_t *p, u_int64_t v) +{ + u_int64_t exp, src; + + do { + exp = *p; + src = exp | v; + } while (atomic_cmpset_64(p, exp, src) == 0); +} + +static __inline u_int64_t +atomic_load_acq_64(volatile u_int64_t *p) +{ + u_int64_t exp; + + do { + exp = *p; + } while (atomic_cmpset_64(p, exp, exp) == 0); + return (exp); +} + +static __inline u_int64_t +atomic_readandclear_64(volatile u_int64_t *p) +{ + u_int64_t exp; + + do { + exp = *p; + } while (atomic_cmpset_64(p, exp, 0) == 0); + return (exp); +} + +#else /* defined(KLD_MODULE) */ + +void atomic_set_64(volatile u_int64_t *, u_int64_t); +void atomic_store_rel_64(volatile u_int64_t *, u_int64_t); +void atomic_clear_64(volatile u_int64_t *, u_int64_t); +void atomic_add_64(volatile u_int64_t *, u_int64_t); +void atomic_subtract_64(volatile u_int64_t *, u_int64_t); +u_int64_t atomic_load_acq_64(volatile u_int64_t *); +int atomic_cmpset_64(volatile u_int64_t *,u_int64_t,u_int64_t); +u_int64_t atomic_readandclear_64(volatile u_int64_t *); +#endif + +#endif /*defined(_ATOMIC_HAVE_QUAD)*/ + #endif /* !defined(LOCORE) */ + #endif /* ! _MACHINE_ATOMIC_H_ */ ------------ Thank Peter and John for your advices. What do you think now? Can someone commit it? -- Michal Mertl mime@traveller.cz To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-audit" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.41.0202041221370.14840-100000>