簡體   English   中英

在gcc MinGW上互鎖Or8

[英]InterlockedOr8 on gcc MinGW

我對CodeBlocks 12.11隨附的MinGW的出廠版本沒有任何問題。 但是現在我嘗試編譯SyncSys 編譯enet沒問題,但是用gcc / MinGW編譯SyncSys本身會帶來錯誤,我不能使用函數_InterlockedOr8,因為它沒有聲明。 研究得出的事實是,_interlockedOr8在intrin.h中定義。 不包括intrin.h,我在MinGW / gcc上搜索了它的等效項:x86intrin.h。 但這仍然行不通。 InterlockedOr8將是要調用的“實際”函數,但是盡管包含了winbase.h和windows.h,但編譯器也找不到該函數。

在研究這個問題的時候,很少有我無法學習的命中。 我怎樣才能解決這個問題?

_InterlockedOr8是Microsoft編譯器獨有的固有編譯器功能-意味着編譯器會自動將實現內聯到代碼中,而不是與庫鏈接。 <intr.h>是與Visual Studio一起分發的頭文件,與Windows SDK分開。

如果您無法切換到Visual Studio( 免費下載,btw ),則可以定義此函數的自己的替換版本:

void InterlockedOr8(char* dst, char src)
{
    __asm
    {
        mov eax, dst       ; EAX = dst
        mov cl, src        ; ECX = src
        lock or [eax], cl  ; *dst = src | *dst; // this is the actual interlocked-or op
    }
}

請注意,此函數與_InterlockedOr8的不同之處在於它不返回* dst的原始值。 如果需要返回值,則實現會變得更加復雜。 我快速瀏覽了SyncSys的源代碼。 需要該功能的兩個地方不需要返回值。 因此,您要做的就是將上述代碼轉換為使用內聯匯編的gcc樣式。

更新

這是一個在OR操作之前正確返回目標地址內原始值的版本。 它可能需要進行一些代碼審查。

char MyInterlockedOr8(char* dst, char src)
{
    char result = 0;
    const size_t ptr_size = sizeof(dst);

    _asm
    {
        mov esi, dst    ; esi = dst
        mov cl, src     ; cl = src // keep "src" cached in a register
        mov al, [esi]   ; al = *dst
start:
        mov bl, cl      ; bl = src
        or bl, al       ; bl = src | *dst

        lock cmpxchg [esi], bl;   // if (*dst == eax) { *dst=bl ;} else {al = *dst};
        jne start

        mov result, al  ; result = al
    }

    return result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM