亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標題: 請問一個驅動代碼邏輯問題,高手請進 [打印本頁]

作者: jiangsheng84    時間: 2012-06-04 15:16
標題: 請問一個驅動代碼邏輯問題,高手請進
/**
* srpt_set_cmd_state() - Set the state of a SCSI command.
* @new: New state to be set.
*
* Does not modify the state of aborted commands. Returns the previous command
* state.
*/
enum srpt_command_state srpt_set_cmd_state(struct srpt_ioctx *     ioctx,
                                                  enum srpt_command_state new)
{
    enum srpt_command_state previous;

    BUG_ON(!ioctx);
    WARN_ON(new == SRPT_STATE_NEW);

    do
    {
        previous = atomic_read(&ioctx->state);
    } while ((previous != SRPT_STATE_DONE)
             && atomic_cmpxchg(&ioctx->state, previous, new) != previous);

    return previous;
}
按正常說,這段代碼執(zhí)行應該沒有什么問題,atomic_read和atomic_cmpxchg都能執(zhí)行成功。
但是為什么要用do while語句來實現(xiàn)呢?說明確實存在循環(huán)的可能嗎?會不會出現(xiàn)死循環(huán)呢?
因為我在中斷上下文執(zhí)行的時候,出了一次NMI的WATCHDOG復位,也就是在中斷中執(zhí)行時間太長了,
會不會是這里在某種情況下死循環(huán)呢?如果不是,為什么這里要寫出do while呢,完全可以用if啊!
(當然也有可能是執(zhí)行中斷中的其他部分代碼的時間太長導致NMI復位的)
作者: bruceteen    時間: 2012-06-04 15:26
看不懂,但 cmpxchg 和 循環(huán) 是一對好基友,達到非鎖原子操作
作者: jiangsheng84    時間: 2012-06-04 15:29
謝謝樓上的回復,但是這里貌似已經調用的是atomic_cmpxchg。槭裁催要循環(huán)呢,奇怪了
作者: jiangsheng84    時間: 2012-06-04 15:34
(previous != SRPT_STATE_DONE)不用管它,這個表示如果讀出來是處于done的狀態(tài)的話,就直接退出了,不在去改變它的狀態(tài)
那就相當于變成:
    do
    {
        previous = atomic_read(&ioctx->state);
    } while ( atomic_cmpxchg(&ioctx->state, previous, new) != previous);
先原子讀該狀態(tài),然后傳入atomic_cmpxchg函數(shù),該函數(shù)會重新讀ioctx->state得狀態(tài),然后和previous比較,如果相等,就修改
為新的狀態(tài)new,并且返回舊有的狀態(tài)(即previous)。
這樣看起來兩次都讀的同一個變量,肯定相等了,然后肯定就會修改為new的狀態(tài),并返回previous的狀態(tài),應該是一次就可以執(zhí)行成功啊
為什么需要do while的循環(huán)呢?
作者: bruceteen    時間: 2012-06-04 15:46
仔細看了一下
關于你的問題,這正是需要atomic的地方,因為可能多個進程在同時操作,atomic_read 和 atomic_cmpxchg 之間,可能被別的進程給 atomic_cmpxchg 了。


作者: jiangsheng84    時間: 2012-06-04 15:53
回復 5# bruceteen


    謝謝,我看內核里面也有許多類似的應用
/**
*        sysfs_get_active - get an active reference to sysfs_dirent
*        @sd: sysfs_dirent to get an active reference to
*
*        Get an active reference of @sd.  This function is noop if @sd
*        is NULL.
*
*        RETURNS:
*        Pointer to @sd on success, NULL on failure.
*/
static struct sysfs_dirent *sysfs_get_active(struct sysfs_dirent *sd)
{
        if (unlikely(!sd))
                return NULL;

        while (1) {
                int v, t;

                v = atomic_read(&sd->s_active);
                if (unlikely(v < 0))
                        return NULL;

                t = atomic_cmpxchg(&sd->s_active, v, v + 1);
                if (likely(t == v))
                        return sd;
                if (t < 0)
                        return NULL;

                cpu_relax();
        }
}
可以看到if (likely(t == v)),既然都likely了,說明一般情況下應該是都能成功的對吧!那應該是不會出現(xiàn)死循環(huán)的,即使有兩個線程在操作這個原子變量,應該
不可能剛好大家都在死循環(huán)來修改這個值吧!
作者: bruceteen    時間: 2012-06-04 16:05
不會死循環(huán)的,總會有一個進程通過
就像一群人不排隊上廁所一樣,馬桶不可能空著,即需要上廁所的人數(shù)會一直減少,不會有人永遠上不了廁所




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2