// @return ratio between max/min time required to access one node's // memory from each processor. static double MeasureRelativeDistance() { const size_t size = 32*MiB; void* mem = vm::Allocate(size); ASSUME_ALIGNED(mem, pageSize); const uintptr_t previousProcessorMask = os_cpu_SetThreadAffinityMask(os_cpu_ProcessorMask()); double minTime = 1e10, maxTime = 0.0; for(size_t node = 0; node < numa_NumNodes(); node++) { const uintptr_t processorMask = numa_ProcessorMaskFromNode(node); os_cpu_SetThreadAffinityMask(processorMask); const double startTime = timer_Time(); memset(mem, 0, size); const double elapsedTime = timer_Time() - startTime; minTime = std::min(minTime, elapsedTime); maxTime = std::max(maxTime, elapsedTime); } (void)os_cpu_SetThreadAffinityMask(previousProcessorMask); vm::Free(mem, size); return maxTime / minTime; }
static bool IsMemoryInterleaved() { if(numa_NumNodes() == 1) return false; if(!acpi_GetTable("FACP")) // no ACPI tables available return false; // indeterminate, assume not interleaved if(acpi_GetTable("SRAT")) // present iff not interleaved return false; return true; }
static Status InitRelativeDistance() { // early-out for non-NUMA systems (saves some time) if(numa_NumNodes() == 1) { relativeDistance = 1.0; return INFO::OK; } // trust values reported by the BIOS, if available const SLIT* slit = (const SLIT*)acpi_GetTable("SLIT"); if(slit) relativeDistance = ReadRelativeDistanceFromSLIT(slit); else relativeDistance = MeasureRelativeDistance(); ENSURE(relativeDistance >= 1.0); ENSURE(relativeDistance <= 4.0); return INFO::OK; }
static UCHAR NodeNumberFromNode(size_t node) { (void)ModuleInit(&initState, InitTopology); ENSURE(node < numa_NumNodes()); return nodes[node].nodeNumber; }
void RunHardwareDetection() { TIMER(L"RunHardwareDetection"); ScriptInterface& scriptInterface = g_ScriptingHost.GetScriptInterface(); scriptInterface.RegisterFunction<void, bool, &SetDisableAudio>("SetDisableAudio"); scriptInterface.RegisterFunction<void, bool, &SetDisableS3TC>("SetDisableS3TC"); scriptInterface.RegisterFunction<void, bool, &SetDisableShadows>("SetDisableShadows"); scriptInterface.RegisterFunction<void, bool, &SetDisableShadowPCF>("SetDisableShadowPCF"); scriptInterface.RegisterFunction<void, bool, &SetDisableAllWater>("SetDisableAllWater"); scriptInterface.RegisterFunction<void, bool, &SetDisableFancyWater>("SetDisableFancyWater"); scriptInterface.RegisterFunction<void, bool, &SetDisableFBOWater>("SetDisableFBOWater"); scriptInterface.RegisterFunction<void, std::string, &SetRenderPath>("SetRenderPath"); // Load the detection script: const wchar_t* scriptName = L"hwdetect/hwdetect.js"; CVFSFile file; if (file.Load(g_VFS, scriptName) != PSRETURN_OK) { LOGERROR(L"Failed to load hardware detection script"); return; } std::string code = file.DecodeUTF8(); // assume it's UTF-8 scriptInterface.LoadScript(scriptName, code); // Collect all the settings we'll pass to the script: // (We'll use this same data for the opt-in online reporting system, so it // includes some fields that aren't directly useful for the hwdetect script) CScriptValRooted settings; scriptInterface.Eval("({})", settings); scriptInterface.SetProperty(settings.get(), "os_unix", OS_UNIX); scriptInterface.SetProperty(settings.get(), "os_bsd", OS_BSD); scriptInterface.SetProperty(settings.get(), "os_linux", OS_LINUX); scriptInterface.SetProperty(settings.get(), "os_android", OS_ANDROID); scriptInterface.SetProperty(settings.get(), "os_macosx", OS_MACOSX); scriptInterface.SetProperty(settings.get(), "os_win", OS_WIN); scriptInterface.SetProperty(settings.get(), "arch_ia32", ARCH_IA32); scriptInterface.SetProperty(settings.get(), "arch_amd64", ARCH_AMD64); scriptInterface.SetProperty(settings.get(), "arch_arm", ARCH_ARM); #ifdef NDEBUG scriptInterface.SetProperty(settings.get(), "build_debug", 0); #else scriptInterface.SetProperty(settings.get(), "build_debug", 1); #endif scriptInterface.SetProperty(settings.get(), "build_opengles", CONFIG2_GLES); scriptInterface.SetProperty(settings.get(), "build_datetime", std::string(__DATE__ " " __TIME__)); scriptInterface.SetProperty(settings.get(), "build_revision", std::wstring(svn_revision)); scriptInterface.SetProperty(settings.get(), "build_msc", (int)MSC_VERSION); scriptInterface.SetProperty(settings.get(), "build_icc", (int)ICC_VERSION); scriptInterface.SetProperty(settings.get(), "build_gcc", (int)GCC_VERSION); scriptInterface.SetProperty(settings.get(), "build_clang", (int)CLANG_VERSION); scriptInterface.SetProperty(settings.get(), "gfx_card", gfx::CardName()); scriptInterface.SetProperty(settings.get(), "gfx_drv_ver", gfx::DriverInfo()); scriptInterface.SetProperty(settings.get(), "snd_card", std::wstring(snd_card)); scriptInterface.SetProperty(settings.get(), "snd_drv_ver", std::wstring(snd_drv_ver)); ReportGLLimits(scriptInterface, settings); scriptInterface.SetProperty(settings.get(), "video_xres", g_VideoMode.GetXRes()); scriptInterface.SetProperty(settings.get(), "video_yres", g_VideoMode.GetYRes()); scriptInterface.SetProperty(settings.get(), "video_bpp", g_VideoMode.GetBPP()); scriptInterface.SetProperty(settings.get(), "video_desktop_xres", g_VideoMode.GetDesktopXRes()); scriptInterface.SetProperty(settings.get(), "video_desktop_yres", g_VideoMode.GetDesktopYRes()); scriptInterface.SetProperty(settings.get(), "video_desktop_bpp", g_VideoMode.GetDesktopBPP()); scriptInterface.SetProperty(settings.get(), "video_desktop_freq", g_VideoMode.GetDesktopFreq()); struct utsname un; uname(&un); scriptInterface.SetProperty(settings.get(), "uname_sysname", std::string(un.sysname)); scriptInterface.SetProperty(settings.get(), "uname_release", std::string(un.release)); scriptInterface.SetProperty(settings.get(), "uname_version", std::string(un.version)); scriptInterface.SetProperty(settings.get(), "uname_machine", std::string(un.machine)); #if OS_LINUX { std::ifstream ifs("/etc/lsb-release"); if (ifs.good()) { std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); scriptInterface.SetProperty(settings.get(), "linux_release", str); } } #endif scriptInterface.SetProperty(settings.get(), "cpu_identifier", std::string(cpu_IdentifierString())); scriptInterface.SetProperty(settings.get(), "cpu_frequency", os_cpu_ClockFrequency()); scriptInterface.SetProperty(settings.get(), "cpu_pagesize", (u32)os_cpu_PageSize()); scriptInterface.SetProperty(settings.get(), "cpu_largepagesize", (u32)os_cpu_LargePageSize()); scriptInterface.SetProperty(settings.get(), "cpu_numprocs", (u32)os_cpu_NumProcessors()); #if ARCH_X86_X64 scriptInterface.SetProperty(settings.get(), "cpu_numpackages", (u32)topology::NumPackages()); scriptInterface.SetProperty(settings.get(), "cpu_coresperpackage", (u32)topology::CoresPerPackage()); scriptInterface.SetProperty(settings.get(), "cpu_logicalpercore", (u32)topology::LogicalPerCore()); scriptInterface.SetProperty(settings.get(), "cpu_numcaches", (u32)topology::NumCaches()); #endif scriptInterface.SetProperty(settings.get(), "numa_numnodes", (u32)numa_NumNodes()); scriptInterface.SetProperty(settings.get(), "numa_factor", numa_Factor()); scriptInterface.SetProperty(settings.get(), "numa_interleaved", numa_IsMemoryInterleaved()); scriptInterface.SetProperty(settings.get(), "ram_total", (u32)os_cpu_MemorySize()); scriptInterface.SetProperty(settings.get(), "ram_total_os", (u32)os_cpu_QueryMemorySize()); scriptInterface.SetProperty(settings.get(), "ram_free", (u32)os_cpu_MemoryAvailable()); #if ARCH_X86_X64 scriptInterface.SetProperty(settings.get(), "x86_frequency", x86_x64::ClockFrequency()); scriptInterface.SetProperty(settings.get(), "x86_vendor", (u32)x86_x64::Vendor()); scriptInterface.SetProperty(settings.get(), "x86_model", (u32)x86_x64::Model()); scriptInterface.SetProperty(settings.get(), "x86_family", (u32)x86_x64::Family()); u32 caps0, caps1, caps2, caps3; x86_x64::GetCapBits(&caps0, &caps1, &caps2, &caps3); scriptInterface.SetProperty(settings.get(), "x86_caps[0]", caps0); scriptInterface.SetProperty(settings.get(), "x86_caps[1]", caps1); scriptInterface.SetProperty(settings.get(), "x86_caps[2]", caps2); scriptInterface.SetProperty(settings.get(), "x86_caps[3]", caps3); scriptInterface.SetProperty(settings.get(), "x86_icaches", ConvertCaches(scriptInterface, x86_x64::L1I)); scriptInterface.SetProperty(settings.get(), "x86_dcaches", ConvertCaches(scriptInterface, x86_x64::L1D)); scriptInterface.SetProperty(settings.get(), "x86_tlbs", ConvertTLBs(scriptInterface)); #endif scriptInterface.SetProperty(settings.get(), "timer_resolution", timer_Resolution()); // Send the same data to the reporting system g_UserReporter.SubmitReport("hwdetect", 11, scriptInterface.StringifyJSON(settings.get(), false)); // Run the detection script: scriptInterface.CallFunctionVoid(scriptInterface.GetGlobalObject(), "RunHardwareDetection", settings); }