We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
你用的是holding判断,但是去看holding的实现,只有当前线程持有了传入的锁,才会返回1. 所以,用holding判断其实没什么用。 你的那个能够通过测试的原因是因为你优先从当前槽位开始搜索空闲buf,就像博客里面说的,这样会降低死锁的概率。 所以,测试用例就没有测到这种情况。 如果把你的实现改为从第0个槽位开始搜索空闲buf的话,那么就不会通过测试用例了。
另外,我觉得可以把holding函数换一下,自己新写一个函数,去掉后面的判断当前cpu是不是持有锁的cpu。然后使用这个函数。
int islock(struct spinlock *lk) { int r; r = (lk->locked); return r; } static struct buf* bget(uint dev, uint blockno) { struct buf *b; int index = hash(blockno); acquire(&bcache[index].lock); // Is the block already cached? for(b = bcache[index].head; b != 0; b = b->next){ if(b->dev == dev && b->blockno == blockno){ //printf("block num:%d,increcse++\n",blockno); b->refcnt++; release(&bcache[index].lock); acquiresleep(&b->lock); return b; } } // printf("inner\n"); for(int i = 0;i < HASHLEN;i++){ // 由于在这里的时候,还是持有index这个位置的锁的。所以当当前的i跟index不同的时候,才需要去尝试获取锁。 if(i != index){ if(islock(&bcache[i].lock)){ continue; } acquire(&bcache[i].lock); } struct buf *temp = bcache[i].head; struct buf *pre = 0; while (temp){ if(temp->refcnt == 0) { // 找到一个空闲的buf,就把它设置好各种参数 temp->dev = dev; temp->blockno = blockno; temp->valid = 0; temp->refcnt = 1; // 开始移动这个buf if(i == index){ // 如果就是在哈希目标的位置上找到的buf,那就不用移动 release(&bcache[i].lock); }else{ // 不然需要将该buf移动到哈希目标的位置上,在这个分支中,此时已经获取到了两个锁,一个是index,一个是i // i是找到的空闲buf的位置,index是目标下标位置 if(pre != 0){ pre->next = temp->next; }else{ bcache[i].head = temp->next; } // 将i位置的temp节点从单链表中移除之后,就能够释放i位置的锁了。 release(&bcache[i].lock); // 此时还是有index位置的锁,此时将temp加入到index的单链表中 temp->next = bcache[index].head; bcache[index].head = temp; release(&bcache[index].lock); } acquiresleep(&temp->lock); //printf("新分配,block num:%d,ref count:%d\n",temp->blockno,temp->refcnt); return temp; } pre = temp; temp = temp->next; } if(i != index){ release(&bcache[i].lock); } } panic("bget: no buffers"); }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
你用的是holding判断,但是去看holding的实现,只有当前线程持有了传入的锁,才会返回1.
所以,用holding判断其实没什么用。
你的那个能够通过测试的原因是因为你优先从当前槽位开始搜索空闲buf,就像博客里面说的,这样会降低死锁的概率。
所以,测试用例就没有测到这种情况。
如果把你的实现改为从第0个槽位开始搜索空闲buf的话,那么就不会通过测试用例了。
另外,我觉得可以把holding函数换一下,自己新写一个函数,去掉后面的判断当前cpu是不是持有锁的cpu。然后使用这个函数。
The text was updated successfully, but these errors were encountered: