Skip to content

Commit

Permalink
Merge pull request #25 from JuliaLang/tb/available_memory
Browse files Browse the repository at this point in the history
Backport changes for further cgroupv2 compat
  • Loading branch information
maleadt authored Sep 19, 2022
2 parents 6d2f161 + e592899 commit e6f0e49
Show file tree
Hide file tree
Showing 17 changed files with 140 additions and 5 deletions.
16 changes: 15 additions & 1 deletion docs/src/misc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ API
.. c:function:: uint64_t uv_get_constrained_memory(void)
Gets the amount of memory available to the process (in bytes) based on
Gets the total amount of memory available to the process (in bytes) based on
limits imposed by the OS. If there is no such constraint, or the constraint
is unknown, `0` is returned. Note that it is not unusual for this value to
be less than or greater than :c:func:`uv_get_total_memory`.
Expand All @@ -573,6 +573,20 @@ API
.. versionadded:: 1.29.0
.. c:function:: uint64_t uv_get_available_memory(void)
Gets the amount of free memory that is still available to the process (in bytes).
This differs from :c:func:`uv_get_free_memory` in that it takes into account any
limits imposed by the OS. If there is no such constraint, or the constraint
is unknown, the amount returned will be identical to :c:func:`uv_get_free_memory`.
.. note::
This function currently only returns a value that is different from
what :c:func:`uv_get_free_memory` reports on Linux, based
on cgroups if it is present.
.. versionadded:: 1.45.0
.. c:function:: uint64_t uv_hrtime(void)
Returns the current high-resolution real time. This is expressed in
Expand Down
1 change: 1 addition & 0 deletions include/uv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,7 @@ UV_EXTERN int uv_chdir(const char* dir);
UV_EXTERN uint64_t uv_get_free_memory(void);
UV_EXTERN uint64_t uv_get_total_memory(void);
UV_EXTERN uint64_t uv_get_constrained_memory(void);
UV_EXTERN uint64_t uv_get_available_memory(void);

UV_EXTERN uint64_t uv_hrtime(void);
UV_EXTERN void uv_sleep(unsigned int msec);
Expand Down
5 changes: 5 additions & 0 deletions src/unix/aix.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


void uv_loadavg(double avg[3]) {
perfstat_cpu_total_t ps_total;
int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
Expand Down
4 changes: 4 additions & 0 deletions src/unix/cygwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}

uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}
5 changes: 5 additions & 0 deletions src/unix/darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);
Expand Down
5 changes: 5 additions & 0 deletions src/unix/freebsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);
Expand Down
5 changes: 5 additions & 0 deletions src/unix/haiku.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


int uv_resident_set_memory(size_t* rss) {
area_info area;
ssize_t cookie;
Expand Down
5 changes: 5 additions & 0 deletions src/unix/hurd.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,8 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}
5 changes: 5 additions & 0 deletions src/unix/ibmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


void uv_loadavg(double avg[3]) {
SSTS0200 rcvr;

Expand Down
57 changes: 55 additions & 2 deletions src/unix/linux-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,13 +794,20 @@ static uint64_t uv__read_uint64(const char* filename) {
* limit is unknown.
*/
static uint64_t uv__get_constrained_memory_fallback(void) {
return uv__read_uint64("/sys/fs/cgroup/memory/memory.limit_in_bytes");
uint64_t limit;

limit = uv__read_uint64("/sys/fs/cgroup/memory/memory.limit_in_bytes");
if (limit == LONG_MAX / 4096 * 4096)
return 0;

return limit;
}


uint64_t uv_get_constrained_memory(void) {
char filename[4097];
char buf[1024];
uint64_t limit;
uint64_t high;
uint64_t max;
char* p;
Expand Down Expand Up @@ -830,7 +837,53 @@ uint64_t uv_get_constrained_memory(void) {
if (high == 0)
return uv__get_constrained_memory_fallback();

return high < max ? high : max;
limit = high < max ? high : max;
if (limit == ~0ull)
return 0;
return limit;
}


static uint64_t uv__get_available_memory_fallback(void) {
uint64_t current;
uint64_t constrained;

constrained = uv__get_constrained_memory_fallback();
if (constrained == 0)
return uv_get_free_memory();

current = uv__read_uint64("/sys/fs/cgroup/memory/memory.usage_in_bytes");
return constrained - current;
}


uint64_t uv_get_available_memory(void) {
char filename[4097];
char buf[1024];
uint64_t current;
uint64_t constrained;
char* p;

constrained = uv_get_constrained_memory();
if (constrained == 0)
return uv__get_available_memory_fallback();

if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)))
return uv__get_available_memory_fallback();

if (memcmp(buf, "0::/", 4))
return uv__get_available_memory_fallback();

p = strchr(buf, '\n');
if (p != NULL)
*p = '\0';

p = buf + 4;

snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/memory.current", p);
current = uv__read_uint64(filename);

return constrained - current;
}


Expand Down
5 changes: 5 additions & 0 deletions src/unix/netbsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


int uv_resident_set_memory(size_t* rss) {
kvm_t *kd = NULL;
struct kinfo_proc2 *kinfo = NULL;
Expand Down
5 changes: 5 additions & 0 deletions src/unix/openbsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


int uv_resident_set_memory(size_t* rss) {
struct kinfo_proc kinfo;
size_t page_size = getpagesize();
Expand Down
5 changes: 5 additions & 0 deletions src/unix/os390.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


int uv_resident_set_memory(size_t* rss) {
char* ascb;
char* rax;
Expand Down
5 changes: 5 additions & 0 deletions src/unix/qnx.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


int uv_resident_set_memory(size_t* rss) {
int fd;
procfs_asinfo asinfo;
Expand Down
5 changes: 5 additions & 0 deletions src/unix/sunos.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


void uv_loadavg(double avg[3]) {
(void) getloadavg(avg, 3);
}
Expand Down
5 changes: 5 additions & 0 deletions src/win/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,11 @@ uint64_t uv_get_constrained_memory(void) {
}


uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
}


uv_pid_t uv_os_getpid(void) {
return GetCurrentProcessId();
}
Expand Down
7 changes: 5 additions & 2 deletions test/test-get-memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ TEST_IMPL(get_memory) {
uint64_t free_mem = uv_get_free_memory();
uint64_t total_mem = uv_get_total_memory();
uint64_t constrained_mem = uv_get_constrained_memory();
uint64_t available_mem = uv_get_available_memory();

printf("free_mem=%llu, total_mem=%llu, constrained_mem=%llu\n",
printf("free_mem=%llu, total_mem=%llu, constrained_mem=%llu, available_memo=%llu\n",
(unsigned long long) free_mem,
(unsigned long long) total_mem,
(unsigned long long) constrained_mem);
(unsigned long long) constrained_mem,
(unsigned long long) available_mem);

ASSERT(free_mem > 0);
ASSERT(total_mem > 0);
Expand All @@ -40,5 +42,6 @@ TEST_IMPL(get_memory) {
#else
ASSERT(total_mem > free_mem);
#endif
ASSERT(available_mem <= free_mem);
return 0;
}

0 comments on commit e6f0e49

Please sign in to comment.