Chapter Summary Process Resources

 

36.4 — Chapter Summary
Process Resources — Key Concepts Consolidated | EmbeddedPathashala

Part 1 — Resource Usage Monitoring (getrusage)

The getrusage() system call lets a process read the resource statistics the kernel has accumulated for it. The who argument selects the target: RUSAGE_SELF for the calling process, RUSAGE_CHILDREN for terminated-and-waited-for descendants, or RUSAGE_THREAD for the calling thread (Linux 2.6.26+, non-portable).

The returned struct rusage has 17 fields. On Linux, 9 are actually populated: ru_utime and ru_stime (CPU time in user and kernel mode), ru_maxrss (peak resident set size, since 2.6.32), ru_minflt and ru_majflt (minor and major page faults), ru_inblock and ru_oublock (block I/O ops, since 2.6.22), and ru_nvcsw and ru_nivcsw (voluntary and involuntary context switches, since 2.6).

RUSAGE_CHILDREN stats are only transferred to the parent when the parent calls wait(). If a child does not wait for its own grandchildren before the parent waits for the child, the grandchild’s stats are permanently lost. For RUSAGE_CHILDREN, ru_maxrss gives the peak RSS across all descendants (maximum, not sum).

Part 2 — Resource Limits (getrlimit / setrlimit)

The getrlimit() and setrlimit() system calls read and modify process resource limits. Each resource has two values in a struct rlimit:

  • rlim_cur (soft limit) — what the kernel enforces at runtime
  • rlim_max (hard limit) — the ceiling for rlim_cur

Privilege rules: An unprivileged process can raise the soft limit up to the hard limit, and can lower the hard limit (irreversibly). Only a privileged process (CAP_SYS_RESOURCE) can raise the hard limit. Both limits are inherited by child processes via fork() and preserved across exec().

RLIM_INFINITY in either field means no limit. The value RLIM_SAVED_CUR/MAX indicates an unrepresentable limit on 32-bit systems with large-file compilation. Always print rlim_t values by casting to long long and using %lld.

The 15 Resource Limits — Quick Reference

Constant Limits On breach Origin
RLIMIT_AS Virtual address space (bytes) ENOMEM SUSv3
RLIMIT_CORE Core dump file size (bytes) File truncated SUSv3
RLIMIT_CPU CPU time (seconds) SIGXCPU → SIGKILL SUSv3
RLIMIT_DATA Data segment (bytes) ENOMEM SUSv3
RLIMIT_FSIZE File size (bytes) SIGXFSZ + EFBIG SUSv3
RLIMIT_MEMLOCK Locked memory (bytes) ENOMEM on mlock BSD
RLIMIT_MSGQUEUE POSIX MQ bytes (per user) ENOMEM on mq_open Linux 2.6.8
RLIMIT_NICE Nice ceiling (20 − rlim_cur) EPERM Linux 2.6.12
RLIMIT_NOFILE Max FD number + 1 EMFILE SUSv3
RLIMIT_NPROC Threads per real UID EAGAIN on fork BSD
RLIMIT_RSS Resident set size NOT enforced BSD
RLIMIT_RTPRIO RT priority ceiling EPERM Linux 2.6.12
RLIMIT_RTTIME RT CPU time (µs, no-sleep) SIGXCPU → SIGKILL Linux 2.6.25
RLIMIT_SIGPENDING Queued signals per UID EAGAIN on sigqueue Linux 2.6.8
RLIMIT_STACK Stack size (bytes) SIGSEGV SUSv3

Key Rules to Remember

Soft limit is what the kernel checks. The hard limit only controls how high the soft limit can be raised. The kernel never directly enforces the hard limit — it is a ceiling for the soft limit.
Unprivileged can only lower hard limit. Lowering the hard limit is irreversible without root/CAP_SYS_RESOURCE. Once lowered, it cannot be raised back.
fork() and exec() both preserve limits. Children inherit parent’s limits. exec() preserves the limits of the calling process. This is how ulimit settings cascade.
NPROC and SIGPENDING are per-user-ID. These limits count against all processes with the same real user ID, not just the process itself.

Leave a Reply

Your email address will not be published. Required fields are marked *