What Are Process Resources?

 

Chapter 36 Introduction
What Are Process Resources? | EmbeddedPathashala
3
System Calls
2
Topics

What Does This Chapter Cover?

When a program runs on Linux it does not exist in a vacuum. It competes with other processes for CPU time, physical memory, and file descriptors. The operating system needs a way to track what each process has used and, when necessary, stop a process from consuming more than its fair share. Chapter 36 of The Linux Programming Interface gives you the tools to do exactly this from inside your own programs.

The chapter is divided into two major topics that work together:

Topic 1 — Resource Monitoring

The getrusage() system call lets a process ask the kernel: “How much CPU time have I used? How many page faults occurred? How many context switches happened?” This is the measurement side — you are reading usage statistics that the kernel has been accumulating for your process.

Think of it like the fuel gauge and trip computer in a car — you are reading the instrument panel to see what you have already consumed.

int getrusage(int who, struct rusage *res_usage);

Topic 2 — Resource Limiting

The getrlimit() and setrlimit() system calls let a process retrieve and set hard caps on how much of a resource it (and its descendants) may use. Once a limit is set, the kernel enforces it — usually by sending a signal or returning an error.

Think of it like the speed governor on a commercial truck — a hard ceiling that prevents the vehicle from ever going above a certain speed, regardless of what the driver does.

int getrlimit(int resource, struct rlimit *rlim);
int setrlimit(int resource, const struct rlimit *rlim);

Why Does This Matter for Embedded / Systems Engineers?

In desktop applications a process consuming too much memory might just cause the program to crash. In an embedded system or a production server, one runaway process can starve every other process of resources and bring the whole system down.

BLE / IoT Daemons
A BLE stack daemon that leaks file descriptors will eventually hit RLIMIT_NOFILE and fail to accept new connections. Setting and monitoring this limit is essential.
exec’ing Untrusted Code
Before exec’ing a user-supplied binary, a parent process should use setrlimit() to cap CPU time, memory, and file descriptors so the child cannot harm the system.
Performance Profiling
getrusage() tells you exactly how much CPU time and how many page faults your code caused — essential data for optimising embedded firmware running on Linux.
Shell Sandboxing
The shell’s built-in ulimit command uses setrlimit() internally. Understanding the underlying API lets you script and automate resource limits precisely.

System Calls at a Glance

System Call Purpose Header Return
getrusage() Read current resource usage statistics <sys/resource.h> 0 success / -1 error
getrlimit() Read current soft and hard resource limits <sys/resource.h> 0 success / -1 error
setrlimit() Set new soft and/or hard resource limits <sys/resource.h> 0 success / -1 error

Code Example — All Three Calls Together

This small program shows all three system calls working together. It reads the current CPU limit, sets a tighter one, then checks the process’s own CPU usage:

#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>

int main(void)
{
    struct rlimit  lim;
    struct rusage  usage;

    /* ---- Step 1: Read the current CPU time limit ---- */
    if (getrlimit(RLIMIT_CPU, &lim) == -1) {
        perror("getrlimit"); exit(1);
    }
    if (lim.rlim_cur == RLIM_INFINITY)
        printf("Current CPU soft limit : unlimited\n");
    else
        printf("Current CPU soft limit : %lld seconds\n",
               (long long)lim.rlim_cur);

    /* ---- Step 2: Set a new soft CPU limit of 60 seconds ---- */
    lim.rlim_cur = 60;       /* soft: 60 seconds              */
    /* leave lim.rlim_max unchanged (keep the existing hard limit) */
    if (setrlimit(RLIMIT_CPU, &lim) == -1) {
        perror("setrlimit"); exit(1);
    }
    printf("New CPU soft limit set to 60 seconds\n");

    /* ---- Step 3: Read this process's current resource usage ---- */
    if (getrusage(RUSAGE_SELF, &usage) == -1) {
        perror("getrusage"); exit(1);
    }
    printf("User CPU used so far  : %ld.%06ld s\n",
           (long)usage.ru_utime.tv_sec,
           (long)usage.ru_utime.tv_usec);
    printf("Sys  CPU used so far  : %ld.%06ld s\n",
           (long)usage.ru_stime.tv_sec,
           (long)usage.ru_stime.tv_usec);

    return 0;
}

/* Compile: gcc -o ch36_intro ch36_intro.c
   Run:     ./ch36_intro */

Interview Questions — Chapter Introduction

Q1. Name the three resource-related system calls covered in Chapter 36 and state the purpose of each.

getrusage() — reads resource usage statistics (CPU time, page faults, context switches) for the calling process or its children. getrlimit() — reads the current soft and hard limits for a specified resource. setrlimit() — changes the soft and/or hard limits for a specified resource. All three require #include <sys/resource.h>.

Q2. What is the difference between monitoring resource usage and setting resource limits?

Monitoring (getrusage) is passive — you are reading statistics that the kernel has already accumulated. Limiting (setrlimit) is active — you are instructing the kernel to enforce a cap on future consumption. Once a limit is set and the process reaches it, the kernel takes action: it either sends a signal or causes a system call to fail with an error.

Q3. Why would an embedded engineer care about resource limits?

Embedded and real-time Linux systems often run multiple critical daemons on hardware with limited RAM and CPU. A single buggy process that consumes all memory or all file descriptors can starve other critical daemons and crash the system. Resource limits are the mechanism to enforce isolation and prevent such cascading failures. They are also used before exec()-ing untrusted or third-party code.

Q4. How does a shell like bash set resource limits for the programs it runs?

Bash uses the built-in ulimit command, which calls setrlimit() internally. When bash forks a child to run a command, the child inherits the limits that were set in bash. The child cannot raise the limits above what the shell set (unless it is privileged). This inheritance chain is how system administrators deploy resource budgets for user processes.

Leave a Reply

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