InterlockedOr8 на gcc MinGW

0

У меня не было проблем с поставляемой версией MinGW, которая поставляется с CodeBlocks 12.11. Но теперь я попытался скомпилировать SyncSys. Компиляция enet не была проблемой, но компиляция самой SyncSys с gcc/MinGW приносит ошибки, что я не могу использовать функцию _InterlockedOr8, потому что она не объявлена. Исследования приводят к тому, что _InterlockedOr8 определяется в intrin.h. intrin.h не входит, и я искал эквивалент для него на MinGW/gcc: x86intrin.h. Но это все еще не работает. InterlockedOr8 будет "реальной" функцией для вызова, но это не может быть найдено ни компилятором, хотя включены winbase.h и windows.h.

Изучая эту проблему, там, где очень мало хитов, от которых я не мог учиться. Как я могу это исправить?

Теги:
gcc
mingw
interlocked

1 ответ

1
Лучший ответ

_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-стиль встроенной сборки.

Обновить

Здесь версия, которая вернет исходное значение в целевом адресе перед операцией ИЛИ. Вероятно, он может использовать небольшой обзор проверки кода...

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;
}
  • 0
    Я мог бы переключиться на VS, у меня уже установлена VS, но мне не нравится IDE, и если я устанавливаю компилятор в CodeBlocks на MSVC10, у меня нет отладчика, и cl.exe всегда выдает ошибки D8003. Я никогда не смотрел на ассемблер, поэтому понятия не имею, что происходит в вашем коде, поэтому было бы здорово, если бы вы могли добавить несколько подсказок / комментариев и спасибо за вашу помощь.
  • 0
    Я также взглянул на код, вы правы, что он не заботится о возвращаемом значении, но _InterlockedAnd8 должен возвращать правильное значение, потому что оно используется. Я только догадался, что код для _InterlockedAnd8 должен быть: void _InterlockedAnd8 (volatile char * dst, char src) {asm ("mov eax, dst; mov cl, src; lock и [eax], cl;"); } Я прав?
Показать ещё 11 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню