enable use of ACPI without the mahaf driver (required for NUMA SRAT access at work). also use new DLL import macros.

This was SVN commit r7718.
This commit is contained in:
janwas 2010-07-08 10:33:38 +00:00
parent 8c1bd05ab9
commit b2c4a8597e
11 changed files with 244 additions and 228 deletions

View File

@ -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<typename T>
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<typename T>
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<u32> 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<u8> 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

View File

@ -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

View File

@ -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<u32> 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<u32> tableIDs(DivideRoundUp((size_t)bufSize, sizeof(DWORD)));
const UINT ret = pEnumSystemFirmwareTables(provider, &tableIDs[0], bufSize);
debug_assert(ret == bufSize);
return tableIDs;
}
std::vector<u8> 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<u8> table(bufSize);
const UINT ret = pGetSystemFirmwareTable(provider, id, &table[0], bufSize);
debug_assert(ret == bufSize);
return table;
}

View File

@ -0,0 +1,8 @@
#ifndef INCLUDED_WACPI
#define INCLUDED_WACPI
extern std::vector<u32> wacpi_TableIDs();
extern std::vector<u8> wacpi_GetTable(u32 id);
#endif // #ifndef INCLUDED_WACPI

View File

@ -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 <omp.h>
@ -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

View File

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

View File

@ -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)

View File

@ -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();
}

View File

@ -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

View File

@ -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();

View File

@ -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);