RLIMIT_RTTIME Realtime CPU Time in Microseconds: SIGXCPU, SIGKILL, Blocking Syscall Reset

 

36.3 — RLIMIT_RTTIME
Realtime CPU Time in Microseconds: SIGXCPU, SIGKILL, Blocking Syscall Reset | EmbeddedPathashala

What is RLIMIT_RTTIME?

RLIMIT_RTTIME is a Linux-specific limit (since kernel 2.6.25) that sets the maximum amount of CPU time — measured in microseconds — that a process running under a realtime scheduling policy (SCHED_FIFO or SCHED_RR) may consume without sleeping (i.e. without performing a blocking system call).

This limit exists to prevent a runaway realtime process from permanently locking up the system. A process running under SCHED_FIFO at priority 99 that never blocks will prevent all lower-priority processes from ever running. RLIMIT_RTTIME provides a safety valve.

How Enforcement Works

The behaviour mirrors RLIMIT_CPU exactly but uses microseconds and applies only to realtime-scheduled processes:

Soft limit reached → SIGXCPU sent
When the process has consumed CPU time equal to the soft RLIMIT_RTTIME (in microseconds) without sleeping, SIGXCPU is sent. Additional SIGXCPU signals are sent for each additional second of CPU time consumed.
Hard limit reached → SIGKILL sent
If the process continues past the hard limit, SIGKILL is sent unconditionally.
The “blocking syscall reset”: The counter is reset when the process makes a blocking system call (one that puts it to sleep — read(), sleep(), a blocking socket recv(), etc.). This allows a realtime process to run indefinitely as long as it periodically blocks. The limit only fires if the process is spinning continuously without ever yielding.

Code Example — RLIMIT_RTTIME Safety Net

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

static void sigxcpu_handler(int sig) {
    printf("\nSIGXCPU: RT CPU time limit hit! Exiting.\n");
    exit(1);
}

int main(void)
{
    struct rlimit rl;
    struct sched_param sp;

    signal(SIGXCPU, sigxcpu_handler);

    /* Set RLIMIT_RTTIME: soft=500ms, hard=1000ms (in microseconds) */
    rl.rlim_cur = 500000;    /* 500,000 µs = 500 ms soft */
    rl.rlim_max = 1000000;   /* 1,000,000 µs = 1 second hard */
    if (setrlimit(RLIMIT_RTTIME, &rl) == -1) {
        perror("setrlimit RLIMIT_RTTIME"); exit(1);
    }
    printf("RLIMIT_RTTIME: soft=500ms hard=1s\n");

    /* Switch to SCHED_FIFO RT scheduling (requires root) */
    sp.sched_priority = 1;
    if (sched_setscheduler(0, SCHED_FIFO, &sp) == -1) {
        perror("sched_setscheduler (need root)"); exit(1);
    }
    printf("Running SCHED_FIFO — spinning without blocking...\n");

    /* Spin forever without any blocking call — will trigger RLIMIT_RTTIME */
    volatile long i = 0;
    while (1) i++;

    return 0;
}
/* Compile: gcc -o rttime_demo rttime_demo.c
   Run as root: sudo ./rttime_demo
   Without root: sched_setscheduler fails, but setrlimit for RLIMIT_RTTIME
   can still be demonstrated to succeed. */

Interview Questions

Q1. What is the unit for RLIMIT_RTTIME and what scheduling policies does it apply to?

Microseconds. It applies only to processes running under realtime scheduling policies: SCHED_FIFO and SCHED_RR. Normal scheduling policies (SCHED_OTHER, SCHED_BATCH, SCHED_IDLE) are not affected.

Q2. What resets the RLIMIT_RTTIME counter?

Any blocking system call that puts the process to sleep — such as sleep(), nanosleep(), read() on a blocking fd, recv() on a socket with no data, or any other call that causes the scheduler to context-switch away. The counter measures consecutive CPU time without sleeping.

Q3. Why is RLIMIT_RTTIME important for embedded/real-time Linux systems?

A SCHED_FIFO process that never blocks will preempt all lower-priority processes forever. If such a process has a bug or runs away, it can hard-lock the system. RLIMIT_RTTIME is a safety valve: even if the RT process runs wild, the kernel will eventually send it SIGXCPU and SIGKILL, restoring system responsiveness.

Q4. How does RLIMIT_RTTIME differ from RLIMIT_CPU?

RLIMIT_CPU measures total CPU time in seconds and applies to all processes. RLIMIT_RTTIME measures consecutive non-blocking CPU time in microseconds and applies only to realtime-scheduled processes. The enforcement signals (SIGXCPU → SIGKILL) are identical for both.

Leave a Reply

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