annotate src/bio.c @ 94:d876c9a65239 default tip

impl mac os target
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Wed, 23 Oct 2019 14:31:38 +0900
parents 83c23a36980d
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 // Buffer cache.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 //
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 // The buffer cache is a linked list of buf structures holding
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 // cached copies of disk block contents. Caching disk blocks
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 // in memory reduces the number of disk reads and also provides
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 // a synchronization point for disk blocks used by multiple processes.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 //
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 // Interface:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 // * To get a buffer for a particular disk block, call bread.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 // * After changing buffer data, call bwrite to write it to disk.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 // * When done with the buffer, call brelse.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 // * Do not use the buffer after calling brelse.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 // * Only one process at a time can use a buffer,
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 // so do not keep them longer than necessary.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 //
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 // The implementation uses three state flags internally:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 // * B_BUSY: the block has been returned from bread
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 // and has not been passed back to brelse.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 // * B_VALID: the buffer data has been read from the disk.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 // * B_DIRTY: the buffer data has been modified
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 // and needs to be written to disk.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "types.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 #include "defs.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "param.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "spinlock.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 #include "buf.h"
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 struct {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 struct spinlock lock;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 struct buf buf[NBUF];
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 // Linked list of all buffers, through prev/next.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 // head.next is most recently used.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 struct buf head;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 } bcache;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 void binit (void)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 struct buf *b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 initlock(&bcache.lock, "bcache");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 //PAGEBREAK!
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 // Create linked list of buffers
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 bcache.head.prev = &bcache.head;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 bcache.head.next = &bcache.head;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 for (b = bcache.buf; b < bcache.buf + NBUF; b++) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 b->next = bcache.head.next;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 b->prev = &bcache.head;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 b->dev = -1;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 bcache.head.next->prev = b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 bcache.head.next = b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 // Look through buffer cache for sector on device dev.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 // If not found, allocate fresh block.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 // In either case, return B_BUSY buffer.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 static struct buf* bget (uint dev, uint sector)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63 struct buf *b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 acquire(&bcache.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 loop:
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 // Is the sector already cached?
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 for (b = bcache.head.next; b != &bcache.head; b = b->next) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 if (b->dev == dev && b->sector == sector) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 if (!(b->flags & B_BUSY)) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 b->flags |= B_BUSY;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 release(&bcache.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 return b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 sleep(b, &bcache.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 goto loop;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 // Not cached; recycle some non-busy and clean buffer.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 for (b = bcache.head.prev; b != &bcache.head; b = b->prev) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 if ((b->flags & B_BUSY) == 0 && (b->flags & B_DIRTY) == 0) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 b->dev = dev;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 b->sector = sector;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 b->flags = B_BUSY;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 release(&bcache.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 return b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 panic("bget: no buffers");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 // Return a B_BUSY buf with the contents of the indicated disk sector.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 struct buf* bread (uint dev, uint sector)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 struct buf *b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 b = bget(dev, sector);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 if (!(b->flags & B_VALID)) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104 iderw(b);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 return b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 // Write b's contents to disk. Must be B_BUSY.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 void bwrite (struct buf *b)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 if ((b->flags & B_BUSY) == 0) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 panic("bwrite");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 b->flags |= B_DIRTY;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 iderw(b);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 // Release a B_BUSY buffer.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 // Move to the head of the MRU list.
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 void brelse (struct buf *b)
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 if ((b->flags & B_BUSY) == 0) {
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 panic("brelse");
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 acquire(&bcache.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 b->next->prev = b->prev;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 b->prev->next = b->next;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 b->next = bcache.head.next;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 b->prev = &bcache.head;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 bcache.head.next->prev = b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 bcache.head.next = b;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 b->flags &= ~B_BUSY;
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 wakeup(b);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 release(&bcache.lock);
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 }
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143