|
42 | 42 |
|
43 | 43 | #include "wwmem.h" |
44 | 44 |
|
| 45 | +#if defined(__unix__) || defined(__unix) |
| 46 | +#include <sys/sysinfo.h> |
| 47 | +#include <unistd.h> |
| 48 | +#elif defined(__APPLE__) |
| 49 | +#include <proc.h> |
| 50 | +#elif defined(_WIN32) |
| 51 | +#include <windows.h> |
| 52 | +#endif |
| 53 | + |
45 | 54 | size_t Largest_Mem_Block(void); |
46 | 55 |
|
47 | 56 | /*=========================================================================*/ |
@@ -219,9 +228,69 @@ void* Resize_Alloc(void* original_ptr, size_t new_size_in_bytes) |
219 | 228 | * HISTORY: * |
220 | 229 | * 09/03/1991 JLB : Commented. * |
221 | 230 | *=========================================================================*/ |
222 | | -int Ram_Free(MemoryFlagType) |
| 231 | +size_t Ram_Free(MemoryFlagType) |
223 | 232 | { |
224 | | - return (64 * 1024 * 1024); |
| 233 | + return Ram_Free(); |
| 234 | +} |
| 235 | + |
| 236 | +size_t Ram_Free(void) |
| 237 | +{ |
| 238 | +#if defined(__unix__) || defined(__unix) |
| 239 | + // Get amount of memory available to program. |
| 240 | + return sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE); |
| 241 | +#elif defined(__APPLE__) |
| 242 | + return os_proc_available_memory(); |
| 243 | +#elif defined(_WIN32) |
| 244 | + MEMORYSTATUSEX status; |
| 245 | + status.dwLength = sizeof(status); |
| 246 | + GlobalMemoryStatusEx(&status); |
| 247 | + return status.ullAvaillPhys; |
| 248 | +#else |
| 249 | + // Oh dear. We are running in some kind of baremetal machine. |
| 250 | + // Assume malloc returns NULL if there is not enough memory. |
| 251 | + // |
| 252 | + // Let's try to allocate a huge chunk of memory first to check if |
| 253 | + // malloc returns NULL on absurd cases. |
| 254 | + |
| 255 | + void* p = malloc(1 * 1024 * 1024 * 1024); |
| 256 | + if (p) { |
| 257 | + // Either this machine has a lot of memory, or malloc doesn't return |
| 258 | + // NULL when out of memory. Hence, returns a safe value. |
| 259 | + free(p); |
| 260 | + return 128 * 1024 * 1024; |
| 261 | + } |
| 262 | + |
| 263 | + // There is no way other than do a binary search with malloc to check. |
| 264 | + // which is the maximum value that it returns something valid. |
| 265 | + |
| 266 | + size_t x1 = 128 * 1024 * 1024; |
| 267 | + size_t x0 = 0; |
| 268 | + |
| 269 | + // Find rightmost element; |
| 270 | + do { |
| 271 | + p = malloc(x1); |
| 272 | + if (p) { |
| 273 | + free(p); |
| 274 | + } else { |
| 275 | + x0 = x1; |
| 276 | + x1 *= 2; |
| 277 | + } |
| 278 | + } while (p != NULL); |
| 279 | + |
| 280 | + // Binary search a value between x0 and x1; |
| 281 | + while (x0 < x1) { |
| 282 | + size_t m = (x1 - x0) / 2; |
| 283 | + p = malloc(m); |
| 284 | + if (p) { |
| 285 | + free(p); |
| 286 | + x0 = m; |
| 287 | + } else { |
| 288 | + x1 = m; |
| 289 | + } |
| 290 | + } |
| 291 | + |
| 292 | + return x1; |
| 293 | +#endif |
225 | 294 | } |
226 | 295 |
|
227 | 296 | /*************************************************************************** |
|
0 commit comments