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
64#define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
65
66
67
68
69
70
71
72
73
74
75typedef struct {
76 volatile unsigned int lock;
77} rwlock_t;
78
79#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
80
81static inline void read_lock(rwlock_t *rw)
82{
83 unsigned int tmp;
84
85 __asm__ __volatile__(
86 ".set\tnoreorder\t\t\t# read_lock\n"
87 "1:\tll\t%1, %2\n\t"
88 "bltz\t%1, 1b\n\t"
89 " addu\t%1, 1\n\t"
90 "sc\t%1, %0\n\t"
91 "beqz\t%1, 1b\n\t"
92 " sync\n\t"
93 ".set\treorder"
94 : "=o" (rw->lock), "=&r" (tmp)
95 : "o" (rw->lock)
96 : "memory");
97}
98
99
100
101
102static inline void read_unlock(rwlock_t *rw)
103{
104 unsigned int tmp;
105
106 __asm__ __volatile__(
107 ".set\tnoreorder\t\t\t# read_unlock\n"
108 "1:\tll\t%1, %2\n\t"
109 "sub\t%1, 1\n\t"
110 "sc\t%1, %0\n\t"
111 "beqz\t%1, 1b\n\t"
112 ".set\treorder"
113 : "=o" (rw->lock), "=&r" (tmp)
114 : "o" (rw->lock)
115 : "memory");
116}
117
118static inline void write_lock(rwlock_t *rw)
119{
120 unsigned int tmp;
121
122 __asm__ __volatile__(
123 ".set\tnoreorder\t\t\t# write_lock\n"
124 "1:\tll\t%1, %2\n\t"
125 "bnez\t%1, 1b\n\t"
126 " lui\t%1, 0x8000\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_unlock(rwlock_t *rw)
137{
138 __asm__ __volatile__(
139 ".set\tnoreorder\t\t\t# write_unlock\n\t"
140 "sync\n\t"
141 "sw\t$0, %0\n\t"
142 ".set\treorder"
143 : "=o" (rw->lock)
144 : "o" (rw->lock)
145 : "memory");
146}
147
148#endif
149