feat(resource): rlimit/rusage/priority
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
#ifndef VLIBC_SYS_RESOURCE_H
|
||||
#define VLIBC_SYS_RESOURCE_H
|
||||
|
||||
/*
|
||||
* vlibc — <sys/resource.h>.
|
||||
*
|
||||
* 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 <vlibc/features.h>
|
||||
|
||||
#if VLIBC_LEVEL_GE(2)
|
||||
|
||||
#include <stddef.h> /* offsetof */
|
||||
|
||||
#include <sys/time.h> /* struct timeval (shared VLIBC_TIMEVAL_DEFINED guard) */
|
||||
|
||||
#include <sys/types.h> /* 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 */
|
||||
Reference in New Issue
Block a user