Skip to content

API-MS-WIN-CORE-SYNCH-L1-2-0.dll: WaitOnAddress\WakeByAddressAll\WakeByAddressSingle #6

@devobject

Description

@devobject

Привет.

Чтобы исправить проблему "May be 100% CPU load or freeze – «API-MS-WIN-CORE-SYNCH-L1-2-0.dll»" - нужно все таки корректно реализовать функции: WaitOnAddress, WakeByAddressAll, WakeByAddressSingle. Если не охота, ковыряться в недрах винды\вайна, то можно поступить проще и взять их аналоги из msvcp140_atomic_wait.dll

Вот рабочий C код:

#include <windows.h>
#pragma comment(lib, "libcpmt.lib") //static

// from xatomic_wait.h
typedef BOOL (__stdcall *_Atomic_wait_indirect_equal_callback_t) (const void* _Storage, void* _Comparand, size_t _Size, void* _Param);
int __stdcall __std_atomic_wait_indirect(const void* _Storage, void* _Comparand, size_t _Size, void* _Param, _Atomic_wait_indirect_equal_callback_t _Are_equal, unsigned long _Remaining_timeout);
void __stdcall __std_atomic_notify_one_indirect(const void* _Storage);
void __stdcall __std_atomic_notify_all_indirect(const void* _Storage);

BOOL __stdcall _Atomic_wait_are_equal_direct_fallback(const void* _Storage, void* _Comparand, size_t _Size, void* _Param) {
    switch (_Size) {
        case 1:
            return (*(const UCHAR *)  _Storage == *(const UCHAR *)_Comparand);
        case 2:
            return (*(const USHORT *) _Storage == *(const USHORT *)_Comparand);
        case 4:
            return (*(const ULONG *)  _Storage == *(const ULONG *)_Comparand);
        case 8:
            return (*(const ULONG64 *)_Storage == *(const ULONG64 *)_Comparand);
		default:
			return FALSE;
    }
}
	
BOOL WINAPI WaitOnAddress(const void *Address, PVOID CompareAddress, SIZE_T AddressSize, DWORD Milliseconds OPTIONAL) {
	return __std_atomic_wait_indirect(Address, CompareAddress, AddressSize, 0, _Atomic_wait_are_equal_direct_fallback, Milliseconds);
}

void WINAPI WakeByAddressAll(const void *addr) {
	__std_atomic_notify_all_indirect(addr);
}

void WINAPI WakeByAddressSingle(const void *addr) {
	__std_atomic_notify_one_indirect(addr);
}

Есть побочный эффект, с которым не разбрался, линкер зачем-то в пустую линкует функцию __CxxFrameHandler из VCRUNTIME140.dll.

PS: Еще можно сильно упростить себе задачу написания прокси функции.
Заменив их forward экспортом: в файле .def пишем:

LIBRARY ...
EXPORTS
SystemFunction036=advapi32.SystemFunction036
SystemFunction040=advapi32.SystemFunction040
SystemFunction041=advapi32.SystemFunction041
... и т.д

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions