diff --git a/source/lib/sysdep/acpi.cpp b/source/lib/sysdep/acpi.cpp index 4fd93d190d..633368fcb1 100644 --- a/source/lib/sysdep/acpi.cpp +++ b/source/lib/sysdep/acpi.cpp @@ -23,15 +23,39 @@ #include "precompiled.h" #include "lib/sysdep/acpi.h" -#include "lib/sysdep/os/win/mahaf.h" #include "lib/sysdep/cpu.h" #include "lib/module_init.h" +#define ENABLE_MAHAF 0 +#if ENABLE_MAHAF +# include "lib/sysdep/os/win/mahaf.h" +#else +# include "lib/sysdep/os/win/wacpi.h" +#endif + #pragma pack(1) typedef const volatile u8* PCV_u8; typedef const volatile AcpiTable* PCV_AcpiTable; + +//----------------------------------------------------------------------------- +// table + +static AcpiTable* AllocateTable(size_t size) +{ + debug_assert(size >= sizeof(AcpiTable)); + return (AcpiTable*)malloc(size); +} + + +template +static void DeallocateTable(const T* table) +{ + free((void*)table); +} + + // return 8-bit checksum of a buffer (should be 0) static u8 ComputeChecksum(PCV_u8 buf, size_t numBytes) { @@ -43,9 +67,49 @@ static u8 ComputeChecksum(PCV_u8 buf, size_t numBytes) } +static bool ValidateTable(const AcpiTable* table, const char* signature = 0) +{ + if(!table) + return false; + + // caller knowns the signature; make sure it matches + if(signature) + { + if(memcmp(table->signature, signature, 4) != 0) + return false; + } + // no specific signature is called for; just make sure it's 4 letters + else + { + for(size_t i = 0; i < 4; i++) + { + if(!isalpha(table->signature[i])) + return false; + } + } + + // must be at least as large as the common header + if(table->size < sizeof(AcpiTable)) + return false; + + // checksum of table must be 0 + // .. AMIBIOS OEMB table has an incorrect checksum (off-by-one), + // so don't complain about any OEM tables (ignored anyway). + const bool isOemTable = (memcmp(table->signature, "OEM", 3) == 0); + if(!isOemTable) + { + if(ComputeChecksum((PCV_u8)table, table->size) != 0) + return false; + } + + return true; +} + + +#if ENABLE_MAHAF + //----------------------------------------------------------------------------- // exception-safe transactional map/use/unmap -//----------------------------------------------------------------------------- // note: if the OS happens to unmap our physical memory, the Unsafe* // functions may crash. we catch this via SEH; on Unix, we'd need handlers @@ -57,7 +121,7 @@ static void* FAILED = (void*)(intptr_t)-1; typedef void* (*UnsafeFunction)(PCV_u8 mem, size_t numBytes, void* arg); -static inline void* CallWithSafetyBlanket(UnsafeFunction func, PCV_u8 mem, size_t numBytes, void* arg) +static void* CallWithSafetyBlanket(UnsafeFunction func, PCV_u8 mem, size_t numBytes, void* arg) { #if MSC_VERSION __try @@ -86,7 +150,6 @@ static void* TransactPhysicalMemory(uintptr_t physicalAddress, size_t numBytes, //----------------------------------------------------------------------------- // Root System Descriptor Pointer -//----------------------------------------------------------------------------- struct BiosDataArea { @@ -162,10 +225,9 @@ static bool RetrieveRsdp(RSDP& rsdp) //----------------------------------------------------------------------------- -// table retrieval -//----------------------------------------------------------------------------- +// copy tables from physical memory -static inline void* UnsafeAllocateCopyOfTable(PCV_u8 mem, size_t numBytes, void* arg) +static void* UnsafeAllocateAndCopyTable(PCV_u8 mem, size_t numBytes, void* arg) { debug_assert(numBytes >= sizeof(AcpiTable)); @@ -180,7 +242,7 @@ static inline void* UnsafeAllocateCopyOfTable(PCV_u8 mem, size_t numBytes, void* return 0; } - PCV_u8 copy = (PCV_u8)malloc(tableSize); + PCV_u8 copy = (PCV_u8)AllocateTable(tableSize); if(!copy) return FAILED; @@ -188,130 +250,116 @@ static inline void* UnsafeAllocateCopyOfTable(PCV_u8 mem, size_t numBytes, void* return (void*)copy; } -// caller is responsible for verifying the table is valid and using -// DeallocateTable to free it. -static const AcpiTable* AllocateCopyOfTable(uintptr_t physicalAddress) + +static const AcpiTable* AllocateAndCopyTable(uintptr_t physicalAddress) { // ACPI table sizes are not known until they've been mapped. since that // is slow, we don't always want to do it twice. the solution is to map // enough for a typical table; if that is too small, realloc and map again. static const size_t initialSize = 4*KiB; size_t actualSize = 0; - void* ret = TransactPhysicalMemory(physicalAddress, initialSize, UnsafeAllocateCopyOfTable, &actualSize); + void* ret = TransactPhysicalMemory(physicalAddress, initialSize, UnsafeAllocateAndCopyTable, &actualSize); // initialSize was too small; actualSize has been set if(ret == 0) - ret = TransactPhysicalMemory(physicalAddress, actualSize, UnsafeAllocateCopyOfTable); + ret = TransactPhysicalMemory(physicalAddress, actualSize, UnsafeAllocateAndCopyTable); // *either* of the above calls failed to allocate memory if(ret == FAILED) return 0; return (const AcpiTable*)ret; } +#endif // ENABLE_MAHAF -template -static void DeallocateTable(const T* table) + +static void AllocateAndCopyTables(const AcpiTable**& tables, size_t& numTables) { - free((void*)table); -} +#if ENABLE_MAHAF + if(mahaf_IsPhysicalMappingDangerous()) + return; + if(!mahaf_Init()) + return; - -static bool VerifyTable(const AcpiTable* table, const char* signature = 0) -{ - if(!table) - return false; - - // caller knowns the signature; make sure it matches - if(signature) - { - if(memcmp(table->signature, signature, 4) != 0) - return false; - } - // no specific signature is called for; just make sure it's 4 letters - else - { - for(size_t i = 0; i < 4; i++) - { - if(!isalpha(table->signature[i])) - return false; - } - } - - // must be at least as large as the common header - if(table->size < sizeof(AcpiTable)) - return false; - - // checksum of table must be 0 - // .. AMIBIOS OEMB table has an incorrect checksum (off-by-one), - // so don't complain about any OEM tables (ignored anyway). - const bool isOemTable = (memcmp(table->signature, "OEM", 3) == 0); - if(ComputeChecksum((PCV_u8)table, table->size) != 0 && !isOemTable) - return false; - - return true; -} - - -static const AcpiTable* GetTable(uintptr_t physicalAddress, const char* signature = 0) -{ - const AcpiTable* table = AllocateCopyOfTable(physicalAddress); - if(VerifyTable(table, signature)) - return table; - else - { - DeallocateTable(table); - return 0; - } -} - - -//----------------------------------------------------------------------------- -// table storage -//----------------------------------------------------------------------------- - -// Root System Descriptor Table -struct RSDT -{ - AcpiTable header; - u32 tables[1]; -}; - -// avoid std::map et al. because we may be called before _cinit -static const AcpiTable** tables; -static size_t numTables; - -static bool LatchAllTables() -{ RSDP rsdp; if(!RetrieveRsdp(rsdp)) - return false; - const RSDT* rsdt = (const RSDT*)GetTable(rsdp.rsdtPhysicalAddress, "RSDT"); - if(!rsdt) - return false; + return; + + // Root System Descriptor Table + struct RSDT + { + AcpiTable header; + u32 tableAddresses[1]; + }; + const RSDT* rsdt = (const RSDT*)AllocateAndCopyTable(rsdp.rsdtPhysicalAddress); + if(!ValidateTable(&rsdt->header, "RSDT")) + { + DeallocateTable(rsdt); + return; + } + + numTables = (rsdt->header.size - sizeof(AcpiTable)) / sizeof(rsdt->tableAddresses[0]); + debug_assert(numTables != 0); - numTables = (rsdt->header.size - sizeof(AcpiTable)) / sizeof(rsdt->tables[0]); - debug_assert(numTables > 0); tables = new const AcpiTable*[numTables]; for(size_t i = 0; i < numTables; i++) - tables[i] = GetTable(rsdt->tables[i]); + tables[i] = AllocateAndCopyTable(rsdt->tableAddresses[i]); DeallocateTable(rsdt); - return true; +#else + const std::vector tableIDs = wacpi_TableIDs(); + debug_assert(!tableIDs.empty()); + + numTables = tableIDs.size(); + tables = new const AcpiTable*[numTables]; + + for(size_t i = 0; i < numTables; i++) + { + std::vector table = wacpi_GetTable(tableIDs[i]); + tables[i] = AllocateTable(table.size()); + memcpy((void*)tables[i], &table[0], table.size()); + } +#endif + + // to prevent callers from choking on invalid tables, we + // zero out the corresponding tables[] entries. + for(size_t i = 0; i < numTables; i++) + { + if(!ValidateTable(tables[i])) + { + DeallocateTable(tables[i]); + tables[i] = 0; + } + } } -static void FreeAllTables() +//----------------------------------------------------------------------------- + +// note: avoid global std::map etc. because we may be called before _cinit +static const AcpiTable** tables; // tables == 0 <=> not initialized +static const AcpiTable* invalidTables; // tables == &invalidTables => init failed +static size_t numTables; + +void acpi_Shutdown() { if(tables) { for(size_t i = 0; i < numTables; i++) DeallocateTable(tables[i]); - delete[] tables; + SAFE_ARRAY_DELETE(tables); + numTables = 0; } + +#if ENABLE_MAHAF + mahaf_Shutdown(); +#endif } const AcpiTable* acpi_GetTable(const char* signature) { + if(cpu_CAS(&tables, (const AcpiTable**)0, &invalidTables)) + AllocateAndCopyTables(tables, numTables); + // (typically only a few tables, linear search is OK) for(size_t i = 0; i < numTables; i++) { @@ -322,44 +370,5 @@ const AcpiTable* acpi_GetTable(const char* signature) return table; } - return 0; + return 0; // no matching AND valid table found } - - -//----------------------------------------------------------------------------- - -#define initState acpiInitState -static ModuleInitState initState; - -bool acpi_Init() -{ - if(ModuleIsError(&initState)) - return false; - if(!ModuleShouldInitialize(&initState)) - return true; - - if(mahaf_IsPhysicalMappingDangerous()) - goto fail; - if(!mahaf_Init()) - goto fail; - - if(!LatchAllTables()) - goto fail; - - return true; - -fail: - ModuleSetError(&initState); - return false; -} - -void acpi_Shutdown() -{ - if(!ModuleShouldShutdown(&initState)) - return; - - FreeAllTables(); - - mahaf_Shutdown(); -} -#undef initState diff --git a/source/lib/sysdep/acpi.h b/source/lib/sysdep/acpi.h index 5a9d8d3311..e42f846c7a 100644 --- a/source/lib/sysdep/acpi.h +++ b/source/lib/sysdep/acpi.h @@ -64,9 +64,18 @@ struct AcpiGenericAddress #pragma pack(pop) -extern bool acpi_Init(); -extern void acpi_Shutdown(); +/** + * @param signature e.g. "RSDT" + * @return pointer to internal storage (valid until acpi_Shutdown()) + * + * note: the first call may be slow, e.g. if a kernel-mode driver is + * loaded. subsequent requests will be faster since tables are cached. + **/ +LIB_API const AcpiTable* acpi_GetTable(const char* signature); -extern const AcpiTable* acpi_GetTable(const char* signature); +/** + * invalidates all pointers returned by acpi_GetTable. + **/ +LIB_API void acpi_Shutdown(); #endif // #ifndef INCLUDED_ACPI diff --git a/source/lib/sysdep/os/win/wacpi.cpp b/source/lib/sysdep/os/win/wacpi.cpp new file mode 100644 index 0000000000..8296446ce9 --- /dev/null +++ b/source/lib/sysdep/os/win/wacpi.cpp @@ -0,0 +1,42 @@ +#include "precompiled.h" +#include "lib/sysdep/os/win/wacpi.h" + +#include "lib/byte_order.h" +#include "lib/sysdep/os/win/wutil.h" + + +static const DWORD provider = FOURCC_BE('A','C','P','I'); + +std::vector wacpi_TableIDs() +{ + WUTIL_FUNC(pEnumSystemFirmwareTables, UINT, (DWORD, PVOID, DWORD)); + WUTIL_IMPORT_KERNEL32(EnumSystemFirmwareTables, pEnumSystemFirmwareTables); + + const UINT bufSize = pEnumSystemFirmwareTables(provider, 0, 0); + debug_assert(bufSize != 0); + debug_assert(bufSize % sizeof(DWORD) == 0); + + std::vector tableIDs(DivideRoundUp((size_t)bufSize, sizeof(DWORD))); + + const UINT ret = pEnumSystemFirmwareTables(provider, &tableIDs[0], bufSize); + debug_assert(ret == bufSize); + + return tableIDs; +} + + +std::vector wacpi_GetTable(u32 id) +{ + WUTIL_FUNC(pGetSystemFirmwareTable, UINT, (DWORD, DWORD, PVOID, DWORD)); + WUTIL_IMPORT_KERNEL32(GetSystemFirmwareTable, pGetSystemFirmwareTable); + + const UINT bufSize = pGetSystemFirmwareTable(provider, id, 0, 0); + debug_assert(bufSize != 0); + + std::vector table(bufSize); + + const UINT ret = pGetSystemFirmwareTable(provider, id, &table[0], bufSize); + debug_assert(ret == bufSize); + + return table; +} diff --git a/source/lib/sysdep/os/win/wacpi.h b/source/lib/sysdep/os/win/wacpi.h new file mode 100644 index 0000000000..52209e4135 --- /dev/null +++ b/source/lib/sysdep/os/win/wacpi.h @@ -0,0 +1,8 @@ +#ifndef INCLUDED_WACPI +#define INCLUDED_WACPI + +extern std::vector wacpi_TableIDs(); + +extern std::vector wacpi_GetTable(u32 id); + +#endif // #ifndef INCLUDED_WACPI diff --git a/source/lib/sysdep/os/win/wcpu.cpp b/source/lib/sysdep/os/win/wcpu.cpp index e4d890d13f..d94a2d564b 100644 --- a/source/lib/sysdep/os/win/wcpu.cpp +++ b/source/lib/sysdep/os/win/wcpu.cpp @@ -25,11 +25,12 @@ */ #include "precompiled.h" +#include "lib/sysdep/os/win/wcpu.h" #include "lib/sysdep/os_cpu.h" -#include "lib/sysdep/os/win/win.h" #include "lib/bits.h" #include "lib/module_init.h" +#include "lib/sysdep/os/win/wutil.h" #ifdef _OPENMP # include @@ -130,9 +131,8 @@ size_t os_cpu_LargePageSize() if(largePageSize == ~(size_t)0) { - typedef SIZE_T (WINAPI *PGetLargePageMinimum)(); - const HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); - const PGetLargePageMinimum pGetLargePageMinimum = (PGetLargePageMinimum)GetProcAddress(hKernel32, "GetLargePageMinimum"); + WUTIL_FUNC(pGetLargePageMinimum, SIZE_T, (void)); + WUTIL_IMPORT_KERNEL32(GetLargePageMinimum, pGetLargePageMinimum); if(pGetLargePageMinimum) { largePageSize = pGetLargePageMinimum(); @@ -148,11 +148,11 @@ size_t os_cpu_LargePageSize() } -static void GetMemoryStatusEx(MEMORYSTATUSEX& mse) +static void GetMemoryStatus(MEMORYSTATUSEX& mse) { // note: we no longer bother dynamically importing GlobalMemoryStatusEx - - // it's available starting with Win2k and avoids overflow/wraparound - // on systems with >= 4 GB of memory. + // it's available on Win2k and above. this function safely handles + // systems with > 4 GB of memory. mse.dwLength = sizeof(mse); const BOOL ok = GlobalMemoryStatusEx(&mse); WARN_IF_FALSE(ok); @@ -165,7 +165,7 @@ size_t os_cpu_MemorySize() if(memorySizeMiB == 0) { MEMORYSTATUSEX mse; - GetMemoryStatusEx(mse); + GetMemoryStatus(mse); DWORDLONG memorySize = mse.ullTotalPhys; // Richter, "Programming Applications for Windows": the reported @@ -184,7 +184,7 @@ size_t os_cpu_MemorySize() size_t os_cpu_MemoryAvailable() { MEMORYSTATUSEX mse; - GetMemoryStatusEx(mse); + GetMemoryStatus(mse); const size_t memoryAvailableMiB = size_t(mse.ullAvailPhys / MiB); return memoryAvailableMiB; } @@ -233,21 +233,14 @@ uintptr_t wcpu_ProcessorMaskFromAffinity(DWORD_PTR processAffinity, DWORD_PTR af static const DWORD invalidProcessorNumber = (DWORD)-1; + + static DWORD CurrentProcessorNumber() { - typedef DWORD (WINAPI *PGetCurrentProcessorNumber)(); - static PGetCurrentProcessorNumber pGetCurrentProcessorNumber; - - static bool initialized; - if(!initialized) - { - initialized = true; - const HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); - // note: NtGetCurrentProcessorNumber and RtlGetCurrentProcessorNumber aren't - // implemented on WinXP SP2, so we can't use those either. - pGetCurrentProcessorNumber = (PGetCurrentProcessorNumber)GetProcAddress(hKernel32, "GetCurrentProcessorNumber"); - } - + // note: NtGetCurrentProcessorNumber and RtlGetCurrentProcessorNumber aren't + // implemented on WinXP SP2. + WUTIL_FUNC(pGetCurrentProcessorNumber, DWORD, (void)); + WUTIL_IMPORT_KERNEL32(GetCurrentProcessorNumber, pGetCurrentProcessorNumber); if(pGetCurrentProcessorNumber) return pGetCurrentProcessorNumber(); else diff --git a/source/lib/sysdep/os/win/wdbg_sym.cpp b/source/lib/sysdep/os/win/wdbg_sym.cpp index b547e4079b..355c79c640 100644 --- a/source/lib/sysdep/os/win/wdbg_sym.cpp +++ b/source/lib/sysdep/os/win/wdbg_sym.cpp @@ -42,14 +42,10 @@ # include "lib/sysdep/arch/ia32/ia32_asm.h" #endif #include "lib/external_libraries/dbghelp.h" -#include "lib/sysdep/os/win/winit.h" #include "lib/sysdep/os/win/wdbg.h" #include "lib/sysdep/os/win/wutil.h" -WINIT_REGISTER_CRITICAL_INIT(wdbg_sym_Init); - - //---------------------------------------------------------------------------- // dbghelp //---------------------------------------------------------------------------- @@ -64,6 +60,13 @@ static uintptr_t mod_base; // for StackWalk64; taken from PE header by wdbg_init. static WORD machine; +// note: RtlCaptureStackBackTrace (http://msinilo.pl/blog/?p=40) +// is likely to be much faster than StackWalk64 (especially relevant +// for debug_GetCaller), but wasn't known during development and +// remains undocumented. +static WUTIL_FUNC(pRtlCaptureContext, VOID, (PCONTEXT)); + + // call on-demand (allows handling exceptions raised before winit.cpp // init functions are called); no effect if already initialized. static LibError sym_init() @@ -77,6 +80,7 @@ static LibError sym_init() hProcess = GetCurrentProcess(); dbghelp_ImportFunctions(); + WUTIL_IMPORT_KERNEL32(RtlCaptureContext, pRtlCaptureContext); // set options // notes: @@ -299,14 +303,6 @@ static LibError ia32_walk_stack(_tagSTACKFRAME64* sf) #endif -// note: RtlCaptureStackBackTrace (http://msinilo.pl/blog/?p=40) -// is likely to be much faster than StackWalk64 (especially relevant -// for debug_GetCaller), but wasn't known during development and -// remains undocumented. - -typedef VOID (WINAPI *PRtlCaptureContext)(PCONTEXT); -static PRtlCaptureContext s_RtlCaptureContext; - LibError wdbg_sym_WalkStack(StackFrameCallback cb, uintptr_t cbData, const CONTEXT* pcontext, const wchar_t* lastFuncToSkip) { @@ -338,11 +334,11 @@ LibError wdbg_sym_WalkStack(StackFrameCallback cb, uintptr_t cbData, const CONTE #if ARCH_IA32 ia32_asm_GetCurrentContext(&context); #else - if(!s_RtlCaptureContext) + if(!pRtlCaptureContext) return ERR::NOT_SUPPORTED; // NOWARN memset(&context, 0, sizeof(context)); context.ContextFlags = CONTEXT_CONTROL|CONTEXT_INTEGER; - s_RtlCaptureContext(&context); + pRtlCaptureContext(&context); #endif } pcontext = &context; @@ -1884,14 +1880,3 @@ void wdbg_sym_WriteMinidump(EXCEPTION_POINTERS* exception_pointers) CloseHandle(hFile); } - - -//----------------------------------------------------------------------------- - -static LibError wdbg_sym_Init() -{ - HMODULE hKernel32Dll = GetModuleHandleW(L"kernel32.dll"); - s_RtlCaptureContext = (PRtlCaptureContext)GetProcAddress(hKernel32Dll, "RtlCaptureContext"); - - return INFO::OK; -} diff --git a/source/lib/sysdep/os/win/whrt/hpet.cpp b/source/lib/sysdep/os/win/whrt/hpet.cpp index 982b873a34..99779cac72 100644 --- a/source/lib/sysdep/os/win/whrt/hpet.cpp +++ b/source/lib/sysdep/os/win/whrt/hpet.cpp @@ -154,8 +154,6 @@ private: return ERR::FAIL; // NOWARN (happens on Win2k) if(!mahaf_Init()) return ERR::FAIL; // NOWARN (no Administrator privileges) - if(!acpi_Init()) - WARN_RETURN(ERR::FAIL); // shouldn't fail, since we've checked mahaf_IsPhysicalMappingDangerous const HpetDescriptionTable* hpet = (const HpetDescriptionTable*)acpi_GetTable("HPET"); if(!hpet) diff --git a/source/lib/sysdep/os/win/whrt/pmt.cpp b/source/lib/sysdep/os/win/whrt/pmt.cpp index 6fcfc52463..88165d7777 100644 --- a/source/lib/sysdep/os/win/whrt/pmt.cpp +++ b/source/lib/sysdep/os/win/whrt/pmt.cpp @@ -68,8 +68,6 @@ public: // mahaf is needed for port I/O. if(!mahaf_Init()) return ERR::FAIL; // NOWARN (no Administrator privileges) - if(!acpi_Init()) - return ERR::FAIL; // NOWARN (happens on Win2k; see mahaf_IsPhysicalMappingDangerous) // (note: it's called FADT, but the signature is "FACP") const FADT* fadt = (const FADT*)acpi_GetTable("FACP"); if(!fadt) @@ -81,7 +79,6 @@ public: void Shutdown() { - acpi_Shutdown(); mahaf_Shutdown(); } diff --git a/source/lib/sysdep/os/win/whrt/whrt.cpp b/source/lib/sysdep/os/win/whrt/whrt.cpp index 91edd4f362..edd0a1ec77 100644 --- a/source/lib/sysdep/os/win/whrt/whrt.cpp +++ b/source/lib/sysdep/os/win/whrt/whrt.cpp @@ -293,12 +293,6 @@ static inline void ShutdownUpdateThread() static LibError whrt_Init() { - // note: several counter implementations use acpi.cpp. if a counter is - // deemed unsafe, it is shut down, which releases the (possibly only) - // reference to the ACPI module. unloading and reloading it after trying - // each counter would be a waste of time, so we grab a reference here. - (void)acpi_Init(); - InitCounter(); // latch initial counter value so that timer starts at 0 diff --git a/source/lib/sysdep/os/win/wnuma.cpp b/source/lib/sysdep/os/win/wnuma.cpp index 964c8bdcab..c055f6cdd5 100644 --- a/source/lib/sysdep/os/win/wnuma.cpp +++ b/source/lib/sysdep/os/win/wnuma.cpp @@ -43,9 +43,8 @@ WINIT_REGISTER_EARLY_INIT(wnuma_Init); static size_t NumNodes() { - typedef BOOL (WINAPI *PGetNumaHighestNodeNumber)(PULONG highestNode); - const HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); - const PGetNumaHighestNodeNumber pGetNumaHighestNodeNumber = (PGetNumaHighestNodeNumber)GetProcAddress(hKernel32, "GetNumaHighestNodeNumber"); + WUTIL_FUNC(pGetNumaHighestNodeNumber, BOOL, (PULONG)); + WUTIL_IMPORT_KERNEL32(GetNumaHighestNodeNumber, pGetNumaHighestNodeNumber); if(pGetNumaHighestNodeNumber) { ULONG highestNode; @@ -62,9 +61,8 @@ static size_t NumNodes() static void FillNodesProcessorMask(uintptr_t* nodesProcessorMask) { - typedef BOOL (WINAPI *PGetNumaNodeProcessorMask)(UCHAR node, PULONGLONG affinity); - const HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); - const PGetNumaNodeProcessorMask pGetNumaNodeProcessorMask = (PGetNumaNodeProcessorMask)GetProcAddress(hKernel32, "GetNumaNodeProcessorMask"); + WUTIL_FUNC(pGetNumaNodeProcessorMask, BOOL, (UCHAR, PULONGLONG)); + WUTIL_IMPORT_KERNEL32(GetNumaNodeProcessorMask, pGetNumaNodeProcessorMask); if(pGetNumaNodeProcessorMask) { DWORD_PTR processAffinity, systemAffinity; @@ -155,14 +153,8 @@ size_t numa_AvailableMemory(size_t node) // note: it is said that GetNumaAvailableMemoryNode sometimes incorrectly // reports zero bytes. the actual cause may however be unexpected // RAM configuration, e.g. not all slots filled. - typedef BOOL (WINAPI *PGetNumaAvailableMemoryNode)(UCHAR node, PULONGLONG availableBytes); - static PGetNumaAvailableMemoryNode pGetNumaAvailableMemoryNode; - if(!pGetNumaAvailableMemoryNode) - { - const HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); - pGetNumaAvailableMemoryNode = (PGetNumaAvailableMemoryNode)GetProcAddress(hKernel32, "GetNumaAvailableMemoryNode"); - } - + WUTIL_FUNC(pGetNumaAvailableMemoryNode, BOOL, (UCHAR, PULONGLONG)); + WUTIL_IMPORT_KERNEL32(GetNumaAvailableMemoryNode, pGetNumaAvailableMemoryNode); if(pGetNumaAvailableMemoryNode) { ULONGLONG availableBytes; @@ -228,15 +220,9 @@ bool numa_IsMemoryInterleaved() static int isInterleaved = -1; if(isInterleaved == -1) { - if(acpi_Init()) - { - // the BIOS only generates an SRAT (System Resource Affinity Table) - // if node interleaving is disabled. - isInterleaved = acpi_GetTable("SRAT") == 0; - acpi_Shutdown(); - } - else - isInterleaved = 0; // can't tell + // the BIOS only generates an SRAT (System Resource Affinity Table) + // if node interleaving is disabled. + isInterleaved = acpi_GetTable("SRAT") == 0; } return isInterleaved != 0; @@ -329,15 +315,10 @@ void* numa_Allocate(size_t size, LargePageDisposition largePageDisposition, size static bool VerifyPages(void* mem, size_t size, size_t pageSize, size_t node) { - typedef BOOL (WINAPI *PQueryWorkingSetEx)(HANDLE hProcess, PVOID buffer, DWORD bufferSize); - static PQueryWorkingSetEx pQueryWorkingSetEx; + WUTIL_FUNC(pQueryWorkingSetEx, BOOL, (HANDLE, PVOID, DWORD)); + WUTIL_IMPORT_KERNEL32(QueryWorkingSetEx, pQueryWorkingSetEx); if(!pQueryWorkingSetEx) - { - const HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll"); - pQueryWorkingSetEx = (PQueryWorkingSetEx)GetProcAddress(hKernel32, "QueryWorkingSetEx"); - if(!pQueryWorkingSetEx) - return true; // can't do anything - } + return true; // can't do anything #if WINVER >= 0x600 size_t largePageSize = os_cpu_LargePageSize(); diff --git a/source/lib/sysdep/os/win/wsnd.cpp b/source/lib/sysdep/os/win/wsnd.cpp index 62e8f09689..6f3c5195aa 100644 --- a/source/lib/sysdep/os/win/wsnd.cpp +++ b/source/lib/sysdep/os/win/wsnd.cpp @@ -111,9 +111,9 @@ static const fs::wpath& GetDirectSoundDriverPath() { #define DS_OK 0 typedef BOOL (CALLBACK* LPDSENUMCALLBACKW)(void*, const wchar_t*, const wchar_t*, void*); - typedef HRESULT (WINAPI *PDirectSoundEnumerateW)(LPDSENUMCALLBACKW, void*); HMODULE hDsoundDll = LoadLibraryW(L"dsound.dll"); - PDirectSoundEnumerateW pDirectSoundEnumerateW = (PDirectSoundEnumerateW)GetProcAddress(hDsoundDll, "DirectSoundEnumerateW"); + WUTIL_FUNC(pDirectSoundEnumerateW, HRESULT, (LPDSENUMCALLBACKW, void*)); + WUTIL_IMPORT(hDsoundDll, DirectSoundEnumerateW, pDirectSoundEnumerateW); if(pDirectSoundEnumerateW) { HRESULT ret = pDirectSoundEnumerateW(DirectSoundCallback, (void*)0);