This source file includes following definitions.
- binit
- bget
- bread
- bwrite
- brelse
- bpin
- bunpin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include "types.h"
18 #include "param.h"
19 #include "spinlock.h"
20 #include "sleeplock.h"
21 #include "riscv.h"
22 #include "defs.h"
23 #include "fs.h"
24 #include "buf.h"
25
26 struct {
27 struct spinlock lock;
28 struct buf buf[NBUF];
29
30
31
32
33 struct buf head;
34 } bcache;
35
36 void
37 binit(void)
38 {
39 struct buf *b;
40
41 initlock(&bcache.lock, "bcache");
42
43
44 bcache.head.prev = &bcache.head;
45 bcache.head.next = &bcache.head;
46 for(b = bcache.buf; b < bcache.buf+NBUF; b++){
47 b->next = bcache.head.next;
48 b->prev = &bcache.head;
49 initsleeplock(&b->lock, "buffer");
50 bcache.head.next->prev = b;
51 bcache.head.next = b;
52 }
53 }
54
55
56
57
58 static struct buf*
59 bget(uint dev, uint blockno)
60 {
61 struct buf *b;
62
63 acquire(&bcache.lock);
64
65
66 for(b = bcache.head.next; b != &bcache.head; b = b->next){
67 if(b->dev == dev && b->blockno == blockno){
68 b->refcnt++;
69 release(&bcache.lock);
70 acquiresleep(&b->lock);
71 return b;
72 }
73 }
74
75
76
77 for(b = bcache.head.prev; b != &bcache.head; b = b->prev){
78 if(b->refcnt == 0) {
79 b->dev = dev;
80 b->blockno = blockno;
81 b->valid = 0;
82 b->refcnt = 1;
83 release(&bcache.lock);
84 acquiresleep(&b->lock);
85 return b;
86 }
87 }
88 panic("bget: no buffers");
89 }
90
91
92 struct buf*
93 bread(uint dev, uint blockno)
94 {
95 struct buf *b;
96
97 b = bget(dev, blockno);
98 if(!b->valid) {
99 virtio_disk_rw(b, 0);
100 b->valid = 1;
101 }
102 return b;
103 }
104
105
106 void
107 bwrite(struct buf *b)
108 {
109 if(!holdingsleep(&b->lock))
110 panic("bwrite");
111 virtio_disk_rw(b, 1);
112 }
113
114
115
116 void
117 brelse(struct buf *b)
118 {
119 if(!holdingsleep(&b->lock))
120 panic("brelse");
121
122 releasesleep(&b->lock);
123
124 acquire(&bcache.lock);
125 b->refcnt--;
126 if (b->refcnt == 0) {
127
128 b->next->prev = b->prev;
129 b->prev->next = b->next;
130 b->next = bcache.head.next;
131 b->prev = &bcache.head;
132 bcache.head.next->prev = b;
133 bcache.head.next = b;
134 }
135
136 release(&bcache.lock);
137 }
138
139 void
140 bpin(struct buf *b) {
141 acquire(&bcache.lock);
142 b->refcnt++;
143 release(&bcache.lock);
144 }
145
146 void
147 bunpin(struct buf *b) {
148 acquire(&bcache.lock);
149 b->refcnt--;
150 release(&bcache.lock);
151 }
152
153