blob: cc4effe06f9571107c95c9246795ef5b7f4a5b01 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/* $OpenBSD: _atomic_lock.c,v 1.7 2008/10/02 23:27:23 deraadt Exp $ */
/* David Leonard, <d@csee.uq.edu.au>. Public domain. */
/*
* Atomic lock for m68k
*/
#include "spinlock.h"
int
_atomic_lock(volatile _spinlock_lock_t *lock)
{
_spinlock_lock_t old;
/*
* The Compare And Swap instruction (mc68020 and above)
* compares its first operand with the memory addressed by
* the third. If they are the same value, the second operand
* is stored at the address. Otherwise the 1st operand (register)
* is loaded with the contents of the 3rd operand.
*
* old = 0;
* CAS(old, 1, *lock);
* if (old == 1) { lock was acquired }
*
* From the MC68030 User's Manual (Motorola), page `3-13':
* CAS Dc,Du,<ea>:
* (<ea> - Dc) -> cc;
* if Z then Du -> <ea>
* else <ea> -> Dc;
*/
old = _SPINLOCK_UNLOCKED;
__asm__("casl %0, %2, %1" : "=d" (old), "=m" (*lock)
: "d" (_SPINLOCK_LOCKED),
"0" (old), "1" (*lock)
: "cc");
return (old != _SPINLOCK_UNLOCKED);
}
|