annotate src/spinlock.cbc @ 58:f1b965f53d3b

add tools userlists
author tobaru
date Fri, 05 Jul 2019 16:39:01 +0900
parents 214d21c891c7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 // Mutual exclusion spin locks.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 #include "types.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 #include "defs.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 #include "param.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 #include "arm.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 #include "memlayout.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 #include "mmu.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 #include "proc.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 #include "spinlock.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
52
214d21c891c7 rename to cbc
kono
parents: 37
diff changeset
12 #define __ncode __code
214d21c891c7 rename to cbc
kono
parents: 37
diff changeset
13 #
0
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 void initlock(struct spinlock *lk, char *name)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 lk->name = name;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 lk->locked = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 lk->cpu = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 // For single CPU systems, there is no need for spinlock.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 // Add the support when multi-processor is supported.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 // Acquire the lock.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 // Loops (spins) until the lock is acquired.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 // Holding a lock for a long time may cause
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 // other CPUs to waste time spinning to acquire it.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 void acquire(struct spinlock *lk)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 pushcli(); // disable interrupts to avoid deadlock.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 lk->locked = 1; // set the lock status to make the kernel happy
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 #if 0
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 if(holding(lk))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 panic("acquire");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 // The xchg is atomic.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 // It also serializes, so that reads after acquire are not
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 // reordered before it.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 while(xchg(&lk->locked, 1) != 0)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 ;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 // Record info about lock acquisition for debugging.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 lk->cpu = cpu;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 getcallerpcs(get_fp(), lk->pcs);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 #endif
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50
37
mir3636
parents: 35
diff changeset
51 /*
35
mir3636
parents: 0
diff changeset
52 void cbc_acquire(struct spinlock *lk, __code (*next)(int ret))
mir3636
parents: 0
diff changeset
53 {
mir3636
parents: 0
diff changeset
54 pushcli(); // disable interrupts to avoid deadlock.
mir3636
parents: 0
diff changeset
55 lk->locked = 1; // set the lock status to make the kernel happy
mir3636
parents: 0
diff changeset
56
mir3636
parents: 0
diff changeset
57 #if 0
mir3636
parents: 0
diff changeset
58 if(holding(lk))
mir3636
parents: 0
diff changeset
59 panic("acquire");
mir3636
parents: 0
diff changeset
60
mir3636
parents: 0
diff changeset
61 // The xchg is atomic.
mir3636
parents: 0
diff changeset
62 // It also serializes, so that reads after acquire are not
mir3636
parents: 0
diff changeset
63 // reordered before it.
mir3636
parents: 0
diff changeset
64 while(xchg(&lk->locked, 1) != 0)
mir3636
parents: 0
diff changeset
65 ;
mir3636
parents: 0
diff changeset
66
mir3636
parents: 0
diff changeset
67 // Record info about lock acquisition for debugging.
mir3636
parents: 0
diff changeset
68 lk->cpu = cpu;
mir3636
parents: 0
diff changeset
69 getcallerpcs(get_fp(), lk->pcs);
mir3636
parents: 0
diff changeset
70
mir3636
parents: 0
diff changeset
71 #endif
mir3636
parents: 0
diff changeset
72 goto next();
mir3636
parents: 0
diff changeset
73 }
37
mir3636
parents: 35
diff changeset
74 */
35
mir3636
parents: 0
diff changeset
75
37
mir3636
parents: 35
diff changeset
76 /*
0
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 // Release the lock.
35
mir3636
parents: 0
diff changeset
78 void cbc_release(struct spinlock *lk, __code (*next)(int ret))
mir3636
parents: 0
diff changeset
79 {
mir3636
parents: 0
diff changeset
80 #if 0
mir3636
parents: 0
diff changeset
81 if(!holding(lk))
mir3636
parents: 0
diff changeset
82 panic("release");
mir3636
parents: 0
diff changeset
83
mir3636
parents: 0
diff changeset
84 lk->pcs[0] = 0;
mir3636
parents: 0
diff changeset
85 lk->cpu = 0;
mir3636
parents: 0
diff changeset
86
mir3636
parents: 0
diff changeset
87 // The xchg serializes, so that reads before release are
mir3636
parents: 0
diff changeset
88 // not reordered after it. The 1996 PentiumPro manual (Volume 3,
mir3636
parents: 0
diff changeset
89 // 7.2) says reads can be carried out speculatively and in
mir3636
parents: 0
diff changeset
90 // any order, which implies we need to serialize here.
mir3636
parents: 0
diff changeset
91 // But the 2007 Intel 64 Architecture Memory Ordering White
mir3636
parents: 0
diff changeset
92 // Paper says that Intel 64 and IA-32 will not move a load
mir3636
parents: 0
diff changeset
93 // after a store. So lock->locked = 0 would work here.
mir3636
parents: 0
diff changeset
94 // The xchg being asm volatile ensures gcc emits it after
mir3636
parents: 0
diff changeset
95 // the above assignments (and after the critical section).
mir3636
parents: 0
diff changeset
96 xchg(&lk->locked, 0);
mir3636
parents: 0
diff changeset
97 #endif
mir3636
parents: 0
diff changeset
98
mir3636
parents: 0
diff changeset
99 lk->locked = 0; // set the lock state to keep the kernel happy
mir3636
parents: 0
diff changeset
100 popcli();
mir3636
parents: 0
diff changeset
101 goto next();
mir3636
parents: 0
diff changeset
102 }
37
mir3636
parents: 35
diff changeset
103 */
35
mir3636
parents: 0
diff changeset
104
0
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 void release(struct spinlock *lk)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 #if 0
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 if(!holding(lk))
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 panic("release");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 lk->pcs[0] = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 lk->cpu = 0;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 // The xchg serializes, so that reads before release are
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 // not reordered after it. The 1996 PentiumPro manual (Volume 3,
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 // 7.2) says reads can be carried out speculatively and in
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 // any order, which implies we need to serialize here.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 // But the 2007 Intel 64 Architecture Memory Ordering White
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 // Paper says that Intel 64 and IA-32 will not move a load
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 // after a store. So lock->locked = 0 would work here.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 // The xchg being asm volatile ensures gcc emits it after
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 // the above assignments (and after the critical section).
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 xchg(&lk->locked, 0);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 #endif
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 lk->locked = 0; // set the lock state to keep the kernel happy
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 popcli();
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 // Check whether this cpu is holding the lock.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 int holding(struct spinlock *lock)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 return lock->locked; // && lock->cpu == cpus;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136