1*7e321ac1Sguenther /* $OpenBSD: _atomic_lock.c,v 1.1 2017/08/15 06:13:24 guenther Exp $ */ 2*7e321ac1Sguenther /* David Leonard, <d@csee.uq.edu.au>. Public domain. */ 3*7e321ac1Sguenther 4*7e321ac1Sguenther /* 5*7e321ac1Sguenther * Atomic lock for i386 6*7e321ac1Sguenther */ 7*7e321ac1Sguenther 8*7e321ac1Sguenther #include <machine/spinlock.h> 9*7e321ac1Sguenther 10*7e321ac1Sguenther int _atomic_lock(volatile _atomic_lock_t * lock)11*7e321ac1Sguenther_atomic_lock(volatile _atomic_lock_t *lock) 12*7e321ac1Sguenther { 13*7e321ac1Sguenther _atomic_lock_t old; 14*7e321ac1Sguenther 15*7e321ac1Sguenther /* 16*7e321ac1Sguenther * Use the eXCHanGe instruction to swap the lock value with 17*7e321ac1Sguenther * a local variable containing the locked state. 18*7e321ac1Sguenther */ 19*7e321ac1Sguenther old = _ATOMIC_LOCK_LOCKED; 20*7e321ac1Sguenther __asm__("xchg %0,(%2)" 21*7e321ac1Sguenther : "=r" (old) 22*7e321ac1Sguenther : "0" (old), "r" (lock)); 23*7e321ac1Sguenther 24*7e321ac1Sguenther return (old != _ATOMIC_LOCK_UNLOCKED); 25*7e321ac1Sguenther } 26