gcc MinGW 上的 InterlockedOr8
Posted
技术标签:
【中文标题】gcc MinGW 上的 InterlockedOr8【英文标题】:InterlockedOr8 on gcc MinGW 【发布时间】:2014-01-05 04:50:25 【问题描述】:我对 CodeBlocks 12.11 随附的 MinGW 版本没有任何问题。但现在我尝试编译SyncSys。编译 enet 没问题,但是用 gcc/MinGW 编译 SyncSys 本身会带来错误,我不能使用函数 _InterlockedOr8 因为它没有声明。研究表明 _InterlockedOr8 是在 intrin.h 中定义的。 intrin.h 不包括在内,我在 MinGW/gcc 上搜索了它的等效项:x86intrin.h。但这仍然行不通。 InterlockedOr8 将是要调用的“真实”函数,但编译器也找不到此函数,尽管包含 winbase.h 和 windows.h。
在研究这个问题时,我无法从中吸取教训。我该如何解决这个问题?
【问题讨论】:
【参考方案1】:_InterlockedOr8 是 Microsoft 编译器独有的内在编译器函数 - 这意味着编译器会自动将实现内联到代码中,而不是与库链接。 <intr.h>
是随 Visual Studio 分发的头文件,独立于 Windows SDK。
如果你不能切换到 Visual Studio (free download, 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;
【讨论】:
我可以切换到 VS,我已经安装了 VS,但我不喜欢 IDE,如果我将 CodeBlocks 中的编译器设置为 MSVC10,我没有调试器,并且 cl.exe 总是抛出 D8003-Errors。我从来没有看过汇编程序,所以我不知道你的代码中发生了什么,所以如果你能添加一些提示/cmets 会很酷,感谢你的帮助。 我也看过代码,你说得对,它不关心返回值,但 _InterlockedAnd8 必须返回正确的值,因为它被使用了。我只是猜测 _InterlockedAnd8 的代码必须是: void _InterlockedAnd8( volatile char* dst, char src ) asm( "mov eax, dst;mov cl, src; lock and [eax], cl;" ); 我说的对吗? 或多或少。但是如果代码实际上使用了 InterlockedOr8 的返回值(这是交换前 dst 指向的值),生成的汇编代码会变得更多,并使用 interlocked-compare-exchange 调用。 我不能把 dst 的值复制到另一个变量中然后返回这个变量吗?诸如此类: char _InterlockedAnd8( volatile char dst, char src ) char ret( *dst ); asm("mov eax, dst;mov cl, src; lock and [eax], cl;");返回 ret; ? @JoshuaBehrens - 如您所见,如果 dst 的内容在您分配“ret”和“或”操作码之间被另一个线程更改,则返回值将不正确。 volatile 关键字最多只会使“dst”变量线程安全,而不是它所引用的地址。以上是关于gcc MinGW 上的 InterlockedOr8的主要内容,如果未能解决你的问题,请参考以下文章
如何将使用sysioctl.h的代码移植到MinGW gcc中?