1
2
3
4
5
6
7
8
9#ifndef _ASM_SPINLOCK_H
10#define _ASM_SPINLOCK_H
11
12
13
14
15
16typedef struct {
17 volatile unsigned int lock;
18} spinlock_t;
19
20#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
21
22#define spin_lock_init(x) do { (x)->lock = 0; } while(0)
23
24#define spin_is_locked(x) ((x)->lock != 0)
25#define spin_unlock_wait(x) do { barrier(); } while ((x)->lock)
26
27
28
29
30
31
32
33
34static inline void spin_lock(spinlock_t *lock)
35{
36 unsigned int tmp;
37
38 __asm__ __volatile__(
39 ".set\tnoreorder\t\t\t# spin_lock\n"
40 "1:\tll\t%1, %2\n\t"
41 "bnez\t%1, 1b\n\t"
42 " li\t%1, 1\n\t"
43 "sc\t%1, %0\n\t"
44 "beqz\t%1, 1b\n\t"
45 " sync\n\t"
46 ".set\treorder"
47 : "=o" (lock->lock), "=&r" (tmp)
48 : "o" (lock->lock)
49 : "memory");
50}
51
52static inline void spin_unlock(spinlock_t *lock)
53{
54 __asm__ __volatile__(
55 ".set\tnoreorder\t\t\t# spin_unlock\n\t"
56 "sync\n\t"
57 "sw\t$0, %0\n\t"
58 ".set\treorder"
59 : "=o" (lock->lock)
60 : "o" (lock->lock)
61 : "memory");
62}
63
64static inline unsigned int spin_trylock(spinlock_t *lock)
65{
66 unsigned int temp, res;
67
68 __asm__ __volatile__(
69 ".set\tnoreorder\t\t\t# spin_trylock\n\t"
70 "1:\tll\t%0, %1\n\t"
71 "or\t%2, %0, %3\n\t"
72 "sc\t%2, %1\n\t"
73 "beqz\t%2, 1b\n\t"
74 " and\t%2, %0, %3\n\t"
75 ".set\treorder"
76 : "=&r" (temp), "=m" (lock->lock), "=&r" (res)
77 : "r" (1), "m" (lock->lock)
78 : "memory");
79
80 return res == 0;
81}
82
83
84
85
86
87
88
89
90
91
92typedef struct {
93 volatile unsigned int lock;
94} rwlock_t;
95
96#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
97
98static inline void read_lock(rwlock_t *rw)
99{
100 unsigned int tmp;
101
102 __asm__ __volatile__(
103 ".set\tnoreorder\t\t\t# read_lock\n"
104 "1:\tll\t%1, %2\n\t"
105 "bltz\t%1, 1b\n\t"
106 " addu\t%1, 1\n\t"
107 "sc\t%1, %0\n\t"
108 "beqz\t%1, 1b\n\t"
109 " sync\n\t"
110 ".set\treorder"
111 : "=o" (rw->lock), "=&r" (tmp)
112 : "o" (rw->lock)
113 : "memory");
114}
115
116
117
118
119static inline void read_unlock(rwlock_t *rw)
120{
121 unsigned int tmp;
122
123 __asm__ __volatile__(
124 ".set\tnoreorder\t\t\t# read_unlock\n"
125 "1:\tll\t%1, %2\n\t"
126 "sub\t%1, 1\n\t"
127 "sc\t%1, %0\n\t"
128 "beqz\t%1, 1b\n\t"
129 "sync\n\t"
130 ".set\treorder"
131 : "=o" (rw->lock), "=&r" (tmp)
132 : "o" (rw->lock)
133 : "memory");
134}
135
136static inline void write_lock(rwlock_t *rw)
137{
138 unsigned int tmp;
139
140 __asm__ __volatile__(
141 ".set\tnoreorder\t\t\t# write_lock\n"
142 "1:\tll\t%1, %2\n\t"
143 "bnez\t%1, 1b\n\t"
144 " lui\t%1, 0x8000\n\t"
145 "sc\t%1, %0\n\t"
146 "beqz\t%1, 1b\n\t"
147 " sync\n\t"
148 ".set\treorder"
149 : "=o" (rw->lock), "=&r" (tmp)
150 : "o" (rw->lock)
151 : "memory");
152}
153
154static inline void write_unlock(rwlock_t *rw)
155{
156 __asm__ __volatile__(
157 ".set\tnoreorder\t\t\t# write_unlock\n\t"
158 "sync\n\t"
159 "sw\t$0, %0\n\t"
160 ".set\treorder"
161 : "=o" (rw->lock)
162 : "o" (rw->lock)
163 : "memory");
164}
165
166#endif
167