简体   繁体   English

在gcc MinGW上互锁Or8

[英]InterlockedOr8 on gcc MinGW

I had no problems with the shipped version of MinGW that comes with CodeBlocks 12.11. 我对CodeBlocks 12.11随附的MinGW的出厂版本没有任何问题。 But now I tried to compile SyncSys . 但是现在我尝试编译SyncSys Compiling enet was no problem but compiling SyncSys itself with gcc/MinGW brings the errors, that I can't use the function _InterlockedOr8 because it is not declared. 编译enet没问题,但是用gcc / MinGW编译SyncSys本身会带来错误,我不能使用函数_InterlockedOr8,因为它没有声明。 Research lead to the fact that _InterlockedOr8 is defined in intrin.h. 研究得出的事实是,_interlockedOr8在intrin.h中定义。 intrin.h is not included and I searched for the equivalent for it on MinGW/gcc: x86intrin.h. 不包括intrin.h,我在MinGW / gcc上搜索了它的等效项:x86intrin.h。 But this still does not work. 但这仍然行不通。 InterlockedOr8 would be the "real" function to call but this is could not be found either by the compiler although winbase.h and windows.h are included. InterlockedOr8将是要调用的“实际”函数,但是尽管包含了winbase.h和windows.h,但编译器也找不到该函数。

While researching this problem there where very few hits I could not learn from. 在研究这个问题的时候,很少有我无法学习的命中。 How can I fix this? 我怎样才能解决这个问题?

_InterlockedOr8 is an intrinsic compiler function unique to the Microsoft compiler - meaning that the compiler automatically inlines an implementation into the code instead of linking with a library. _InterlockedOr8是Microsoft编译器独有的固有编译器功能-意味着编译器会自动将实现内联到代码中,而不是与库链接。 <intr.h> is a header file distributed with Visual Studio, separate from the Windows SDK. <intr.h>是与Visual Studio一起分发的头文件,与Windows SDK分开。

If you can't switch to Visual Studio ( free download, btw ), then you could define your own replacement version of this function: 如果您无法切换到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
    }
}

Notice that this function differs from _InterlockedOr8 in the fact that it doesn't return the original value of *dst. 请注意,此函数与_InterlockedOr8的不同之处在于它不返回* dst的原始值。 The implementation gets a more complicated if you need the return value. 如果需要返回值,则实现会变得更加复杂。 I took a quick look at SyncSys source. 我快速浏览了SyncSys的源代码。 The two places that need that function don't need the return value. 需要该功能的两个地方不需要返回值。 So all you have to do is convert the above code to use the gcc style of inline assembly. 因此,您要做的就是将上述代码转换为使用内联汇编的gcc样式。

Update 更新

Here's a version that correctly returns the original value within the destination address before the OR operation. 这是一个在OR操作之前正确返回目标地址内原始值的版本。 It could probably use a little code review scrutiny... 它可能需要进行一些代码审查。

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