1 /************************************************************************
2 **                                                                     **
3 **                   The YapTab/YapOr/OPTYap systems                   **
4 **                                                                     **
5 ** YapTab extends the Yap Prolog engine to support sequential tabling  **
6 ** YapOr extends the Yap Prolog engine to support or-parallelism       **
7 ** OPTYap extends the Yap Prolog engine to support or-parallel tabling **
8 **                                                                     **
9 **                                                                     **
10 **      Yap Prolog was developed at University of Porto, Portugal      **
11 **                                                                     **
12 ************************************************************************/
13 
14 /************************************************************************
15 **                        Atomic locks for ALPHA                       **
16 ************************************************************************/
17 
18 /* This code is stolen from the Linux kernel */
19 
_test_and_set_bit(unsigned long nr,volatile void * addr)20 static __inline__ int _test_and_set_bit(unsigned long nr,
21 				       volatile void * addr)
22 {
23 	unsigned long oldbit;
24 	unsigned long temp;
25 	unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
26 
27 	__asm__ __volatile__(
28 	"1:	ldl_l %0,%1\n"
29 	"	and %0,%3,%2\n"
30 	"	bne %2,2f\n"
31 	"	xor %0,%3,%0\n"
32 	"	stl_c %0,%1\n"
33 	"	beq %0,3f\n"
34 	"	mb\n"
35 	"2:\n"
36 	".subsection 2\n"
37 	"3:	br 1b\n"
38 	".previous"
39 	:"=&r" (temp), "=m" (*m), "=&r" (oldbit)
40 	:"Ir" (1UL << (nr & 31)), "m" (*m));
41 
42 	return oldbit != 0;
43 }
44 
_spin_lock(volatile void * lock)45 static __inline__ void _spin_lock(volatile void *lock)
46 {
47 	long tmp;
48 
49 	/* Use sub-sections to put the actual loop at the end
50 	   of this object file's text section so as to perfect
51 	   branch prediction.  */
52 	__asm__ __volatile__(
53 	"1:	ldl_l	%0,%1\n"
54 	"	blbs	%0,2f\n"
55 	"	or	%0,1,%0\n"
56 	"	stl_c	%0,%1\n"
57 	"	beq	%0,2f\n"
58 	"	mb\n"
59 	".subsection 2\n"
60 	"2:	ldl	%0,%1\n"
61 	"	blbs	%0,2b\n"
62 	"	br	1b\n"
63 	".previous"
64 	: "=r" (tmp), "=m" (__dummy_lock(lock))
65 	: "m"(__dummy_lock(lock)));
66 }
67 
_write_lock(rwlock_t * lock)68 static inline void _write_lock(rwlock_t * lock)
69 {
70 	long regx;
71 
72 	__asm__ __volatile__(
73 	"1:	ldl_l	%1,%0\n"
74 	"	bne	%1,6f\n"
75 	"	or	$31,1,%1\n"
76 	"	stl_c	%1,%0\n"
77 	"	beq	%1,6f\n"
78 	"	mb\n"
79 	".subsection 2\n"
80 	"6:	ldl	%1,%0\n"
81 	"	bne	%1,6b\n"
82 	"	br	1b\n"
83 	".previous"
84 	: "=m" (__dummy_lock(lock)), "=&r" (regx)
85 	: "0" (__dummy_lock(lock))
86 	);
87 }
88 
_read_lock(rwlock_t * lock)89 static inline void _read_lock(rwlock_t * lock)
90 {
91 	long regx;
92 
93 	__asm__ __volatile__(
94 	"1:	ldl_l	%1,%0\n"
95 	"	blbs	%1,6f\n"
96 	"	subl	%1,2,%1\n"
97 	"	stl_c	%1,%0\n"
98 	"	beq	%1,6f\n"
99 	"4:	mb\n"
100 	".subsection 2\n"
101 	"6:	ldl	%1,%0\n"
102 	"	blbs	%1,6b\n"
103 	"	br	1b\n"
104 	".previous"
105 	: "=m" (__dummy_lock(lock)), "=&r" (regx)
106 	: "m" (__dummy_lock(lock))
107 	);
108 }
109 
110 
_write_unlock(rwlock_t * lock)111 static inline void _write_unlock(rwlock_t * lock)
112 {
113 	mb();
114 	*(volatile int *)lock = 0;
115 }
116 
_read_unlock(rwlock_t * lock)117 static inline void _read_unlock(rwlock_t * lock)
118 {
119 	long regx;
120 	__asm__ __volatile__(
121 	"1:	ldl_l	%1,%0\n"
122 	"	addl	%1,2,%1\n"
123 	"	stl_c	%1,%0\n"
124 	"	beq	%1,6f\n"
125 	".subsection 2\n"
126 	"6:	br	1b\n"
127 	".previous"
128 	: "=m" (__dummy_lock(lock)), "=&r" (regx)
129 	: "m" (__dummy_lock(lock)));
130 }
131 
132