unix,win: add uv_get_constrained_memory()

Fixes: https://github.com/libuv/libuv/issues/2286
PR-URL: https://github.com/libuv/libuv/pull/2289
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
Kelvin Jin 2019-05-01 13:54:56 -07:00 committed by cjihrig
parent 6602fca820
commit c4e9657d59
No known key found for this signature in database
GPG Key ID: 7434390BDBE9B9C5
13 changed files with 102 additions and 2 deletions

View File

@ -461,6 +461,19 @@ API
Gets memory information (in bytes).
.. c:function:: uint64_t uv_get_constrained_memory(void)
Gets the 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`.
.. note::
This function currently only returns a non-zero value on Linux, based
on cgroups if it is present.
.. versionadded:: 1.29.0
.. c:function:: uint64_t uv_hrtime(void)
Returns the current high-resolution real time. This is expressed in

View File

@ -1561,6 +1561,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_hrtime(void);

View File

@ -344,6 +344,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
perfstat_cpu_total_t ps_total;
int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);

View File

@ -117,6 +117,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);

View File

@ -137,6 +137,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
struct loadavg info;
size_t size = sizeof(info);

View File

@ -183,6 +183,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
SSTS0200 rcvr;

View File

@ -1011,3 +1011,42 @@ uint64_t uv_get_total_memory(void) {
return 0;
}
static uint64_t uv__read_cgroups_uint64(const char* cgroup, const char* param) {
char filename[256];
uint64_t rc;
int fd;
ssize_t n;
char buf[32]; /* Large enough to hold an encoded uint64_t. */
snprintf(filename, 256, "/sys/fs/cgroup/%s/%s", cgroup, param);
rc = 0;
fd = uv__open_cloexec(filename, O_RDONLY);
if (fd < 0)
return 0;
n = read(fd, buf, sizeof(buf) - 1);
if (n > 0) {
buf[n] = '\0';
sscanf(buf, "%llu", &rc);
}
if (uv__close_nocheckstdio(fd))
abort();
return rc;
}
uint64_t uv_get_constrained_memory(void) {
/*
* This might return 0 if there was a problem getting the memory limit from
* cgroups. This is OK because a return value of 0 signifies that the memory
* limit is unknown.
*/
return uv__read_cgroups_uint64("memory", "memory.limit_in_bytes");
}

View File

@ -126,6 +126,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
int uv_resident_set_memory(size_t* rss) {
kvm_t *kd = NULL;
struct kinfo_proc2 *kinfo = NULL;

View File

@ -136,6 +136,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
int uv_resident_set_memory(size_t* rss) {
struct kinfo_proc kinfo;
size_t page_size = getpagesize();

View File

@ -356,6 +356,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
int uv_resident_set_memory(size_t* rss) {
char* ascb;
char* rax;

View File

@ -380,6 +380,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
void uv_loadavg(double avg[3]) {
(void) getloadavg(avg, 3);
}

View File

@ -320,6 +320,11 @@ uint64_t uv_get_total_memory(void) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
}
uv_pid_t uv_os_getpid(void) {
return GetCurrentProcessId();
}

View File

@ -25,10 +25,12 @@
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();
printf("free_mem=%llu, total_mem=%llu\n",
printf("free_mem=%llu, total_mem=%llu, constrained_mem=%llu\n",
(unsigned long long) free_mem,
(unsigned long long) total_mem);
(unsigned long long) total_mem,
(unsigned long long) constrained_mem);
ASSERT(free_mem > 0);
ASSERT(total_mem > 0);