X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/9c095379236460b62dd1fb3ef8e73e749beca27e..477d3c1cb94fc723c033f6ad0897a6a3d65046b6:/sys/cpu/i386/include/atomic.h diff --git a/sys/cpu/i386/include/atomic.h b/sys/cpu/i386/include/atomic.h index 7650c995ba..87f3dce71d 100644 --- a/sys/cpu/i386/include/atomic.h +++ b/sys/cpu/i386/include/atomic.h @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/include/atomic.h,v 1.9.2.1 2000/07/07 00:38:47 obrien Exp $ - * $DragonFly: src/sys/cpu/i386/include/atomic.h,v 1.11 2005/05/25 01:44:12 dillon Exp $ + * $DragonFly: src/sys/cpu/i386/include/atomic.h,v 1.15 2005/10/13 00:02:46 dillon Exp $ */ #ifndef _MACHINE_ATOMIC_H_ #define _MACHINE_ATOMIC_H_ @@ -138,11 +138,20 @@ ATOMIC_ASM(subtract, long, "subl %1,%0", v) #if defined(KLD_MODULE) +extern int atomic_swap_int(volatile int *addr, int value); extern int atomic_poll_acquire_int(volatile u_int *p); extern void atomic_poll_release_int(volatile u_int *p); #else +static __inline int +atomic_swap_int(volatile int *addr, int value) +{ + __asm __volatile("xchgl %0, %1" : + "=r" (value), "=m" (*addr) : "0" (value) : "memory"); + return (value); +} + static __inline int atomic_poll_acquire_int(volatile u_int *p) @@ -169,6 +178,16 @@ atomic_poll_release_int(volatile u_int *p) * bit 0-30 interrupt handler disabled bits (counter) * bit 31 interrupt handler currently running bit (1 = run) * + * atomic_intr_cond_test(P) Determine if the interlock is in an + * acquired state. Returns 0 if it not + * acquired, non-zero if it is. + * + * atomic_intr_cond_try(P) + * Increment the request counter and attempt to + * set bit 31 to acquire the interlock. If + * we are unable to set bit 31 the request + * counter is decremented and we return -1, + * otherwise we return 0. * * atomic_intr_cond_enter(P, func, arg) * Increment the request counter and attempt to @@ -215,6 +234,8 @@ void atomic_intr_init(atomic_intr_t *p); int atomic_intr_handler_disable(atomic_intr_t *p); void atomic_intr_handler_enable(atomic_intr_t *p); int atomic_intr_handler_is_enabled(atomic_intr_t *p); +int atomic_intr_cond_test(atomic_intr_t *p); +int atomic_intr_cond_try(atomic_intr_t *p); void atomic_intr_cond_enter(atomic_intr_t *p, void (*func)(void *), void *arg); void atomic_intr_cond_exit(atomic_intr_t *p, void (*func)(void *), void *arg); @@ -235,7 +256,7 @@ atomic_intr_handler_disable(atomic_intr_t *p) __asm __volatile(MPLOCKED "orl $0x40000000,%1; movl %1,%%eax; " \ "andl $0x80000000,%%eax" \ - : "=&a"(data) : "m"(*p)); + : "=a"(data) , "+m"(*p)); return(data); } @@ -272,6 +293,36 @@ atomic_intr_cond_enter(atomic_intr_t *p, void (*func)(void *), void *arg) : "ax", "cx", "dx"); } +/* + * Attempt to enter the interrupt condition variable. Returns zero on + * success, 1 on failure. + */ +static __inline +int +atomic_intr_cond_try(atomic_intr_t *p) +{ + int ret; + + __asm __volatile(MPLOCKED "incl %0; " \ + "1: ;" \ + "subl %%eax,%%eax; " \ + MPLOCKED "btsl $31,%0; jnc 2f; " \ + MPLOCKED "decl %0; " \ + "movl $1,%%eax;" \ + "2: ;" \ + : "+m" (*p), "=a"(ret) \ + : : "cx", "dx"); + return (ret); +} + + +static __inline +int +atomic_intr_cond_test(atomic_intr_t *p) +{ + return((int)(*p & 0x80000000)); +} + static __inline void atomic_intr_cond_exit(atomic_intr_t *p, void (*func)(void *), void *arg)