make grade 80/80 with comment

This commit is contained in:
ridethepig 2023-02-04 14:17:55 +00:00
parent c67450b32b
commit d4798926a3
2 changed files with 18 additions and 12 deletions

View File

@ -98,20 +98,20 @@ bget(uint dev, uint blockno)
} }
h = h->next; h = h->next;
} }
release(&hash_locks[bucket]);
// release the unfound bucket, or there'll be deadlock
acquire(&bcache.lock); 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){ for(int i = 0; i < NBUF; ++ i){
b = &bcache.buf[i]; b = &bcache.buf[i];
if(b->refcnt == 0) {
int victim_bucket = b->blockno % NLOCK_BUCKETS; int victim_bucket = b->blockno % NLOCK_BUCKETS;
acquire(&hash_locks[victim_bucket]);
if(b->refcnt == 0) {
b->dev = dev; b->dev = dev;
b->blockno = blockno; b->blockno = blockno;
b->valid = 0; b->valid = 0;
b->refcnt = 1; 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 // try to release hash entry from the old bucket
h = hash_entry[victim_bucket]; h = hash_entry[victim_bucket];
ph = 0; ph = 0;
@ -124,19 +124,19 @@ bget(uint dev, uint blockno)
ph = h; ph = h;
h = h->next; 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]; h = &hash_tbls[i];
acquire(&hash_locks[bucket]);
h->next = hash_entry[bucket]; h->next = hash_entry[bucket];
hash_entry[bucket] = h; hash_entry[bucket] = h;
if (victim_bucket != bucket) {
// release(&hash_locks[victim_bucket]);
}
release(&bcache.lock);
release(&hash_locks[bucket]); release(&hash_locks[bucket]);
acquiresleep(&b->lock); acquiresleep(&b->lock);
return b; return b;
} }
release(&hash_locks[victim_bucket]);
} }
#else #else
// Is the block already cached? // Is the block already cached?
@ -201,6 +201,11 @@ brelse(struct buf *b)
releasesleep(&b->lock); 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; int bucket = b->blockno % NLOCK_BUCKETS;
acquire(&hash_locks[bucket]); acquire(&hash_locks[bucket]);
b->refcnt--; b->refcnt--;

1
time.txt Normal file
View File

@ -0,0 +1 @@
9