unix: check RLIMIT_AS and RLIMIT_DATA in uv_get_constrained_memory
Add uv__get_rlimit_max_memory() helper that checks RLIMIT_AS and RLIMIT_DATA resource limits across all Unix platforms. This helper returns the minimum of these rlimits if set. Update all Unix platform implementations of uv_get_constrained_memory() to use this helper, ensuring consistent handling of resource limits: - Linux: combine cgroup limits with rlimits - z/OS: combine RLIMIT_MEMLIMIT with rlimits - Other Unix platforms: use rlimits (previously returned 0) This provides a more accurate view of available memory when processes have rlimit constraints in addition to platform-specific limits. Related: https://github.com/JuliaLang/julia/pull/51656 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
74079a8e47
commit
7ffec72cdb
@ -396,7 +396,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2149,3 +2149,30 @@ int uv__sock_reuseport(int fd) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv__get_rlimit_max_memory(void) {
|
||||
struct rlimit rl;
|
||||
uint64_t result = 0;
|
||||
uint64_t rlimit_value;
|
||||
|
||||
#if defined(RLIMIT_AS)
|
||||
/* Check RLIMIT_AS (virtual memory limit). */
|
||||
if (getrlimit(RLIMIT_AS, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) {
|
||||
rlimit_value = rl.rlim_cur;
|
||||
if (result == 0 || rlimit_value < result)
|
||||
result = rlimit_value;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RLIMIT_DATA)
|
||||
/* Check RLIMIT_DATA (data segment limit). */
|
||||
if (getrlimit(RLIMIT_DATA, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) {
|
||||
rlimit_value = rl.rlim_cur;
|
||||
if (result == 0 || rlimit_value < result)
|
||||
result = rlimit_value;
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -85,7 +85,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. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
uint64_t uv_get_available_memory(void) {
|
||||
|
||||
@ -121,7 +121,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -117,7 +117,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -163,7 +163,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. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -245,7 +245,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -377,6 +377,7 @@ int uv__signal_loop_fork(uv_loop_t* loop);
|
||||
|
||||
/* platform specific */
|
||||
uint64_t uv__hrtime(uv_clocktype_t type);
|
||||
uint64_t uv__get_rlimit_max_memory(void);
|
||||
int uv__kqueue_init(uv_loop_t* loop);
|
||||
int uv__platform_loop_init(uv_loop_t* loop);
|
||||
void uv__platform_loop_delete(uv_loop_t* loop);
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/resource.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -2217,11 +2218,21 @@ static uint64_t uv__get_cgroup_constrained_memory(char buf[static 1024]) {
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
char buf[1024];
|
||||
uint64_t cgroup_limit;
|
||||
uint64_t rlimit_limit;
|
||||
|
||||
if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)))
|
||||
return 0;
|
||||
|
||||
return uv__get_cgroup_constrained_memory(buf);
|
||||
cgroup_limit = uv__get_cgroup_constrained_memory(buf);
|
||||
rlimit_limit = uv__get_rlimit_max_memory();
|
||||
|
||||
/* Return the minimum of cgroup and rlimit constraints. */
|
||||
if (cgroup_limit == 0)
|
||||
return rlimit_limit;
|
||||
if (rlimit_limit == 0)
|
||||
return cgroup_limit;
|
||||
return cgroup_limit < rlimit_limit ? cgroup_limit : rlimit_limit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -127,7 +127,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -188,12 +188,23 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
struct rlimit rl;
|
||||
uint64_t memlimit;
|
||||
uint64_t rlimit_limit;
|
||||
|
||||
/* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */
|
||||
if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0)
|
||||
return rl.rlim_cur * 1024 * 1024;
|
||||
memlimit = 0;
|
||||
if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY)
|
||||
memlimit = rl.rlim_cur * 1024 * 1024;
|
||||
|
||||
return 0; /* There is no memory limit set. */
|
||||
/* Also check RLIMIT_AS and RLIMIT_DATA. */
|
||||
rlimit_limit = uv__get_rlimit_max_memory();
|
||||
|
||||
/* Return the minimum of RLIMIT_MEMLIMIT and other rlimits. */
|
||||
if (memlimit == 0)
|
||||
return rlimit_limit;
|
||||
if (rlimit_limit == 0)
|
||||
return memlimit;
|
||||
return memlimit < rlimit_limit ? memlimit : rlimit_limit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -118,7 +118,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0;
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -413,7 +413,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
|
||||
|
||||
uint64_t uv_get_constrained_memory(void) {
|
||||
return 0; /* Memory constraints are unknown. */
|
||||
return uv__get_rlimit_max_memory();
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user