CppCommon 1.0.5.0
C++ Common Library
Loading...
Searching...
No Matches
memory.cpp
Go to the documentation of this file.
1
9#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
10#define __STDC_WANT_LIB_EXT1__ 1
11#include <stdlib.h>
12#include <string.h>
13#endif
14
15#include "memory/memory.h"
16
17#if defined(__APPLE__)
18#include <mach/mach.h>
19#include <sys/sysctl.h>
20#include <fcntl.h>
21#include <unistd.h>
22#elif defined(unix) || defined(__unix) || defined(__unix__)
23#include <sys/sysinfo.h>
24#include <fcntl.h>
25#include <unistd.h>
26#elif defined(_WIN32) || defined(_WIN64)
27#include <windows.h>
28#include <wincrypt.h>
29#endif
30
31namespace CppCommon {
32
34{
35#if defined(__APPLE__)
36 int64_t memsize = 0;
37 size_t size = sizeof(memsize);
38 if (sysctlbyname("hw.memsize", &memsize, &size, nullptr, 0) == 0)
39 return memsize;
40
41 return -1;
42#elif defined(unix) || defined(__unix) || defined(__unix__)
43 int64_t pages = sysconf(_SC_PHYS_PAGES);
44 int64_t page_size = sysconf(_SC_PAGESIZE);
45 if ((pages > 0) && (page_size > 0))
46 return pages * page_size;
47
48 return -1;
49#elif defined(_WIN32) || defined(_WIN64)
50 MEMORYSTATUSEX status;
51 status.dwLength = sizeof(status);
52 GlobalMemoryStatusEx(&status);
53 return status.ullTotalPhys;
54#else
55 #error Unsupported platform
56#endif
57}
58
60{
61#if defined(__APPLE__)
62 mach_port_t host_port = mach_host_self();
63 if (host_port == MACH_PORT_NULL)
64 return -1;
65
66 vm_size_t page_size = 0;
67 host_page_size(host_port, &page_size);
68
69 vm_statistics_data_t vmstat;
70 mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
71 kern_return_t kernReturn = host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vmstat, &count);
72 if (kernReturn != KERN_SUCCESS)
73 return -1;
74
75 [[maybe_unused]] int64_t used_mem = (vmstat.active_count + vmstat.inactive_count + vmstat.wire_count) * page_size;
76 int64_t free_mem = vmstat.free_count * page_size;
77 return free_mem;
78#elif defined(unix) || defined(__unix) || defined(__unix__)
79 int64_t pages = sysconf(_SC_AVPHYS_PAGES);
80 int64_t page_size = sysconf(_SC_PAGESIZE);
81 if ((pages > 0) && (page_size > 0))
82 return pages * page_size;
83
84 return -1;
85#elif defined(_WIN32) || defined(_WIN64)
86 MEMORYSTATUSEX status;
87 status.dwLength = sizeof(status);
88 GlobalMemoryStatusEx(&status);
89 return status.ullAvailPhys;
90#else
91 #error Unsupported platform
92#endif
93}
94
95bool Memory::IsZero(const void* buffer, size_t size) noexcept
96{
97 const char* ptr = (const char*)buffer;
98 for (size_t i = 0; i < size; ++i)
99 if (ptr[i] != 0)
100 return false;
101 return true;
102}
103
104void Memory::ZeroFill(void* buffer, size_t size)
105{
106#ifdef __STDC_LIB_EXT1__
107 memset_s(buffer, size, 0, size);
108#elif defined(_WIN32) || defined(_WIN64)
109 SecureZeroMemory(buffer, size);
110#else
111 volatile char* ptr = (volatile char*)buffer;
112 while (size--)
113 *ptr++ = 0;
114#endif
115}
116
117void Memory::RandomFill(void* buffer, size_t size)
118{
119#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
120 int fd = open("/dev/urandom", O_RDONLY);
121 if (fd < 0)
122 throwex SystemException("Cannot open '/dev/urandom' file for reading!");
123 ssize_t count = read(fd, buffer, size);
124 if (count < 0)
125 throwex SystemException("Cannot read from '/dev/urandom' file!");
126 int result = close(fd);
127 if (result != 0)
128 throwex SystemException("Cannot close '/dev/urandom' file!");
129#elif defined(_WIN32) || defined(_WIN64)
130 char* ptr = (char*)buffer;
131 for(size_t i = 0; i < size; ++i)
132 ptr[i] = rand() % 256;
133#endif
134}
135
136void Memory::CryptoFill(void* buffer, size_t size)
137{
138#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
139 int fd = open("/dev/random", O_RDONLY);
140 if (fd < 0)
141 throwex SystemException("Cannot open '/dev/random' file for reading!");
142 ssize_t count = read(fd, buffer, size);
143 if (count < 0)
144 throwex SystemException("Cannot read from '/dev/random' file!");
145 int result = close(fd);
146 if (result != 0)
147 throwex SystemException("Cannot close '/dev/random' file!");
148#elif defined(_WIN32) || defined(_WIN64)
149 HCRYPTPROV hCryptContext;
150 if (!CryptAcquireContext(&hCryptContext, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
151 throwex SystemException("Cannot acquire cryptographic service provider context!");
152 if (!CryptGenRandom(hCryptContext, (DWORD)size, (BYTE*)buffer))
153 throwex SystemException("Cannot generate random bytes using cryptographic service provider context!");
154 if (!CryptReleaseContext(hCryptContext, 0))
155 throwex SystemException("Cannot release cryptographic service provider context!");
156#endif
157}
158
159} // namespace CppCommon
static bool IsZero(const void *buffer, size_t size) noexcept
Is the given memory buffer filled with zeros?
Definition memory.cpp:95
static void CryptoFill(void *buffer, size_t size)
Fill the given memory buffer with cryptographic strong random bytes.
Definition memory.cpp:136
static int64_t RamFree()
Free RAM in bytes.
Definition memory.cpp:59
static int64_t RamTotal()
Total RAM in bytes.
Definition memory.cpp:33
static void ZeroFill(void *buffer, size_t size)
Fill the given memory buffer with zeros.
Definition memory.cpp:104
static void RandomFill(void *buffer, size_t size)
Fill the given memory buffer with random bytes.
Definition memory.cpp:117
System exception.
Definition exceptions.h:107
#define throwex
Throw extended exception macro.
Definition exceptions.h:23
Memory management definition.
C++ Common project definitions.