Files

204 lines
7.5 KiB
C

#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 */