InterlockedOr8 на gcc MinGW

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

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

0

Решение

_InterlockedOr8 — это встроенная функция компилятора, уникальная для компилятора Microsoft. Это означает, что компилятор автоматически внедряет реализацию в код, а не связывается с библиотекой. <intr.h> файл заголовка, распространяемый вместе с Visual Studio, отдельно от Windows SDK

Если вы не можете переключиться на Visual Studio (скачать бесплатно, кстати), тогда вы можете определить свою собственную заменяющую версию этой функции:

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;
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]