ValueUnion - A type used to correctly alias the byte-for-byte output of `sysctl` with the result type it's to be interpreted as.
| 94 | /// ValueUnion - A type used to correctly alias the byte-for-byte output of |
| 95 | /// `sysctl` with the result type it's to be interpreted as. |
| 96 | struct ValueUnion { |
| 97 | union DataT { |
| 98 | int32_t int32_value; |
| 99 | int64_t int64_value; |
| 100 | // For correct aliasing of union members from bytes. |
| 101 | char bytes[8]; |
| 102 | }; |
| 103 | using DataPtr = std::unique_ptr<DataT, decltype(&std::free)>; |
| 104 | |
| 105 | // The size of the data union member + its trailing array size. |
| 106 | std::size_t size; |
| 107 | DataPtr buff; |
| 108 | |
| 109 | public: |
| 110 | ValueUnion() : size(0), buff(nullptr, &std::free) {} |
| 111 | |
| 112 | explicit ValueUnion(std::size_t buff_size) |
| 113 | : size(sizeof(DataT) + buff_size), |
| 114 | buff(::new (std::malloc(size)) DataT(), &std::free) {} |
| 115 | |
| 116 | ValueUnion(ValueUnion&& other) = default; |
| 117 | |
| 118 | explicit operator bool() const { return bool(buff); } |
| 119 | |
| 120 | char* data() const { return buff->bytes; } |
| 121 | |
| 122 | std::string GetAsString() const { return std::string(data()); } |
| 123 | |
| 124 | int64_t GetAsInteger() const { |
| 125 | if (size == sizeof(buff->int32_value)) |
| 126 | return buff->int32_value; |
| 127 | else if (size == sizeof(buff->int64_value)) |
| 128 | return buff->int64_value; |
| 129 | BENCHMARK_UNREACHABLE(); |
| 130 | } |
| 131 | |
| 132 | template <class T, int N> |
| 133 | std::array<T, N> GetAsArray() { |
| 134 | const int arr_size = sizeof(T) * N; |
| 135 | BM_CHECK_LE(arr_size, size); |
| 136 | std::array<T, N> arr; |
| 137 | std::memcpy(arr.data(), data(), arr_size); |
| 138 | return arr; |
| 139 | } |
| 140 | }; |
| 141 | |
| 142 | ValueUnion GetSysctlImp(std::string const& name) { |
| 143 | #if defined BENCHMARK_OS_OPENBSD |