[英]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.