make grade 80/80 with comment
This commit is contained in:
parent
c67450b32b
commit
d4798926a3
29
kernel/bio.c
29
kernel/bio.c
@ -98,20 +98,20 @@ bget(uint dev, uint blockno)
|
||||
}
|
||||
h = h->next;
|
||||
}
|
||||
release(&hash_locks[bucket]);
|
||||
// release the unfound bucket, or there'll be deadlock
|
||||
acquire(&bcache.lock);
|
||||
// after bcache.lock is aquired, only b->refcnt maybe out of our control
|
||||
// so, have to aquire hash_locks[victim_bucket] before test refcnt
|
||||
for(int i = 0; i < NBUF; ++ i){
|
||||
b = &bcache.buf[i];
|
||||
if(b->refcnt == 0) {
|
||||
int victim_bucket = b->blockno % NLOCK_BUCKETS;
|
||||
acquire(&hash_locks[victim_bucket]);
|
||||
if(b->refcnt == 0) {
|
||||
b->dev = dev;
|
||||
b->blockno = blockno;
|
||||
b->valid = 0;
|
||||
b->refcnt = 1;
|
||||
// first find the victim's hash
|
||||
if (victim_bucket != bucket)
|
||||
{
|
||||
// acquire(&hash_locks[victim_bucket]);
|
||||
}
|
||||
// try to release hash entry from the old bucket
|
||||
h = hash_entry[victim_bucket];
|
||||
ph = 0;
|
||||
@ -124,19 +124,19 @@ bget(uint dev, uint blockno)
|
||||
ph = h;
|
||||
h = h->next;
|
||||
}
|
||||
// add it to new hash entry
|
||||
release(&hash_locks[victim_bucket]);
|
||||
release(&bcache.lock);
|
||||
// this should avoid deadlock and meanwhile guard the hashtable
|
||||
// because after b is set, the only thing we need is hashtable rather than buf attributes
|
||||
h = &hash_tbls[i];
|
||||
acquire(&hash_locks[bucket]);
|
||||
h->next = hash_entry[bucket];
|
||||
hash_entry[bucket] = h;
|
||||
|
||||
if (victim_bucket != bucket) {
|
||||
// release(&hash_locks[victim_bucket]);
|
||||
}
|
||||
release(&bcache.lock);
|
||||
release(&hash_locks[bucket]);
|
||||
acquiresleep(&b->lock);
|
||||
return b;
|
||||
}
|
||||
release(&hash_locks[victim_bucket]);
|
||||
}
|
||||
#else
|
||||
// Is the block already cached?
|
||||
@ -201,6 +201,11 @@ brelse(struct buf *b)
|
||||
|
||||
releasesleep(&b->lock);
|
||||
|
||||
// if you use bcache lock, test0 fails without doubt
|
||||
// the reason why this works is that, whenever b->refcnt is written or read
|
||||
// its 'hash_locks[H(b->blockno)]' will always been locked
|
||||
// the reason why b->blockno is valid is that, only when refcnt==0 could this field be written
|
||||
// but here it must be non-zero before lock aquired
|
||||
int bucket = b->blockno % NLOCK_BUCKETS;
|
||||
acquire(&hash_locks[bucket]);
|
||||
b->refcnt--;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user