2015-09-06 34 views
-1

我開發了一個基於gcc的原子內置函數的可重入函數。不幸的是,我得到「計算,但不使用」的價值觀神祕警告:__atomic_exchange_n上的神祕「計算值未使用」警告#

$ gcc -c -Wall ss.c 
ss.c: In function ‘ss_wrapper’: 
ss.c:87:3: warning: value computed is not used [-Wunused-value] 
    __atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST); 
^
ss.c:91:5: warning: value computed is not used [-Wunused-value] 
    __atomic_exchange_n(&ss_top, bkp->next, __ATOMIC_SEQ_CST); // release the lock, find out if there is new element 
    ^

這是我的函數:

static void ss_wrapper(int signum, siginfo_t* siginfo, void *ucontext) { 
    // currently top element on the signal stack 
    static struct ss_hit* ss_top = NULL; 


    struct ss_hit* hit = ss_newhit(signum, siginfo, (ucontext_t*)ucontext); 
    struct ss_hit* bkp; 

    again: 

    bkp = hit; 
    __atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST); 
    if (!hit) { // we got the lock, we are the master 
    ss_fire(bkp); 

    // release the lock, find out if there is new element 
    __atomic_exchange_n(&ss_top, bkp->next, __ATOMIC_SEQ_CST); 
    if (bkp->next) { // there IS 

     hit = bkp; 
     free(bkp); 
     goto again; 

    } else 
     free(bkp); 
    } else { // we didn't got the lock, but we got the top in hit 
    __atomic_store(&hit->next, &bkp, __ATOMIC_SEQ_CST); 
    } 
} 

它爲什麼會發生? __atomic_exchange_n不應該計算任何東西,它只會交換兩個變量的內容。

+0

整個源文件可以找到[這裏](https://開頭raw.githubusercontent.com/HorvathAkosPeter/pipenet/master/staging/ss.c)。 – peterh

+0

你不應該直接使用atomic-builtins,而是使用C11'stdatomic.h'。爲什麼讓你的代碼依賴於編譯器而不需要實際的需要。 – Olaf

+0

@Olaf由於缺乏信任,我試圖使用可能的最低級別。但是現在我的代碼產生了良好的asm,沒有更多的理由不使用符合標準的方式,這就是我將要做的。 – peterh

回答

1

只交換兩個變量

不,它沒有的內容。它將一個變量的內容與寄存器的內容交換。第二個變量從不改變。 (即使沒有查閱文檔,這從用於傳遞兩個參數的不同慣例中顯而易見 - 原子交換的存儲器地址作爲指針傳遞,另一個值被複制,而不是適當地訪問)

作爲這種誤解的結果,你的邏輯被打破了。你的意思是:

hit = __atomic_exchange_n(&ss_top, hit, __ATOMIC_SEQ_CST); 
if (!hit) { // we got the lock, we are the master 

它將寄存器的新值寫回第二個變量。對hit的訪問是非原子的,但沒關係,因爲它是一個局部變量,不與任何其他線程共享。

不要只是扔掉的返回值,如果你這樣做,你將永遠不會進入分支爲「我們是主人」

+0

你有權利,這真的是使asm完美的唯一方法......也許我誤解了海灣合作委員會內部文件,也許不是。:-( – peterh

-1

@Olaf在評論中回答了我的問題:儘管聲明瞭一個虛擬變量__attribute__((unused)),並給他返回值可以避免警告,但還有一種更簡單的方法:將函數投射到(void),如下所示:

(void)__atomic_exchange_n(...); 

擴展:雖然這個解決方案還消除了警告,但仍然不使用__atomic_exchange_n GCC正確內建(雖然有時它編譯正確的代碼)。被接受的答案最終解決了這個問題。

+0

這並不能解決問題。是的,它顯示瞭如何放棄表達式的結果,但是讀取整個函數,顯然需要結果。 –

+0

@BenVoigt你有權利,這真的是使asm完美的唯一方法......也許我誤解了海灣合作委員會的內置文件,也許不是。 :-( – peterh