Skip to content

Commit 58c3443

Browse files
Implement Ram_Free to check amout of free RAM.
Signed-off-by: Giuliano Belinassi <gbelinassi@suse.de>
1 parent 15a5c1e commit 58c3443

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

common/alloc.cpp

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@
4242

4343
#include "wwmem.h"
4444

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+
4554
size_t Largest_Mem_Block(void);
4655

4756
/*=========================================================================*/
@@ -219,9 +228,69 @@ void* Resize_Alloc(void* original_ptr, size_t new_size_in_bytes)
219228
* HISTORY: *
220229
* 09/03/1991 JLB : Commented. *
221230
*=========================================================================*/
222-
int Ram_Free(MemoryFlagType)
231+
size_t Ram_Free(MemoryFlagType)
223232
{
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
225294
}
226295

227296
/***************************************************************************

common/memflag.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ void* operator new[](size_t size, MemoryFlagType flag);
6464
void* Alloc(size_t bytes_to_alloc, MemoryFlagType flags);
6565
void Free(void const* pointer);
6666
void* Resize_Alloc(void* original_ptr, size_t new_size_in_bytes);
67-
int Ram_Free(MemoryFlagType flag);
67+
size_t Ram_Free(MemoryFlagType flag);
68+
size_t Ram_Free(void);
6869
int Heap_Size(MemoryFlagType flag);
6970
int Total_Ram_Free(MemoryFlagType flag);
7071

0 commit comments

Comments
 (0)