-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbuf.c
105 lines (95 loc) · 2.52 KB
/
buf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include "buf.h"
#include "monitor.h"
#include "mem.h"
#include "ide.h"
#include "param.h"
struct {
struct buf buf[NBUF]; //缓存块数组
struct buf head; //链表头部
} bcache;
void binit(void)
{
bcache.head.prev = &bcache.head;
bcache.head.next = &bcache.head;
int i;
for (i = 0; i < NBUF; i++)
{
bcache.buf[i].next = bcache.head.next;
bcache.buf[i].prev = &bcache.head;
bcache.buf[i].dev = -1;
bcache.head.next->prev = &bcache.buf[i];
bcache.head.next = &bcache.buf[i];
}
}
void brelse(struct buf* cur)
{
if (cur->flags & BUF_BUSY)
PANIC("brelse");
cur->prev->next = cur->next;
cur->next->prev = cur->prev;
cur->next = bcache.head.next;
cur->prev = &bcache.head;
bcache.head.next->prev = cur;
bcache.head.next = cur;
}
static struct buf* bget(uint dev, uint sector)
{
int i;
for (i = 0; i < NBUF; i++)
{
if (bcache.buf[i].dev == dev && bcache.buf[i].sector == sector)
{
if (bcache.buf[i].flags & BUF_BUSY == 0)
{
brelse(&bcache.buf[i]);
return &bcache.buf[i];
}
else //该缓冲块正在被其他进程使用, 采用效率较低的轮询方式
{
i--;
continue;
}
}
}
//寻找其他的缓冲块,采用的算法是最近最少使用
struct buf *temp;
for (temp = bcache.head.prev; temp != &bcache.head; temp = temp->prev)
{
if (temp->flags & BUF_BUSY == 0)
{
//把该缓存块的值写入磁盘
if (temp->flags & BUF_DIRTY != 0)
iderw(temp);
temp->dev = dev;
temp->sector = sector;
temp->flags = 0; //清空该缓存块的标识
brelse(temp);
return temp;
}
}
PANIC("can't find buffer block");
}
//从磁盘读数据
struct buf* bread(uint dev, uint sector)
{
struct buf *b;
b = bget(dev, sector);
b->flags |= BUF_BUSY;
//如果不可用
if ( !(b->flags & BUF_VALID))
{
iderw(b); //从磁盘向该缓存中读数据
b->flags |= BUF_VALID;
}
b->flags &= ~BUF_BUSY;
return b;
}
//向磁盘写数据,在写之前一定要先读
//防止一个缓冲块中有多个磁盘块的数据
void bwrite(struct buf *b)
{
b->flags |= BUF_BUSY;
b->flags |= BUF_DIRTY;
iderw(b);
b->flags &= ~BUF_BUSY;
}