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