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. WUTIL_FUNC(pGetNumaAvailableMemoryNode, BOOL, (UCHAR, PULONGLONG)); WUTIL_IMPORT_KERNEL32(GetNumaAvailableMemoryNode, pGetNumaAvailableMemoryNode); if(pGetNumaAvailableMemoryNode) { const UCHAR nodeNumber = NodeNumberFromNode(node); ULONGLONG availableBytes; const BOOL ok = pGetNumaAvailableMemoryNode(nodeNumber, &availableBytes); WARN_IF_FALSE(ok); const size_t availableMiB = size_t(availableBytes / MiB); return availableMiB; } // NUMA not supported - return available system memory else return os_cpu_MemoryAvailable(); }
void WriteSystemInfo() { TIMER(L"write_sys_info"); // get_cpu_info and gfx_detect already called during init - see call site snd_detect(); struct utsname un; uname(&un); OsPath pathname = psLogDir()/"system_info.txt"; FILE* f = sys_OpenFile(pathname, "w"); if(!f) return; // current timestamp (redundant WRT OS timestamp, but that is not // visible when people are posting this file's contents online) { wchar_t timestampBuf[100] = {'\0'}; time_t seconds; time(&seconds); struct tm* t = gmtime(&seconds); const size_t charsWritten = wcsftime(timestampBuf, ARRAY_SIZE(timestampBuf), L"(generated %Y-%m-%d %H:%M:%S UTC)", t); ENSURE(charsWritten != 0); fprintf(f, "%ls\n\n", timestampBuf); } // OS fprintf(f, "OS : %s %s (%s)\n", un.sysname, un.release, un.version); // CPU fprintf(f, "CPU : %s, %s", un.machine, cpu_IdentifierString()); #if ARCH_X86_X64 fprintf(f, " (%dx%dx%d)", (int)topology::NumPackages(), (int)topology::CoresPerPackage(), (int)topology::LogicalPerCore()); #endif double cpuClock = os_cpu_ClockFrequency(); // query OS (may fail) #if ARCH_X86_X64 if(cpuClock <= 0.0) cpuClock = x86_x64::ClockFrequency(); // measure (takes a few ms) #endif if(cpuClock > 0.0) { if(cpuClock < 1e9) fprintf(f, ", %.2f MHz\n", cpuClock*1e-6); else fprintf(f, ", %.2f GHz\n", cpuClock*1e-9); } else fprintf(f, "\n"); // memory fprintf(f, "Memory : %u MiB; %u MiB free\n", (unsigned)os_cpu_MemorySize(), (unsigned)os_cpu_MemoryAvailable()); // graphics const std::wstring cardName = gfx::CardName(); const std::wstring driverInfo = gfx::DriverInfo(); fprintf(f, "Graphics Card : %ls\n", cardName.c_str()); fprintf(f, "OpenGL Drivers : %s; %ls\n", glGetString(GL_VERSION), driverInfo.c_str()); fprintf(f, "Video Mode : %dx%d:%d\n", g_VideoMode.GetXRes(), g_VideoMode.GetYRes(), g_VideoMode.GetBPP()); // sound fprintf(f, "Sound Card : %ls\n", snd_card); fprintf(f, "Sound Drivers : %ls\n", snd_drv_ver); // OpenGL extensions (write them last, since it's a lot of text) const char* exts = ogl_ExtensionString(); if (!exts) exts = "{unknown}"; fprintf(f, "\nOpenGL Extensions: \n%s\n", SplitExts(exts).c_str()); // System Management BIOS (even more text than OpenGL extensions) std::string smbios = SMBIOS::StringizeStructures(SMBIOS::GetStructures()); fprintf(f, "\nSMBIOS: \n%s\n", smbios.c_str()); fclose(f); f = 0; }
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); }