首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DragonflyBSD:锁管理器(kern_lock.c)代码中可能存在争用条件?

DragonflyBSD:锁管理器(kern_lock.c)代码中可能存在争用条件?
EN

Stack Overflow用户
提问于 2020-01-29 19:21:48
回答 1查看 83关注 0票数 0

最近,我一直在阅读lock_manager (kern_lock.c)代码,遇到了一些我认为会产生竞争条件的场景。

步骤1:

@undo_shreq(...):如果有一个升级请求挂起,代码将重置"LKC_UPREQ“标志并调用wakeup();只有在以下情况下才会发生这种情况

代码语言:javascript
复制
(count & (LKC_EXREQ | LKC_UPREQ | LKC_CANCEL)) &&

       (count & (LKC_SMASK | LKC_XMASK)) == 0)

第2步:

现在,并行地,另一个线程T2正在尝试获得排它锁,并且它达到了平凡条件(即) @lockmgr_exclusive(...)

代码语言:javascript
复制
if ((count & (LKC_UPREQ | LKC_EXREQ |
      LKC_XMASK)) == 0 &&
    ((count & LKC_SHARED) == 0 ||
     (count & LKC_SMASK) == 0))

因此,T2将计数加1,并将其自身设置为拥有者线程--这意味着它获得了排他性。

第3步:

一个线程(T1)在LKC_UPREQ标志上休眠,由步骤1唤醒;以下是休眠后的代码(....after、LK_SLEEPFAIL和睡眠错误健全性检查),@lockmgr_upgrade(...)

代码语言:javascript
复制
if ((count & LKC_UPREQ) == 0) {           // reset by step 1
KKASSERT((count & LKC_XMASK) == 1);      // true, by step 2
lkp->lk_lockholder = td;
break;
}

我明白了(如果我错了,请纠正我),在步骤3,线程T1将lk_lockholder重置为自身--这意味着它获得了排他性!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-30 01:34:33

它的工作方式是,如果一个线程设置了UPREQ,然后休眠,另一个线程将授予它独占锁并唤醒它。授权线程清除UPREQ并递增独占计数,但是不知道是谁设置了UPREQ,因此接下来由设置UPREQ的线程来设置lockholder字段。

由于lockmgr代码必须同时处理多个独占到单个共享的饥饿、多个共享到单个独占的饥饿情况和死锁边缘情况,因此它相当复杂。在过去的一两年里,已经发现了边缘案例,但在我看来,这个特殊案例并不像是一个bug。只是有点混乱,因为排他锁是由第二个线程授予的(UPREQ清除,excl计数递增),但是第一线程仍然负责设置lk_lockholder字段。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59965974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档