@@ -49,7 +49,6 @@ binit(void)
49
49
for (b = bcache .buf ; b < bcache .buf + NBUF ; b ++ ){
50
50
b -> next = bcache .head .next ;
51
51
b -> prev = & bcache .head ;
52
- b -> dev = -1 ;
53
52
initsleeplock (& b -> lock , "buffer" );
54
53
bcache .head .next -> prev = b ;
55
54
bcache .head .next = b ;
@@ -66,33 +65,33 @@ bget(uint dev, uint blockno)
66
65
67
66
acquire (& bcache .lock );
68
67
69
- //cprintf("bget %d\n", blockno);
70
- loop :
68
+ // cprintf("bget %d\n", blockno);
69
+
71
70
// Is the block already cached?
72
71
for (b = bcache .head .next ; b != & bcache .head ; b = b -> next ){
73
72
if (b -> dev == dev && b -> blockno == blockno ){
74
- if (!holdingsleep (& b -> lock )) {
75
- acquiresleep (& b -> lock );
76
- //cprintf("return buffer %p for blk %d\n", b - bcache.buf, blockno);
77
- release (& bcache .lock );
78
- return b ;
79
- }
80
- sleep (b , & bcache .lock );
81
- goto loop ;
73
+ //cprintf("bget %d; get sleep lock for buffer %p\n", blockno, b - bcache.buf);
74
+ b -> refcnt ++ ;
75
+ release (& bcache .lock );
76
+ acquiresleep (& b -> lock );
77
+ //cprintf("bget: return buffer %p for blk %d\n", b - bcache.buf, blockno);
78
+ return b ;
82
79
}
83
80
}
84
81
85
- // Not cached; recycle some non-locked and clean buffer.
82
+ // Not cached; recycle some unused buffer and clean buffer
86
83
// "clean" because B_DIRTY and not locked means log.c
87
84
// hasn't yet committed the changes to the buffer.
88
85
for (b = bcache .head .prev ; b != & bcache .head ; b = b -> prev ){
89
- if (!holdingsleep (& b -> lock ) && (b -> flags & B_DIRTY ) == 0 ){
86
+ if (b -> refcnt == 0 && (b -> flags & B_DIRTY ) == 0 ) {
87
+ // cprintf("bget %d; use %p for %d\n", b - bcache.buf, blockno);
90
88
b -> dev = dev ;
91
89
b -> blockno = blockno ;
92
- b -> flags = 0 ; // XXX
93
- acquiresleep (& b -> lock );
94
- //cprintf("return buffer %p for blk %d\n", b - bcache.buf, blockno);
90
+ b -> flags = 0 ;
91
+ b -> refcnt = 1 ;
95
92
release (& bcache .lock );
93
+ acquiresleep (& b -> lock );
94
+ // cprintf("bget: return buffer %p for blk %d\n", b - bcache.buf, blockno);
96
95
return b ;
97
96
}
98
97
}
@@ -116,7 +115,7 @@ bread(uint dev, uint blockno)
116
115
void
117
116
bwrite (struct buf * b )
118
117
{
119
- if (b -> lock . locked == 0 )
118
+ if (! holdingsleep ( & b -> lock ) )
120
119
panic ("bwrite" );
121
120
b -> flags |= B_DIRTY ;
122
121
iderw (b );
@@ -127,20 +126,23 @@ bwrite(struct buf *b)
127
126
void
128
127
brelse (struct buf * b )
129
128
{
130
- if (b -> lock . locked == 0 )
129
+ if (! holdingsleep ( & b -> lock ) )
131
130
panic ("brelse" );
132
131
133
- acquire (& bcache .lock );
134
-
135
- b -> next -> prev = b -> prev ;
136
- b -> prev -> next = b -> next ;
137
- b -> next = bcache .head .next ;
138
- b -> prev = & bcache .head ;
139
- bcache .head .next -> prev = b ;
140
- bcache .head .next = b ;
141
132
releasesleep (& b -> lock );
142
- wakeup (b );
143
133
134
+ acquire (& bcache .lock );
135
+ b -> refcnt -- ;
136
+ if (b -> refcnt == 0 ) {
137
+ // no one is waiting for it.
138
+ b -> next -> prev = b -> prev ;
139
+ b -> prev -> next = b -> next ;
140
+ b -> next = bcache .head .next ;
141
+ b -> prev = & bcache .head ;
142
+ bcache .head .next -> prev = b ;
143
+ bcache .head .next = b ;
144
+ }
145
+
144
146
release (& bcache .lock );
145
147
}
146
148
//PAGEBREAK!
0 commit comments