初始化内容

This commit is contained in:
2026-09-16 14:07:40 +08:00
parent 6934b390bf
commit 4f643c1e7c
18350 changed files with 6088489 additions and 305 deletions
@@ -0,0 +1,41 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#include "infoware/cpu.hpp"
#include <cstring>
#include <sys/utsname.h>
// https://github.com/karelzak/util-linux/blob/master/sys-utils/lscpu.c
iware::cpu::architecture_t iware::cpu::architecture() noexcept {
utsname buf;
if(uname(&buf) == -1)
return iware::cpu::architecture_t::unknown;
if(!strcmp(buf.machine, "x86_64"))
return iware::cpu::architecture_t::x64;
else if(strstr(buf.machine, "arm") == buf.machine)
return iware::cpu::architecture_t::arm;
else if(!strcmp(buf.machine, "ia64") || !strcmp(buf.machine, "IA64"))
return iware::cpu::architecture_t::itanium;
else if(!strcmp(buf.machine, "i686"))
return iware::cpu::architecture_t::x86;
else
return iware::cpu::architecture_t::unknown;
}
#endif
@@ -0,0 +1,41 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/cpu.hpp"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724958(v=vs.85).aspx
iware::cpu::architecture_t iware::cpu::architecture() noexcept {
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
switch(sysinfo.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_AMD64:
return iware::cpu::architecture_t::x64;
case PROCESSOR_ARCHITECTURE_ARM:
return iware::cpu::architecture_t::arm;
case PROCESSOR_ARCHITECTURE_IA64:
return iware::cpu::architecture_t::itanium;
case PROCESSOR_ARCHITECTURE_INTEL:
return iware::cpu::architecture_t::x86;
default:
return iware::cpu::architecture_t::unknown;
}
}
#endif
+25
View File
@@ -0,0 +1,25 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#include "infoware/cpu.hpp"
#include <cstdint>
iware::cpu::endianness_t iware::cpu::endianness() noexcept {
const std::uint16_t test = 0xFF00;
const auto result = *static_cast<const std::uint8_t*>(static_cast<const void*>(&test));
if(result == 0xFF)
return iware::cpu::endianness_t::big;
else
return iware::cpu::endianness_t::little;
}
+33
View File
@@ -0,0 +1,33 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef __APPLE__
#include "infoware/cpu.hpp"
#include "infoware/detail/sysctl.hpp"
std::uint64_t iware::cpu::frequency() noexcept {
const auto ctl_data = iware::detail::sysctl("hw.cpufrequency");
if(ctl_data.empty())
return 0;
const auto data = iware::detail::deconstruct_sysctl_int(ctl_data);
if(!data.first)
return 0;
return data.second;
}
#endif
@@ -0,0 +1,39 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#include "infoware/cpu.hpp"
#include <fstream>
#include <string>
std::uint64_t iware::cpu::frequency() noexcept {
std::ifstream cpuinfo("/proc/cpuinfo");
if(!cpuinfo.is_open() || !cpuinfo)
return 0;
for(std::string line; std::getline(cpuinfo, line);)
if(line.find("cpu MHz") == 0) {
const auto colon_id = line.find_first_of(':');
return static_cast<std::uint64_t>(std::strtod(line.c_str() + colon_id + 1, nullptr) * 1'000'000);
}
return 0;
}
#endif
#endif
+39
View File
@@ -0,0 +1,39 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/cpu.hpp"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
std::uint64_t iware::cpu::frequency() noexcept {
HKEY hkey;
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, R"(HARDWARE\DESCRIPTION\System\CentralProcessor\0)", 0, KEY_READ, &hkey)) {
// Fallback
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return freq.QuadPart * 1'000;
}
DWORD freq_mhz;
DWORD freq_mhz_len = sizeof(freq_mhz);
if(RegQueryValueExA(hkey, "~MHz", nullptr, nullptr, static_cast<LPBYTE>(static_cast<void*>(&freq_mhz)), &freq_mhz_len))
return {};
return freq_mhz * 1'000'000;
}
#endif
@@ -0,0 +1,136 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#include "infoware/cpu.hpp"
#include "infoware/detail/cpuid.hpp"
#if defined(_WIN32) && defined(_MSC_VER)
#include <intrin.h>
#define INFOWARE_XCR_XFEATURE_ENABLED_MASK _XCR_XFEATURE_ENABLED_MASK
#else
#define INFOWARE_XCR_XFEATURE_ENABLED_MASK 0
#endif // Is MSVC
static bool has_os_avx() {
bool avxsupport = false;
std::int32_t cpuinfo[4];
iware::detail::cpuid(cpuinfo, 1);
bool osusesxsave_restore = (cpuinfo[2] & (1 << 27)) != 0;
bool cpusupportsavx = (cpuinfo[2] & (1 << 28)) != 0;
if(osusesxsave_restore && cpusupportsavx) {
const auto xcrFeatureMask = iware::detail::xgetbv(INFOWARE_XCR_XFEATURE_ENABLED_MASK);
avxsupport = (xcrFeatureMask & 0x06) == 0x06;
}
return avxsupport;
}
static bool has_os_avx_512() {
if(!has_os_avx())
return false;
const auto xcrFeatureMask = iware::detail::xgetbv(INFOWARE_XCR_XFEATURE_ENABLED_MASK);
return (xcrFeatureMask & 0xE6) == 0xE6;
}
std::vector<iware::cpu::instruction_set_t> iware::cpu::supported_instruction_sets() {
std::int32_t info[4];
iware::detail::cpuid(info, 0);
const auto idinfo = info[0];
iware::detail::cpuid(info, 0x80000000);
const std::uint32_t extendedidinfo = info[0];
std::vector<iware::cpu::instruction_set_t> supported;
supported.reserve(64);
#define ADD_SET_IF(infoindex, bitindex, name) \
if((info[(infoindex)] & (1 << (bitindex))) != 0) \
supported.push_back(iware::cpu::instruction_set_t::name);
if(idinfo >= 0x00000001) {
iware::detail::cpuid(info, 0x00000001);
ADD_SET_IF(3, 22, mmx_extended);
ADD_SET_IF(3, 23, mmx);
ADD_SET_IF(3, 25, sse);
ADD_SET_IF(3, 26, sse2);
ADD_SET_IF(2, 0, sse3);
ADD_SET_IF(2, 9, ssse3);
ADD_SET_IF(2, 19, sse41);
ADD_SET_IF(2, 20, sse42);
ADD_SET_IF(2, 25, aes);
ADD_SET_IF(2, 28, fma3);
ADD_SET_IF(2, 12, rd_rand);
}
if(idinfo >= 0x00000007) {
iware::detail::cpuid(info, 0x00000007);
if(has_os_avx()) {
// Both must be present to have AVX
ADD_SET_IF(1, 5, avx2);
}
ADD_SET_IF(1, 4, hle);
ADD_SET_IF(1, 3, bmi1);
ADD_SET_IF(1, 8, bmi2);
ADD_SET_IF(1, 19, adx);
ADD_SET_IF(1, 14, mpx);
ADD_SET_IF(1, 29, sha);
if(has_os_avx_512()) {
supported.push_back(iware::cpu::instruction_set_t::avx_512);
ADD_SET_IF(1, 16, avx_512_f);
ADD_SET_IF(1, 28, avx_512_cd);
ADD_SET_IF(1, 26, avx_512_pf);
ADD_SET_IF(1, 27, avx_512_er);
ADD_SET_IF(1, 31, avx_512_vl);
ADD_SET_IF(1, 30, avx_512_bw);
ADD_SET_IF(1, 17, avx_512_dq);
ADD_SET_IF(1, 21, avx_512_ifma);
ADD_SET_IF(2, 1, avx_512_vbmi);
}
ADD_SET_IF(2, 0, prefetch_wt1);
}
if(extendedidinfo >= 0x80000001) {
iware::detail::cpuid(info, 0x80000001);
ADD_SET_IF(3, 29, x64);
ADD_SET_IF(3, 0, x87_fpu);
ADD_SET_IF(3, 30, s3d_now);
ADD_SET_IF(3, 31, s3d_now_extended);
ADD_SET_IF(3, 29, x64);
ADD_SET_IF(2, 5, bmi1);
ADD_SET_IF(2, 6, bmi2);
ADD_SET_IF(2, 16, adx);
ADD_SET_IF(2, 11, mpx);
}
#undef ADD_SET_IF
return supported;
}
@@ -0,0 +1,73 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef __APPLE__
#include "infoware/cpu.hpp"
#include "infoware/detail/sysctl.hpp"
#include <algorithm>
#include <cstring>
#include <utility>
static std::pair<const char* const*, const char* const*> instruction_set_to_names(iware::cpu::instruction_set_t set) {
static const char* mmx[] = {"MMX"};
static const char* threednow[] = {"3DNOW", "3DNOWEXT"};
static const char* sse[] = {"SSE"};
static const char* sse2[] = {"SSE2"};
static const char* sse3[] = {"SSSE3", "SSE3"};
static const char* avx[] = {"AVX"};
#define HANDLED_CASE(iset, variable) \
case iware::cpu::instruction_set_t::iset: \
return {variable, variable + (sizeof(variable) / sizeof(*variable))};
switch(set) {
HANDLED_CASE(s3d_now, threednow)
HANDLED_CASE(mmx, mmx)
HANDLED_CASE(sse, sse)
HANDLED_CASE(sse2, sse2)
HANDLED_CASE(sse3, sse3)
HANDLED_CASE(avx, avx)
default:
return {nullptr, nullptr};
}
#undef HANDLED_CASE
}
bool iware::cpu::instruction_set_supported(iware::cpu::instruction_set_t set) {
const auto ises = supported_instruction_sets();
if(std::find(ises.begin(), ises.end(), set) != ises.cend())
return true;
const auto set_names = instruction_set_to_names(set);
if(!set_names.first)
return false;
auto ctl_data = iware::detail::sysctl("machdep.cpu.features");
if(ctl_data.empty())
return 0;
for(auto cur_name = std::strtok(ctl_data.data(), " \t\n"); cur_name; cur_name = std::strtok(nullptr, " \t\n"))
if(std::any_of(set_names.first, set_names.second, [&](auto name) { return name == cur_name; }))
return true;
return false;
}
#endif
@@ -0,0 +1,82 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#include "infoware/cpu.hpp"
#include <algorithm>
#include <fstream>
#include <sstream>
#include <string>
#include <utility>
static std::pair<const char* const*, const char* const*> instruction_set_to_names(iware::cpu::instruction_set_t set) {
static const char* mmx[] = {"mmx"};
static const char* threednow[] = {"3dnow", "3dnowext"};
static const char* sse[] = {"sse"};
static const char* sse2[] = {"sse2"};
static const char* sse3[] = {"ssse3", "sse3"};
static const char* avx[] = {"avx"};
#define HANDLED_CASE(iset, variable) \
case iware::cpu::instruction_set_t::iset: \
return {variable, variable + (sizeof(variable) / sizeof(*variable))};
switch(set) {
HANDLED_CASE(s3d_now, threednow)
HANDLED_CASE(mmx, mmx)
HANDLED_CASE(sse, sse)
HANDLED_CASE(sse2, sse2)
HANDLED_CASE(sse3, sse3)
HANDLED_CASE(avx, avx)
default:
return {nullptr, nullptr};
}
#undef HANDLED_CASE
}
bool iware::cpu::instruction_set_supported(iware::cpu::instruction_set_t set) {
const auto ises = supported_instruction_sets();
if(std::find(ises.begin(), ises.end(), set) != ises.cend())
return true;
const auto set_names = instruction_set_to_names(set);
if(!set_names.first)
return false;
std::ifstream cpuinfo("/proc/cpuinfo");
if(!cpuinfo.is_open() || !cpuinfo)
return false;
for(std::string tmp; std::getline(cpuinfo, tmp);)
if(tmp.find("flags") == 0) {
const auto colon_id = tmp.find_first_of(':');
std::istringstream is(tmp.c_str() + colon_id + 1);
while(is >> tmp)
if(std::any_of(set_names.first, set_names.second, [&](auto name) { return tmp == name; }))
return true;
}
return false;
}
#endif
#endif
@@ -0,0 +1,57 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/cpu.hpp"
#include <algorithm>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
bool iware::cpu::instruction_set_supported(iware::cpu::instruction_set_t set) {
std::vector<iware::cpu::instruction_set_t> ises = supported_instruction_sets();
if(std::find(ises.cbegin(), ises.cend(), set) != ises.cend())
return true;
// TODO: is this necessary if we detect things with xgetbv and cpuid?
// That is, AVX usually needs to have both OS support alongside
DWORD feature;
switch(set) {
case iware::cpu::instruction_set_t::s3d_now:
feature = PF_3DNOW_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::mmx:
feature = PF_MMX_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::sse:
feature = PF_XMMI_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::sse2:
feature = PF_XMMI64_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::sse3:
feature = PF_SSE3_INSTRUCTIONS_AVAILABLE;
break;
case iware::cpu::instruction_set_t::avx:
feature = PF_XMMI64_INSTRUCTIONS_AVAILABLE;
break;
default:
return false;
}
return IsProcessorFeaturePresent(feature) != 0;
}
#endif
@@ -0,0 +1,84 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef __APPLE__
#include "infoware/cpu.hpp"
#include "infoware/detail/sysctl.hpp"
// https://github.com/ThePhD/infoware/issues/12#issuecomment-495291650
iware::cpu::quantities_t iware::cpu::quantities() {
iware::cpu::quantities_t ret{};
const auto ctl_thread_data = iware::detail::sysctl("machdep.cpu.thread_count");
if(!ctl_thread_data.empty()) {
const auto thread_data = iware::detail::deconstruct_sysctl_int(ctl_thread_data);
if(thread_data.first)
ret.logical = thread_data.second;
}
const auto ctl_core_data = iware::detail::sysctl("machdep.cpu.core_count");
if(!ctl_core_data.empty()) {
const auto core_data = iware::detail::deconstruct_sysctl_int(ctl_core_data);
if(core_data.first)
ret.physical = core_data.second;
}
const auto ctl_packages_data = iware::detail::sysctl("hw.packages");
if(!ctl_packages_data.empty()) {
const auto packages_data = iware::detail::deconstruct_sysctl_int(ctl_packages_data);
if(packages_data.first)
ret.packages = packages_data.second;
}
return ret;
}
// This is hell
//
// https://github.com/ThePhD/infoware/issues/12#issuecomment-495782115
//
// TODO: couldn't find a good way to get the associativity (default 0) or the type (default unified)
iware::cpu::cache_t iware::cpu::cache(unsigned int level) {
// Unspecified keys default to nullptr
static const char* size_keys[][3]{{}, {"hw.l1icachesize", "hw.l1dcachesize", "hw.l1cachesize"}, {"hw.l2cachesize"}, {"hw.l3cachesize"}};
iware::cpu::cache_t ret{};
const auto ctl_cachelinesize_data = iware::detail::sysctl("hw.cachelinesize");
if(!ctl_cachelinesize_data.empty()) {
const auto cachelinesize_data = iware::detail::deconstruct_sysctl_int(ctl_cachelinesize_data);
if(cachelinesize_data.first)
ret.line_size = cachelinesize_data.second;
}
if(level < sizeof(size_keys) / sizeof(*size_keys))
for(auto key : size_keys[level]) {
if(!key)
break;
const auto ctl_cachesize_data = iware::detail::sysctl(key);
if(!ctl_cachesize_data.empty()) {
const auto cachesize_data = iware::detail::deconstruct_sysctl_int(ctl_cachesize_data);
if(cachesize_data.first)
ret.size += cachesize_data.second;
}
}
return ret;
}
#endif
@@ -0,0 +1,110 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#include "infoware/cpu.hpp"
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <string>
#include <unistd.h>
#include <vector>
// http://stackoverflow.com/a/150971/2851815
// https://github.com/karelzak/util-linux/blob/25b7045e5db032df5354c0749cb454a20b89c522/sys-utils/lscpu.c#L1119
iware::cpu::quantities_t iware::cpu::quantities() {
iware::cpu::quantities_t ret{};
ret.logical = sysconf(_SC_NPROCESSORS_ONLN);
std::ifstream cpuinfo("/proc/cpuinfo");
if(!cpuinfo.is_open() || !cpuinfo)
return ret;
std::vector<unsigned int> package_ids;
for(std::string line; std::getline(cpuinfo, line);)
if(line.find("physical id") == 0) {
const auto physical_id = std::strtoul(line.c_str() + line.find_first_of("1234567890"), nullptr, 10);
if(std::find(package_ids.begin(), package_ids.end(), physical_id) == package_ids.end())
package_ids.emplace_back(physical_id);
}
ret.packages = package_ids.size();
ret.physical = ret.logical / ret.packages;
return ret;
}
// http://superuser.com/a/203481
iware::cpu::cache_t iware::cpu::cache(unsigned int level) {
std::string prefix("/sys/devices/system/cpu/cpu0/cache/index" + std::to_string(level) + '/');
iware::cpu::cache_t ret{};
{
std::ifstream size(prefix + "size");
if(size.is_open() && size) {
char suffix;
size >> ret.size >> suffix;
switch(suffix) {
case 'G':
ret.size *= 1024;
[[fallthrough]];
case 'M':
ret.size *= 1024;
[[fallthrough]];
case 'K':
ret.size *= 1024;
}
}
}
{
std::ifstream line_size(prefix + "coherency_line_size");
if(line_size.is_open() && line_size)
line_size >> ret.line_size;
}
{
std::ifstream associativity(prefix + "associativity");
if(associativity.is_open() && associativity) {
unsigned int tmp;
associativity >> tmp;
ret.associativity = tmp;
}
}
{
std::ifstream type(prefix + "type");
if(type.is_open() && type) {
std::string tmp;
type >> tmp;
if(tmp.find("nified") == 1)
ret.type = iware::cpu::cache_type_t::unified;
else if(tmp.find("nstruction") == 1)
ret.type = iware::cpu::cache_type_t::instruction;
else if(tmp.find("ata") == 1)
ret.type = iware::cpu::cache_type_t::data;
else if(tmp.find("race") == 1)
ret.type = iware::cpu::cache_type_t::trace;
}
}
return ret;
}
#endif
#endif
@@ -0,0 +1,85 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/cpu.hpp"
#include <bitset>
#include <vector>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> cpuinfo_buffer() {
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> buffer;
DWORD byte_count = 0;
GetLogicalProcessorInformation(nullptr, &byte_count);
buffer.resize(byte_count / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
GetLogicalProcessorInformation(buffer.data(), &byte_count);
return buffer;
}
// C++ified http://stackoverflow.com/a/28894219/2851815
iware::cpu::quantities_t iware::cpu::quantities() {
iware::cpu::quantities_t ret{};
for(auto&& info : cpuinfo_buffer())
switch(info.Relationship) {
case RelationProcessorCore:
++ret.physical;
// A hyperthreaded core supplies more than one logical processor.
ret.logical += static_cast<std::uint32_t>(std::bitset<sizeof(ULONG_PTR) * 8>(static_cast<std::uintptr_t>(info.ProcessorMask)).count());
break;
case RelationProcessorPackage:
// Logical processors share a physical package.
++ret.packages;
break;
default:
break;
}
return ret;
}
iware::cpu::cache_t iware::cpu::cache(unsigned int level) {
for(auto&& info : cpuinfo_buffer())
if(info.Relationship == RelationCache)
// Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache.
if(info.Cache.Level == level) {
iware::cpu::cache_type_t type{};
switch(info.Cache.Type) {
case CacheUnified:
type = iware::cpu::cache_type_t::unified;
break;
case CacheInstruction:
type = iware::cpu::cache_type_t::instruction;
break;
case CacheData:
type = iware::cpu::cache_type_t::data;
break;
case CacheTrace:
type = iware::cpu::cache_type_t::trace;
break;
}
return {info.Cache.Size, info.Cache.LineSize, info.Cache.Associativity, type};
}
return {};
}
#endif
+29
View File
@@ -0,0 +1,29 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#include <cstring>
#include <infoware/cpu.hpp>
#include <infoware/detail/cpuid.hpp>
std::string iware::cpu::vendor_id() {
std::int32_t info[4];
char name[13];
iware::detail::cpuid(info, 0);
std::memcpy(name + 0, &info[1], 4);
std::memcpy(name + 4, &info[3], 4);
std::memcpy(name + 8, &info[2], 4);
name[12] = '\0';
return name;
}
@@ -0,0 +1,42 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef __APPLE__
#include "infoware/cpu.hpp"
#include "infoware/detail/sysctl.hpp"
#include <string>
using namespace std::literals;
static std::string sysctl_value(const char* subkey) {
auto ctl_data = iware::detail::sysctl(("machdep.cpu."s + subkey).c_str());
if(ctl_data.empty())
return {};
else
return ctl_data.data();
}
std::string iware::cpu::vendor() {
return sysctl_value("vendor");
}
std::string iware::cpu::model_name() {
return sysctl_value("brand_string");
}
#endif
@@ -0,0 +1,49 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#include "infoware/cpu.hpp"
#include <fstream>
#include <string>
static std::string cpuinfo_value(const char* key) {
std::ifstream cpuinfo("/proc/cpuinfo");
if(!cpuinfo.is_open() || !cpuinfo)
return {};
for(std::string line; std::getline(cpuinfo, line);)
if(line.find(key) == 0) {
const auto colon_id = line.find_first_of(':');
const auto nonspace_id = line.find_first_not_of(" \t", colon_id + 1);
return line.c_str() + nonspace_id;
}
return {};
}
std::string iware::cpu::vendor() {
return cpuinfo_value("vendor");
}
std::string iware::cpu::model_name() {
return cpuinfo_value("model name");
}
#endif
#endif
@@ -0,0 +1,45 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/cpu.hpp"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
template <unsigned int IdentLen>
static std::string central_processor_subkey(const char* key) {
HKEY hkey;
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, R"(HARDWARE\DESCRIPTION\System\CentralProcessor\0)", 0, KEY_READ, &hkey))
return {};
char identifier[IdentLen];
DWORD identifier_len = sizeof(identifier);
LPBYTE lpdata = static_cast<LPBYTE>(static_cast<void*>(&identifier[0]));
if(RegQueryValueExA(hkey, key, nullptr, nullptr, lpdata, &identifier_len))
return {};
return identifier;
}
std::string iware::cpu::vendor() {
return central_processor_subkey<12 + 1>("VendorIdentifier");
}
std::string iware::cpu::model_name() {
return central_processor_subkey<64 + 1>("ProcessorNameString");
}
#endif
+32
View File
@@ -0,0 +1,32 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#include "infoware/detail/cpuid.hpp"
#include <cpuid.h>
#include <cstdint>
void iware::detail::cpuid(std::int32_t (&out)[4], std::int32_t x) {
__cpuid_count(x, 0, out[0], out[1], out[2], out[3]);
}
std::uint64_t iware::detail::xgetbv(std::uint32_t index) {
std::uint32_t eax, edx;
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
return ((uint64_t)edx << 32) | eax;
}
#endif
+30
View File
@@ -0,0 +1,30 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/detail/cpuid.hpp"
#include <cstdint>
#include <intrin.h>
void iware::detail::cpuid(std::int32_t (&out)[4], std::int32_t x) {
__cpuidex(out, x, 0);
}
std::uint64_t iware::detail::xgetbv(std::uint32_t x) {
return _xgetbv(x);
}
#endif
+19
View File
@@ -0,0 +1,19 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#include "infoware/detail/scope.hpp"
iware::detail::quickscope_wrapper::~quickscope_wrapper() {
if(func)
func();
}
+70
View File
@@ -0,0 +1,70 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef __APPLE__
#include "infoware/detail/sysctl.hpp"
#include <cstdint>
#include <cstring>
#include <sys/sysctl.h>
#include <sys/types.h>
// Requires data.size() >= sizeof(T)
template <class T>
static std::pair<bool, T> deconstruct_specific_int(const std::vector<char>& data) {
std::pair<bool, T> out{true, {}};
std::memcpy(&out.second, data.data(), sizeof(out.second));
return out;
}
#define SYSCTL_IMPL(fname, ...) \
std::size_t len{}; \
if(fname(__VA_ARGS__, nullptr, &len, nullptr, 0)) \
return {}; \
\
std::vector<char> ret(len); \
if(fname(__VA_ARGS__, ret.data(), &len, nullptr, 0)) \
return {}; \
\
return ret
std::vector<char> iware::detail::sysctl(const char* name) {
SYSCTL_IMPL(::sysctlbyname, name);
}
std::vector<char> iware::detail::sysctl(int mib_0, int mib_1) {
int name[2]{mib_0, mib_1};
SYSCTL_IMPL(::sysctl, name, sizeof(name) / sizeof(*name));
}
std::pair<bool, std::uint64_t> iware::detail::deconstruct_sysctl_int(const std::vector<char>& data) {
switch(data.size()) {
case sizeof(std::uint16_t):
return deconstruct_specific_int<std::uint16_t>(data);
case sizeof(std::uint32_t):
return deconstruct_specific_int<std::uint32_t>(data);
case sizeof(std::uint64_t):
return deconstruct_specific_int<std::uint64_t>(data);
default:
return {};
}
}
#endif
+32
View File
@@ -0,0 +1,32 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef __APPLE__
#include "infoware/detail/sysctl.hpp"
std::vector<char> iware::detail::sysctl(const char*) {
return {};
}
std::vector<char> iware::detail::sysctl(int, int) {
return {};
}
std::pair<bool, std::uint64_t> iware::detail::deconstruct_sysctl_int(const std::vector<char>&) {
return {};
}
#endif
+28
View File
@@ -0,0 +1,28 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#include "infoware/detail/winstring.hpp"
std::string iware::detail::narrowen_winstring(const wchar_t*) {
return {};
}
std::string iware::detail::narrowen_bstring(const wchar_t*) {
return {};
}
#endif
+50
View File
@@ -0,0 +1,50 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/detail/winstring.hpp"
#include <cwchar>
#include <string>
#define WIN32_LEAN_AND_MEAN
#include <wbemidl.h>
#include <windows.h>
static std::string transcode_from_wide(const wchar_t* wstr, std::size_t wstr_size) {
std::string ret;
// convert even embedded NUL
if(const auto len = WideCharToMultiByte(CP_UTF8, 0, wstr, static_cast<int>(wstr_size), NULL, 0, 0, 0)) {
ret.resize(len, '\0');
if(!WideCharToMultiByte(CP_UTF8, 0, wstr, static_cast<int>(wstr_size), &ret[0], len, 0, 0))
ret.clear();
}
return ret;
}
std::string iware::detail::narrowen_winstring(const wchar_t* wstr) {
if(!wstr)
return {};
return transcode_from_wide(wstr, std::wcslen(wstr));
}
std::string iware::detail::narrowen_bstring(const wchar_t* bstr) {
if(!bstr)
return {};
return transcode_from_wide(bstr, SysStringLen(const_cast<BSTR>(bstr)));
}
#endif
+74
View File
@@ -0,0 +1,74 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef INFOWARE_USE_D3D
#ifdef INFOWARE_USE_OPENCL
#include "infoware/gpu.hpp"
#include <cstdlib>
#include <cstring>
#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif
static iware::gpu::vendor_t parse_vendor(const char* name) {
if(!std::strcmp(name, "Intel(R) Corporation") || !std::strcmp(name, "Intel"))
return iware::gpu::vendor_t::intel;
else if(!std::strcmp(name, "Advanced Micro Devices, Inc.") || !std::strcmp(name, "AMD"))
return iware::gpu::vendor_t::amd;
else if(!std::strcmp(name, "NVIDIA Corporation"))
return iware::gpu::vendor_t::nvidia;
else if(!std::strcmp(name, "Apple"))
return iware::gpu::vendor_t::apple;
else
return iware::gpu::vendor_t::unknown;
}
/// See https://github.com/Oblomov/clinfo/blob/bfc628e74d4cdbf5c5adca169e8bae540fca92ef/src/clinfo.c#L2104 for other available props
std::vector<iware::gpu::device_properties_t> iware::gpu::device_properties() {
cl_platform_id platforms[64];
cl_uint platforms_used;
clGetPlatformIDs(sizeof(platforms) / sizeof(*platforms), platforms, &platforms_used);
std::vector<iware::gpu::device_properties_t> ret;
for(auto i = 0u; i < platforms_used; ++i) {
cl_device_id devices[64];
cl_uint devices_used;
clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_GPU, sizeof(devices) / sizeof(*devices), devices, &devices_used);
for(auto j = 0u; j < devices_used; ++j) {
char name[256];
char vendorname[256];
cl_ulong cache;
cl_ulong memory;
cl_uint max_frequency;
clGetDeviceInfo(devices[j], CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, sizeof(cache), &cache, nullptr);
clGetDeviceInfo(devices[j], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(max_frequency), &max_frequency, nullptr);
clGetDeviceInfo(devices[j], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(memory), &memory, nullptr);
clGetDeviceInfo(devices[j], CL_DEVICE_VENDOR, sizeof(vendorname) / sizeof(*vendorname), &vendorname, nullptr);
clGetDeviceInfo(devices[j], CL_DEVICE_NAME, sizeof(name) / sizeof(*name), &name, nullptr);
ret.push_back({parse_vendor(vendorname), name, memory, cache, max_frequency * 1'000'000});
}
}
return ret;
}
#endif
#endif
+65
View File
@@ -0,0 +1,65 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef INFOWARE_USE_D3D
#ifndef INFOWARE_USE_OPENCL
#ifdef INFOWARE_USE_OPENGL
// OpenGL is literaly hitler to initialise a windowless context for, so no game.
// Leave it for someone smarter than me :G
//
// Here is guidance I received from my Graphics Lord, Elim Garak, on Discord:
// [5:44 PM] 🕴: Elim, my lord, plz tell me the simplest way of setting up a dummy OGL ctx so I can glGetString()
// [5:46 PM] Elim | iscicadabannedyet.com: You know how to acquire your function pointers, rite? For WGL, EGL, XGL shit etc(edited)
// [5:46 PM] Borgleader: glLoadGen >>>>> acquiring pointers manually
// [5:46 PM] Elim | iscicadabannedyet.com: or that
// [5:46 PM] 🕴: not really, no
// [5:46 PM] Elim | iscicadabannedyet.com: You just want to know how to get the dummy?
// [5:46 PM] Elim | iscicadabannedyet.com: oh
// [5:47 PM] 🕴: from what I've read it's impl-def land
// [5:47 PM] 🕴: OGL land is so fucking alien to me
// [5:48 PM] 🕴: from what I read I assume you use like WGL or some shit to make a ctx which allows you to call OGL-proper functions
// [5:48 PM] Elim | iscicadabannedyet.com: Basically, on Windows it's as trivial as wglCreateContext(GetDC(your_window_handle)
// [5:48 PM] Elim | iscicadabannedyet.com: WGL is the glue between the Windows window system and OGL
// [5:49 PM] 🕴: Can I use a dummy window for that?
// [5:49 PM] Elim | iscicadabannedyet.com: yes
// [5:49 PM] 🕴: cool
// [5:49 PM] 🕴: And what on non-Windows?
// [5:50 PM] Elim | iscicadabannedyet.com: On OS X, one doesn't need to jump through such hoops because the Apple lords integrated OpenGL 4.1 and below inside
// of their system SDK
// [5:50 PM] Elim | iscicadabannedyet.com: As for lunix, it's EGL over there
// [5:50 PM] Elim | iscicadabannedyet.com: https://www.khronos.org/registry/egl/sdk/docs/man/html/eglCreateContext.xhtml
// [5:50 PM] 🕴: So I don't need to set up anything on OSX, it will work OOTB?(edited)
// [5:50 PM] Borgleader: except their drivers are shit so theres no point inusing it 😛
// [5:51 PM] Elim | iscicadabannedyet.com: It will work in the sense that you can get any core profile out of the box, yeah
// [5:51 PM] Elim | iscicadabannedyet.com: will it work practically as borgleader mentions
// [5:51 PM] Elim | iscicadabannedyet.com: hehehe, fun times ahead 😛(edited)
// [5:51 PM] 🕴: right, so a raw call on OSX, WGL wglCreateContext() w/dummy window on Windooze and EGL on Linux
// [5:52 PM] Elim | iscicadabannedyet.com: yeah, on lunix eglCreateContext attaches to the display
// [5:52 PM] 🕴: Elim is the greatest man of all time
// [5:52 PM] Elim | iscicadabannedyet.com: bby, write code and be quiet 😛
// [5:53 PM] Elim | iscicadabannedyet.com: but yeah, it's p retarded
#include "infoware/gpu.hpp"
#include <vector>
std::vector<iware::gpu::device_properties_t> iware::gpu::device_properties() {
return {};
}
#endif
#endif
#endif
+28
View File
@@ -0,0 +1,28 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef INFOWARE_USE_OPENGL
#ifndef INFOWARE_USE_OPENCL
#ifndef INFOWARE_USE_D3D
#include "infoware/gpu.hpp"
std::vector<iware::gpu::device_properties_t> iware::gpu::device_properties() {
return {};
}
#endif
#endif
#endif
+69
View File
@@ -0,0 +1,69 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef INFOWARE_USE_D3D
#include "infoware/detail/memory.hpp"
#include "infoware/detail/winstring.hpp"
#include "infoware/gpu.hpp"
#include "infoware/pci.hpp"
#include <d3d11.h>
#include <memory>
static iware::gpu::vendor_t vendor_from_name(const std::string& v) {
if(v.find("NVidia") != std::string::npos || v.find("NVIDIA") != std::string::npos)
return iware::gpu::vendor_t::nvidia;
else if(v.find("AMD") != std::string::npos || v.find("ATi") != std::string::npos || v.find("Advanced Micro Devices") != std::string::npos)
return iware::gpu::vendor_t::amd;
else if(v.find("Intel") != std::string::npos)
return iware::gpu::vendor_t::intel;
else if(v.find("Microsoft") != std::string::npos)
return iware::gpu::vendor_t::microsoft;
else if(v.find("Qualcomm") != std::string::npos)
return iware::gpu::vendor_t::qualcomm;
else
return iware::gpu::vendor_t::unknown;
}
std::vector<iware::gpu::device_properties_t> iware::gpu::device_properties() {
IDXGIFactory* factory_raw;
if(CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&factory_raw)) != S_OK)
return {};
std::unique_ptr<IDXGIFactory, iware::detail::release_deleter> factory(factory_raw);
std::vector<iware::gpu::device_properties_t> devices{};
for(auto aid = 0u;; ++aid) {
IDXGIAdapter* adapter_raw;
const auto adapter_result = factory->EnumAdapters(aid, &adapter_raw);
if(adapter_result != S_OK || adapter_result == DXGI_ERROR_NOT_FOUND)
break;
std::unique_ptr<IDXGIAdapter, iware::detail::release_deleter> adapter(adapter_raw);
DXGI_ADAPTER_DESC adapterdesc;
adapter->GetDesc(&adapterdesc);
const auto device = iware::pci::identify_device(adapterdesc.VendorId, adapterdesc.DeviceId);
std::string device_name = device.device_name ? device.device_name : iware::detail::narrowen_winstring(adapterdesc.Description);
devices.push_back({vendor_from_name(device.vendor_name), device_name, adapterdesc.DedicatedVideoMemory, adapterdesc.SharedSystemMemory,
// TODO: there's purportedly (https://en.wikipedia.org/wiki/Windows_Display_Driver_Model#WDDM_2.3)
// a Windows API for getting the max clock, but I haven't been able to find it or use it
0});
}
return devices;
}
#endif
+72
View File
@@ -0,0 +1,72 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#include "infoware/pci.hpp"
#include "infoware_generated/pci_data.hpp"
#include <algorithm>
#include <utility>
namespace {
struct id_pair_t {
std::uint64_t id;
std::size_t index;
};
struct pci_vendor_info_t {
std::uint64_t pci_id;
const char* name;
std::initializer_list<const std::uint64_t> device_indices;
};
struct pci_device_info_t {
std::uint64_t pci_id;
const char* name;
};
} // anonymous namespace
static const id_pair_t indices[]{INFOWARE_GENERATED_PCI_INDICES};
static const pci_vendor_info_t vendors[]{INFOWARE_GENERATED_PCI_VENDORS};
static const pci_device_info_t devices[]{INFOWARE_GENERATED_PCI_DEVICES};
static const pci_vendor_info_t* find_vendor(std::uint64_t vendor_id) noexcept {
const auto idx_itr = std::lower_bound(std::begin(indices), std::end(indices), vendor_id, [](auto&& left, auto right) { return left.id < right; });
if(idx_itr != std::end(indices) && idx_itr->id == vendor_id)
return &vendors[idx_itr->index];
else
return nullptr;
}
iware::pci::device iware::pci::identify_device(std::uint64_t vendor_id, std::uint64_t device_id) noexcept {
const auto vendor = find_vendor(vendor_id);
if(!vendor)
return {nullptr, nullptr};
const auto device_itr = std::lower_bound(std::begin(vendor->device_indices), std::end(vendor->device_indices), device_id,
[](auto left, auto right) { return devices[left].pci_id < right; });
if(device_itr == std::end(vendor->device_indices) || devices[*device_itr].pci_id != device_id)
return {vendor->name, nullptr};
const auto& device = devices[*device_itr];
return {vendor->name, device.name};
}
const char* iware::pci::identify_vendor(std::uint64_t pci_id) noexcept {
if(const auto vendor = find_vendor(pci_id))
return vendor->name;
else
return nullptr;
}
+46
View File
@@ -0,0 +1,46 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef __APPLE__
#include "infoware/detail/sysctl.hpp"
#include "infoware/system.hpp"
#include <cstdlib>
iware::system::OS_info_t iware::system::OS_info() {
auto ctl_ostype_data = iware::detail::sysctl("kern.ostype");
auto ctl_version_data = iware::detail::sysctl("kern.version");
auto ctl_osrelease_data = iware::detail::sysctl("kern.osrelease");
char buf{};
char* osrelease_marker = ctl_osrelease_data.empty() ? &buf : ctl_osrelease_data.data();
const auto ctl_osrevision_data = iware::detail::sysctl("kern.osrevision");
unsigned int build_number{};
if(!ctl_osrevision_data.empty()) {
const auto osrevision_data = iware::detail::deconstruct_sysctl_int(ctl_osrevision_data);
if(osrevision_data.first)
build_number = osrevision_data.second;
}
return {ctl_ostype_data.empty() ? "" : ctl_ostype_data.data(), //
ctl_version_data.empty() ? "" : ctl_version_data.data(), //
static_cast<unsigned int>(std::strtoul(osrelease_marker, &osrelease_marker, 10)), //
static_cast<unsigned int>(std::strtoul(osrelease_marker + 1, &osrelease_marker, 10)), //
static_cast<unsigned int>(std::strtoul(osrelease_marker + 1, nullptr, 10)), //
build_number};
}
#endif
@@ -0,0 +1,98 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#include "infoware/system.hpp"
#include <cstdlib>
#include <fstream>
static iware::system::OS_info_t lsb_release(std::ifstream& release) {
iware::system::OS_info_t ret{};
for(std::string line; std::getline(release, line);)
if(line.find("DISTRIB_ID") == 0)
ret.name = line.substr(line.find('=') + 1);
else if(line.find("DISTRIB_RELEASE") == 0) {
char* marker = &line[line.find('=') + 1];
ret.major = std::strtoul(marker, &marker, 10);
ret.minor = std::strtoul(marker + 1, &marker, 10);
ret.patch = std::strtoul(marker + 1, &marker, 10);
ret.build_number = std::strtoul(marker + 1, nullptr, 10);
} else if(line.find("DISTRIB_DESCRIPTION") == 0) {
const auto start_idx = line.find('"') + 1;
const auto end_idx = line.size() - 1;
ret.full_name = line.substr(start_idx, end_idx - start_idx);
}
return ret;
}
static void trim_quotes(std::string& in) {
if(in.empty())
return;
if(in.back() == '"')
in.pop_back();
if(in.front() == '"')
in.erase(in.begin());
}
// https://www.linux.org/docs/man5/os-release.html
iware::system::OS_info_t iware::system::OS_info() {
std::ifstream release("/etc/os-release");
if(!release.is_open() || !release) {
release.open("/usr/lib/os-release", std::ios::in);
if(!release.is_open() || !release) {
release.open("/etc/lsb-release", std::ios::in);
if(!release.is_open() || !release)
return {};
else
return lsb_release(release);
}
}
iware::system::OS_info_t ret{};
for(std::string line; std::getline(release, line);)
if(line.find("NAME") == 0)
ret.name = line.substr(line.find('=') + 1);
else if(line.find("PRETTY_NAME") == 0)
ret.full_name = line.substr(line.find('=') + 1);
else if(line.find("VERSION_ID") == 0) {
char* marker = &line[line.find('=') + 1];
if(marker[0] == '"')
++marker;
ret.major = std::strtoul(marker, &marker, 10);
if(marker[0] && marker[0] != '"')
ret.minor = std::strtoul(marker + 1, &marker, 10);
if(marker[0] && marker[0] != '"')
ret.patch = std::strtoul(marker + 1, &marker, 10);
if(marker[0] && marker[0] != '"')
ret.build_number = std::strtoul(marker + 1, nullptr, 10);
}
trim_quotes(ret.name);
trim_quotes(ret.full_name);
return ret;
}
#endif
#endif
+88
View File
@@ -0,0 +1,88 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/detail/memory.hpp"
#include "infoware/detail/scope.hpp"
#include "infoware/detail/winstring.hpp"
#include "infoware/system.hpp"
#include <memory>
#include <string>
#define WIN32_LEAN_AND_MEAN
#include <wbemidl.h>
#include <windows.h>
// Use WIM to acquire Win32_OperatingSystem.Name
// https://msdn.microsoft.com/en-us/library/aa390423(v=vs.85).aspx
static std::string version_name() {
auto err = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if(FAILED(err) && err != RPC_E_CHANGED_MODE)
return {};
iware::detail::quickscope_wrapper com_uninitialiser{CoUninitialize};
const auto init_result =
CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE, nullptr);
if(FAILED(init_result) && init_result != RPC_E_TOO_LATE)
return {};
IWbemLocator* wbem_loc_raw;
if(FAILED(CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<void**>(&wbem_loc_raw))))
return {};
std::unique_ptr<IWbemLocator, iware::detail::release_deleter> wbem_loc(wbem_loc_raw);
IWbemServices* wbem_services_raw;
wchar_t network_resource[] = LR"(ROOT\CIMV2)";
if(FAILED(wbem_loc->ConnectServer(network_resource, nullptr, nullptr, 0, 0, 0, 0, &wbem_services_raw)))
return {};
std::unique_ptr<IWbemServices, iware::detail::release_deleter> wbem_services(wbem_services_raw);
if(FAILED(CoSetProxyBlanket(wbem_services.get(), RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr,
EOAC_NONE)))
return {};
IEnumWbemClassObject* query_iterator_raw;
wchar_t query_lang[] = L"WQL";
wchar_t query[] = L"SELECT Name FROM Win32_OperatingSystem";
if(FAILED(wbem_services->ExecQuery(query_lang, query, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &query_iterator_raw)))
return {};
std::unique_ptr<IEnumWbemClassObject, iware::detail::release_deleter> query_iterator(query_iterator_raw);
std::string ret;
while(query_iterator) {
IWbemClassObject* value_raw;
unsigned long iter_result;
query_iterator->Next(static_cast<LONG>(WBEM_INFINITE), 1, &value_raw, &iter_result);
if(!iter_result)
break;
std::unique_ptr<IWbemClassObject, iware::detail::release_deleter> value(value_raw);
VARIANT val;
value->Get(L"Name", 0, &val, 0, 0);
iware::detail::quickscope_wrapper val_destructor{[&] { VariantClear(&val); }};
ret = iware::detail::narrowen_bstring(val.bstrVal);
}
return ret.substr(0, ret.find('|'));
}
iware::system::OS_info_t iware::system::OS_info() {
const auto kernel_version = iware::system::kernel_info();
return {"Windows NT", version_name(), kernel_version.major, kernel_version.minor, kernel_version.patch, kernel_version.build_number};
}
#endif
@@ -0,0 +1,55 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#include "infoware/detail/scope.hpp"
#include "infoware/system.hpp"
#include <cstring>
#include <wordexp.h>
// http://man7.org/linux/man-pages/man3/wordexp.3.html
static std::size_t count_expansions(const char* of) noexcept {
wordexp_t exp{};
iware::detail::quickscope_wrapper exp_deleter{[&]() { wordfree(&exp); }};
if(wordexp(of, &exp, 0))
return 0;
// If nothing is expanded wordexp() returns the original string
if(exp.we_wordc == 1 && std::strcmp(exp.we_wordv[0], of) == 0)
return 0;
else
return exp.we_wordc;
}
// http://unix.stackexchange.com/questions/25601/how-do-mouse-events-work-in-linux
// https://www.kernel.org/doc/Documentation/input/input.txt section 3.2.2
std::size_t iware::system::mouse_amount() noexcept {
return count_expansions("/dev/input/mouse*");
}
// https://www.kernel.org/doc/Documentation/input/input.txt section 3.2.1
// Doesn't specify that and there doesn't seem to be a way to get it
std::size_t iware::system::keyboard_amount() noexcept {
return 0;
}
std::size_t iware::system::other_HID_amount() noexcept {
return 0;
}
#endif
+47
View File
@@ -0,0 +1,47 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/system.hpp"
#define WIN32_LEAN_AND_MEAN
#include <algorithm>
#include <windows.h>
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms645598(v=vs.85).aspx
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms645568(v=vs.85).aspx
static std::size_t device_amount(unsigned int device_type) noexcept {
// Assuming 64 is enough for anyone
RAWINPUTDEVICELIST input_devices[64];
unsigned int input_devices_n = sizeof(input_devices) / sizeof(RAWINPUTDEVICELIST);
const auto amt = GetRawInputDeviceList(input_devices, &input_devices_n, sizeof(RAWINPUTDEVICELIST));
return std::count_if(input_devices, input_devices + amt, [&](auto&& device) { return device.dwType == device_type; });
}
std::size_t iware::system::mouse_amount() noexcept {
return device_amount(RIM_TYPEMOUSE);
}
std::size_t iware::system::keyboard_amount() noexcept {
return device_amount(RIM_TYPEKEYBOARD);
}
std::size_t iware::system::other_HID_amount() noexcept {
return device_amount(RIM_TYPEHID);
}
#endif
+103
View File
@@ -0,0 +1,103 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
//
//
// Darwin support via Carbon API originally by Arthur Biancarelli https://github.com/ThePhD/infoware/issues/17#issuecomment-538789869
#ifdef __APPLE__
#include "infoware/detail/scope.hpp"
#include "infoware/system.hpp"
#include <ApplicationServices/ApplicationServices.h>
#include <algorithm>
#include <cstring>
template <class T, class F>
static std::vector<T> enumerate_displays(F&& cbk) {
std::uint32_t num_displays;
if(CGGetActiveDisplayList(0, nullptr, &num_displays) != kCGErrorSuccess)
return {};
std::vector<CGDirectDisplayID> display_ids(num_displays);
if(CGGetActiveDisplayList(num_displays, display_ids.data(), &num_displays) != kCGErrorSuccess)
return {};
std::vector<T> ret;
ret.reserve(num_displays);
for(std::size_t i = 0; i < num_displays; ++i)
ret.emplace_back(std::move(cbk(display_ids[i])));
return ret;
}
std::vector<iware::system::display_t> iware::system::displays() {
return enumerate_displays<iware::system::display_t>([](auto display_id) {
const std::uint32_t width = CGDisplayPixelsWide(display_id);
// 25.4 millimeters per inch
const std::uint32_t dpi = 25.4 * CGDisplayScreenSize(display_id).width / width;
auto display_mode = CGDisplayCopyDisplayMode(display_id);
iware::detail::quickscope_wrapper display_mode_deleter{[&]() { CGDisplayModeRelease(display_mode); }};
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
// A string in the form --------RRRRRRRRGGGGGGGGBBBBBBBB
auto pixel_encoding_raw = CGDisplayModeCopyPixelEncoding(display_mode);
iware::detail::quickscope_wrapper pixel_encoding_raw_deleter{[&]() { CFRelease(pixel_encoding_raw); }};
#pragma GCC diagnostic pop
// Count the number of occurences of R/G/B pixels
std::uint32_t bpp{};
if(const auto pixel_encoding = CFStringGetCStringPtr(pixel_encoding_raw, kCFStringEncodingUTF8))
bpp = std::count_if(pixel_encoding, pixel_encoding + std::strlen(pixel_encoding), [](auto c) { return c == 'R' || c == 'G' || c == 'B'; });
return iware::system::display_t{width, static_cast<std::uint32_t>(CGDisplayPixelsHigh(display_id)), dpi, bpp,
// The refresh rate, in hertz, of the specified display mode for a CRT display.
// Some displays may not use conventional video vertical and horizontal sweep in painting the screen;
// for these displays, the return value is 0.
//
// Tested to return 0 for Retina displays
CGDisplayModeGetRefreshRate(display_mode)};
});
}
std::vector<std::vector<iware::system::display_config_t>> iware::system::available_display_configurations() {
return enumerate_displays<std::vector<iware::system::display_config_t>>([](auto display_id) {
auto modes = CGDisplayCopyAllDisplayModes(display_id, nullptr);
if(!modes)
return std::vector<iware::system::display_config_t>{};
iware::detail::quickscope_wrapper modes_deleter{[&]() { CFRelease(modes); }};
const auto modes_len = CFArrayGetCount(modes);
std::vector<iware::system::display_config_t> ret;
ret.reserve(modes_len);
for(auto i = 0l; i < modes_len; ++i) {
auto mode = static_cast<CGDisplayModeRef>(const_cast<void*>(CFArrayGetValueAtIndex(modes, i)));
ret.emplace_back(iware::system::display_config_t{static_cast<std::uint32_t>(CGDisplayModeGetWidth(mode)),
static_cast<std::uint32_t>(CGDisplayModeGetHeight(mode)),
{CGDisplayModeGetRefreshRate(mode)}});
}
return ret;
});
}
#endif
@@ -0,0 +1,32 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#ifndef INFOWARE_USE_X11
#include "infoware/system.hpp"
std::vector<iware::system::display_t> iware::system::displays() {
return {};
}
std::vector<std::vector<iware::system::display_config_t>> iware::system::available_display_configurations() {
return {};
}
#endif
#endif
#endif
+97
View File
@@ -0,0 +1,97 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/system.hpp"
#include <algorithm>
#include <cstdlib>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
std::vector<iware::system::display_t> iware::system::displays() {
std::vector<iware::system::display_t> ret;
EnumDisplayMonitors(
nullptr, nullptr,
[](auto, auto hdc, auto rect, auto userdata) {
static const auto desktop_dc = GetDC(nullptr);
static const unsigned int desktop_dpi = GetDeviceCaps(desktop_dc, LOGPIXELSX);
// https://blogs.msdn.microsoft.com/oldnewthing/20101013-00/?p=12543
static const unsigned int desktop_bpp = GetDeviceCaps(desktop_dc, BITSPIXEL) * GetDeviceCaps(desktop_dc, PLANES);
static const double desktop_refresh_rate = GetDeviceCaps(desktop_dc, VREFRESH);
// https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx
// Doesn't work, can't link to shcore
//
// unsigned int dpi_x;
// unsigned int dpi_y;
// GetDpiForMonitor(monitor /* arg #1 */, MDT_DEFAULT, &dpi_x, &dpi_y);
// Sometimes returns 0 for some reason?
// Fall back to the desktop's globals if so.
const unsigned int monitor_dpi = GetDeviceCaps(hdc, LOGPIXELSX);
const unsigned int monitor_bpp = GetDeviceCaps(hdc, BITSPIXEL) * GetDeviceCaps(hdc, PLANES);
const double monitor_refresh_rate = GetDeviceCaps(hdc, VREFRESH);
const unsigned int width = std::abs(rect->right - rect->left);
const unsigned int height = std::abs(rect->bottom - rect->top);
auto& ret = *reinterpret_cast<std::vector<iware::system::display_t>*>(userdata);
// See http://stackoverflow.com/a/12654433/2851815 and up for DPI. In short: can't be done too too well, go with best solution.
ret.push_back({width, height, monitor_dpi ? monitor_dpi : desktop_dpi, monitor_bpp ? monitor_bpp : desktop_bpp,
monitor_refresh_rate ? monitor_refresh_rate : desktop_refresh_rate});
return 1;
},
reinterpret_cast<LPARAM>(&ret));
return ret;
}
std::vector<std::vector<iware::system::display_config_t>> iware::system::available_display_configurations() {
std::vector<std::vector<iware::system::display_config_t>> ret;
DISPLAY_DEVICE dev;
dev.cb = sizeof(dev);
for(DWORD dev_i = 0; EnumDisplayDevices(nullptr, dev_i, &dev, EDD_GET_DEVICE_INTERFACE_NAME); ++dev_i) {
std::vector<iware::system::display_config_t> configs;
const auto add_config = [&](auto&& mode) {
configs.emplace_back(iware::system::display_config_t{mode.dmPelsWidth, mode.dmPelsHeight, {static_cast<double>(mode.dmDisplayFrequency)}});
};
DEVMODE mode{};
for(DWORD mode_i = 0; EnumDisplaySettings(dev.DeviceName, mode_i, &mode); ++mode_i)
if(configs.empty())
add_config(mode);
else {
auto&& last = configs.back();
if(last.width == mode.dmPelsWidth && last.height == mode.dmPelsHeight) {
if(std::find(last.refresh_rates.begin(), last.refresh_rates.end(), mode.dmDisplayFrequency) == last.refresh_rates.end())
last.refresh_rates.emplace_back(mode.dmDisplayFrequency);
} else
add_config(mode);
}
if(!configs.empty())
ret.emplace_back(std::move(configs));
}
return ret;
}
#endif
+91
View File
@@ -0,0 +1,91 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#ifdef INFOWARE_USE_X11
#include "infoware/detail/scope.hpp"
#include "infoware/system.hpp"
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <cstdlib>
template <class T, class F>
static std::vector<T> enumerate_screens(F&& cbk) {
const auto display_name = std::getenv("DISPLAY");
if(!display_name)
return {};
auto display = XOpenDisplay(display_name);
if(!display)
return {};
iware::detail::quickscope_wrapper display_deleter{[&]() { XCloseDisplay(display); }};
const auto screen_count = ScreenCount(display);
std::vector<T> ret;
ret.reserve(screen_count);
for(auto i = 0; i < screen_count; ++i) {
const auto root = RootWindow(display, i);
auto config = XRRGetScreenInfo(display, root);
if(!config)
continue;
iware::detail::quickscope_wrapper config_deleter{[&]() { XRRFreeScreenConfigInfo(config); }};
ret.emplace_back(std::move(cbk(display, i, config)));
}
return ret;
}
std::vector<iware::system::display_t> iware::system::displays() {
return enumerate_screens<iware::system::display_t>([](auto display, auto screen_number, auto screen_config) {
const std::uint32_t width = DisplayWidth(display, screen_number);
return iware::system::display_t{
width,
static_cast<std::uint32_t>(DisplayHeight(display, screen_number)),
// 25.4 millimeters per inch
static_cast<std::uint32_t>(25.4 * DisplayWidthMM(display, screen_number) / width),
static_cast<std::uint32_t>(DefaultDepth(display, screen_number)),
static_cast<double>(XRRConfigCurrentRate(screen_config)),
};
});
}
std::vector<std::vector<iware::system::display_config_t>> iware::system::available_display_configurations() {
return enumerate_screens<std::vector<iware::system::display_config_t>>([](auto, auto, auto screen_config) {
int size_count;
const auto sizes = XRRConfigSizes(screen_config, &size_count);
std::vector<iware::system::display_config_t> configs;
configs.reserve(size_count);
for(auto i = 0; i < size_count; i++) {
int rate_count;
const auto rates = XRRConfigRates(screen_config, i, &rate_count);
configs.emplace_back(iware::system::display_config_t{
static_cast<std::uint32_t>(sizes[i].width), static_cast<std::uint32_t>(sizes[i].height), {rates, rates + rate_count}});
}
return configs;
});
}
#endif
#endif
#endif
@@ -0,0 +1,42 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#include "infoware/system.hpp"
#include <cstdlib>
#include <cstring>
#include <sys/utsname.h>
iware::system::kernel_info_t iware::system::kernel_info() {
utsname uts;
uname(&uts);
char* marker = uts.release;
const std::uint32_t major = std::strtoul(marker, &marker, 10);
const std::uint32_t minor = std::strtoul(marker + 1, &marker, 10);
const std::uint32_t patch = std::strtoul(marker + 1, &marker, 10);
const std::uint32_t build_number = std::strtoul(marker + 1, nullptr, 10);
auto kernel = iware::system::kernel_t::unknown;
if(!std::strcmp(uts.sysname, "Linux"))
kernel = iware::system::kernel_t::linux;
else if(!std::strcmp(uts.sysname, "Darwin"))
kernel = iware::system::kernel_t::darwin;
return {kernel, major, minor, patch, build_number};
}
#endif
@@ -0,0 +1,45 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/detail/scope.hpp"
#include "infoware/system.hpp"
#include <memory>
#include <string>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
// Get OS (platform) version from kernel32.dll because GetVersion is deprecated in Win8+
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
iware::system::kernel_info_t iware::system::kernel_info() {
std::string path;
path.resize(GetSystemDirectoryA(nullptr, 0) - 1);
GetSystemDirectoryA(&path[0], static_cast<UINT>(path.size() + 1));
path += "\\kernel32.dll";
const auto ver_info_len = GetFileVersionInfoSizeA(path.c_str(), nullptr);
auto ver_info = std::make_unique<std::uint8_t[]>(ver_info_len);
GetFileVersionInfoA(path.c_str(), 0, ver_info_len, ver_info.get());
VS_FIXEDFILEINFO* file_version;
unsigned int file_version_len;
VerQueryValueA(ver_info.get(), "", reinterpret_cast<void**>(&file_version), &file_version_len);
return {iware::system::kernel_t::windows_nt, HIWORD(file_version->dwProductVersionMS), LOWORD(file_version->dwProductVersionMS),
HIWORD(file_version->dwProductVersionLS), LOWORD(file_version->dwProductVersionLS)};
}
#endif
+51
View File
@@ -0,0 +1,51 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef __APPLE__
#include "infoware/detail/sysctl.hpp"
#include "infoware/system.hpp"
#include <cstdint>
#include <mach/mach.h>
#include <mach/vm_statistics.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <unistd.h>
/// Adapted from https://stackoverflow.com/q/14789672/2851815
iware::system::memory_t iware::system::memory() noexcept {
iware::system::memory_t ret{};
const auto host = mach_host_self();
const auto ctl_ram = iware::detail::sysctl(CTL_HW, HW_MEMSIZE);
if(!ctl_ram.empty()) {
const auto ram = iware::detail::deconstruct_sysctl_int(ctl_ram);
if(ram.first)
ret.virtual_total = ram.second;
}
vm_statistics64 stats;
natural_t count = HOST_VM_INFO64_COUNT;
if(host_statistics64(host, HOST_VM_INFO64, reinterpret_cast<host_info64_t>(&stats), &count) == KERN_SUCCESS)
ret.virtual_available = stats.free_count * getpagesize();
ret.physical_total = ret.virtual_total;
ret.physical_available = ret.virtual_available;
return ret;
}
#endif
@@ -0,0 +1,48 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifndef _WIN32
#ifndef __APPLE__
#include "infoware/system.hpp"
#include <fstream>
#include <string>
iware::system::memory_t iware::system::memory() noexcept {
std::ifstream meminfo("/proc/meminfo");
if(!meminfo.is_open() || !meminfo)
return {};
iware::system::memory_t ret;
for(std::string line; std::getline(meminfo, line);) {
const auto colon_id = line.find_first_of(':');
const auto value = std::strtoul(line.c_str() + colon_id + 1, nullptr, 10) * 1024;
if(line.find("MemTotal") == 0)
ret.physical_total = value;
else if(line.find("MemAvailable") == 0)
ret.physical_available = value;
else if(line.find("VmallocTotal") == 0)
ret.virtual_total = value;
else if(line.find("VmallocUsed") == 0)
ret.virtual_available = ret.virtual_total - value;
}
return ret;
}
#endif
#endif
+31
View File
@@ -0,0 +1,31 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#ifdef _WIN32
#include "infoware/system.hpp"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
iware::system::memory_t iware::system::memory() noexcept {
MEMORYSTATUSEX mem;
mem.dwLength = sizeof(mem);
if(!GlobalMemoryStatusEx(&mem))
return {};
return {mem.ullAvailPhys, mem.ullTotalPhys, mem.ullAvailVirtual, mem.ullTotalVirtual};
}
#endif
+16
View File
@@ -0,0 +1,16 @@
// infoware - C++ System information Library
//
// Written in 2016-2020 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>
#include "infoware/version.hpp"
const char* const iware::version = INFOWARE_VERSION;