#ifndef VLIBC_SYS_RESOURCE_H #define VLIBC_SYS_RESOURCE_H /* * vlibc — . * * Per-process resource limits and usage accounting. Nothing in this header * is POSIX.1-2008 base — getrlimit/setrlimit/getrusage/getpriority/ * setpriority and nice are all XSI [CX] — so the entire surface is gated at * level 2: * * Level 2 (muslmimic): getrlimit, setrlimit, getrusage, getpriority, * setpriority, nice, getrlimit64, setrlimit64, * struct rlimit, struct rusage, rlim_t, RLIMIT_*, * RLIM_INFINITY, PRIO_*, RUSAGE_*. * * struct rusage matches the kernel layout on x86_64 verbatim: two struct * timevals (16 bytes each — the kernel record uses the same two-long * __kernel_old_timeval) followed by fourteen longs, and the kernel * getrusage copies it out without translation. struct rlimit is likewise * the kernel's struct rlimit64 (two 64-bit words), which is why * getrlimit/setrlimit pass the record straight to SYS_prlimit64 and why * getrlimit64/setrlimit64 are name-only aliases on this architecture. * Both shapes are pinned by the static asserts below. * * Every function here performs kernel I/O with side effects and reports * failures through errno, so no declaration carries an intent attribute * (const/pure would be unsound). */ #include #if VLIBC_LEVEL_GE(2) #include /* offsetof */ #include /* struct timeval (shared VLIBC_TIMEVAL_DEFINED guard) */ #include /* id_t */ #ifdef __cplusplus extern "C" { #endif /* * Resource limit values: the 64-bit width of the kernel's rlimit64 record * (unsigned long long on x86_64, where the classic long is also 64-bit but * the LFS spelling is authoritative). */ typedef unsigned long long rlim_t; /* * A resource limit pair: rlim_cur is the soft limit (enforced), rlim_max * the hard limit (ceiling a soft limit may be raised to without * privilege). RLIM_INFINITY in either field means "unlimited". */ struct rlimit { rlim_t rlim_cur; /* soft limit (current) */ rlim_t rlim_max; /* hard limit (ceiling) */ }; /* * Per-process resource usage. The field order is the kernel's own * (getrusage copies the record out untouched): the two CPU-time timevals * first, then the fourteen accounting longs. ru_maxrss is in kilobytes. * The fields a kernel does not maintain stay zero. */ struct rusage { struct timeval ru_utime; /* user CPU time used */ struct timeval ru_stime; /* system CPU time used */ long ru_maxrss; /* maximum resident set size (KiB) */ long ru_ixrss; /* integral shared memory size */ long ru_idrss; /* integral unshared data size */ long ru_isrss; /* integral unshared stack size */ long ru_minflt; /* page reclaims (soft page faults) */ long ru_majflt; /* page faults (hard page faults) */ long ru_nswap; /* swaps */ long ru_inblock; /* block input operations */ long ru_oublock; /* block output operations */ long ru_msgsnd; /* IPC messages sent */ long ru_msgrcv; /* IPC messages received */ long ru_nsignals; /* signals received */ long ru_nvcsw; /* voluntary context switches */ long ru_nivcsw; /* involuntary context switches */ }; /* x86_64 kernel ABI: 2 x struct timeval (16 B) + 14 longs (8 B) = 144 B. */ _Static_assert(sizeof(struct rusage) == 144, "struct rusage must match the x86_64 kernel layout"); _Static_assert(offsetof(struct rusage, ru_maxrss) == 32, "ru_maxrss must follow the two timevals"); _Static_assert(sizeof(struct rlimit) == 2 * sizeof(rlim_t), "struct rlimit is a pair of rlim_t words"); /* ---- Resource limit identifiers (kernel asm-generic values) ---- */ #define RLIMIT_CPU 0 /* CPU time in seconds */ #define RLIMIT_FSIZE 1 /* maximum file size */ #define RLIMIT_DATA 2 /* data segment size */ #define RLIMIT_STACK 3 /* stack size */ #define RLIMIT_CORE 4 /* core file size */ #define RLIMIT_RSS 5 /* resident set size */ #define RLIMIT_NPROC 6 /* number of processes */ #define RLIMIT_NOFILE 7 /* number of open files */ #define RLIMIT_MEMLOCK 8 /* locked-in-memory address space */ #define RLIMIT_AS 9 /* address space size */ #define RLIMIT_LOCKS 10 /* number of file locks held */ #define RLIMIT_SIGPENDING 11 /* number of pending signals */ #define RLIMIT_MSGQUEUE 12 /* bytes in POSIX message queues */ #define RLIMIT_NICE 13 /* ceiling for the nice value */ #define RLIMIT_RTPRIO 14 /* maximum realtime priority */ #define RLIMIT_RTTIME 15 /* realtime CPU time (us) */ #define RLIMIT_NLIMITS 16 /* number of resource kinds */ /* "No limit" value for either field of struct rlimit. */ #define RLIM_INFINITY (~0UL) /* Saved-limit markers (legacy; equal to RLIM_INFINITY on Linux). */ #define RLIM_SAVED_CUR RLIM_INFINITY #define RLIM_SAVED_MAX RLIM_INFINITY /* ---- getpriority/setpriority target selectors ---- */ #define PRIO_PROCESS 0 /* a single process */ #define PRIO_PGRP 1 /* a process group */ #define PRIO_USER 2 /* every process of a user */ /* The valid nice-value range (PRIO_MIN is the highest scheduling priority). */ #define PRIO_MIN (-20) #define PRIO_MAX 19 /* ---- getrusage `who` selectors ---- */ #define RUSAGE_SELF 0 /* the calling process */ #define RUSAGE_CHILDREN (-1) /* terminated and waited-for children */ #define RUSAGE_THREAD 1 /* the calling thread */ /* * Return the current soft and hard limits of resource through rlim. The * call never fails for a valid resource. Return 0, or -1 with errno set * when resource is out of range or rlim points outside the address space. */ int getrlimit(int resource, struct rlimit *rlim); /* * Set the soft and hard limits of resource from rlim. Raising the hard * limit (or the soft limit above the hard limit) requires privilege. * Return 0, or -1 with errno set for an out-of-range resource, a soft * limit above the hard limit, or a denied raise. */ int setrlimit(int resource, const struct rlimit *rlim); /* * Fill usage with the resource usage of who (RUSAGE_SELF, RUSAGE_CHILDREN * or RUSAGE_THREAD). Return 0, or -1 with errno set for an unknown who or * when usage points outside the address space. */ int getrusage(int who, struct rusage *usage); /* * Return the nice value of the target described by (which, who), in the * range PRIO_MIN..PRIO_MAX, or -1 with errno set on error. Because -1 is * also a valid priority, callers conventionally clear errno before the * call and treat a -1 return with a nonzero errno as an error. */ int getpriority(int which, id_t who); /* * Set the nice value of every process named by (which, who) to prio, * clamping out-of-range values to PRIO_MIN..PRIO_MAX. Lowering the value * (raising priority) requires privilege. Return 0, or -1 with errno set. */ int setpriority(int which, id_t who, int prio); /* * Add inc to the calling process's nice value and return the new value, * or -1 with errno set on error (see getpriority for the -1 convention). */ int nice(int inc); /* * Large-file aliases. rlim_t is already 64-bit on x86_64, so these behave * exactly as getrlimit/setrlimit and exist as separate exported symbols for * LFS callers. */ int getrlimit64(int resource, struct rlimit *rlim); int setrlimit64(int resource, const struct rlimit *rlim); #ifdef __cplusplus } #endif #endif /* VLIBC_LEVEL_GE(2) */ #endif /* VLIBC_SYS_RESOURCE_H */