Skip to content

Commit 2adb7c2

Browse files
committed
Move retry loop/sleep/wakeup in bio.c into sleeping locks
1 parent 6670d3b commit 2adb7c2

File tree

3 files changed

+31
-28
lines changed

3 files changed

+31
-28
lines changed

bio.c

+29-27
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ binit(void)
4949
for(b = bcache.buf; b < bcache.buf+NBUF; b++){
5050
b->next = bcache.head.next;
5151
b->prev = &bcache.head;
52-
b->dev = -1;
5352
initsleeplock(&b->lock, "buffer");
5453
bcache.head.next->prev = b;
5554
bcache.head.next = b;
@@ -66,33 +65,33 @@ bget(uint dev, uint blockno)
6665

6766
acquire(&bcache.lock);
6867

69-
//cprintf("bget %d\n", blockno);
70-
loop:
68+
// cprintf("bget %d\n", blockno);
69+
7170
// Is the block already cached?
7271
for(b = bcache.head.next; b != &bcache.head; b = b->next){
7372
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;
8279
}
8380
}
8481

85-
// Not cached; recycle some non-locked and clean buffer.
82+
// Not cached; recycle some unused buffer and clean buffer
8683
// "clean" because B_DIRTY and not locked means log.c
8784
// hasn't yet committed the changes to the buffer.
8885
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);
9088
b->dev = dev;
9189
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;
9592
release(&bcache.lock);
93+
acquiresleep(&b->lock);
94+
// cprintf("bget: return buffer %p for blk %d\n", b - bcache.buf, blockno);
9695
return b;
9796
}
9897
}
@@ -116,7 +115,7 @@ bread(uint dev, uint blockno)
116115
void
117116
bwrite(struct buf *b)
118117
{
119-
if(b->lock.locked == 0)
118+
if(!holdingsleep(&b->lock))
120119
panic("bwrite");
121120
b->flags |= B_DIRTY;
122121
iderw(b);
@@ -127,20 +126,23 @@ bwrite(struct buf *b)
127126
void
128127
brelse(struct buf *b)
129128
{
130-
if(b->lock.locked == 0)
129+
if(!holdingsleep(&b->lock))
131130
panic("brelse");
132131

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;
141132
releasesleep(&b->lock);
142-
wakeup(b);
143133

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+
144146
release(&bcache.lock);
145147
}
146148
//PAGEBREAK!

buf.h

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ struct buf {
33
uint dev;
44
uint blockno;
55
struct sleeplock lock;
6+
uint refcnt;
67
struct buf *prev; // LRU cache list
78
struct buf *next;
89
struct buf *qnext; // disk queue

defs.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void popcli(void);
131131

132132
// sleeplock.c
133133
void acquiresleep(struct sleeplock*);
134-
void releasesleep(struct sleeplock*);
134+
void releasesleep(struct sleeplock*);
135135
int holdingsleep(struct sleeplock*);
136136
void initsleeplock(struct sleeplock*, char*);
137137

0 commit comments

Comments
 (0)