Resource Usage And Limitation
*****************************

This chapter describes functions for examining how much of various kinds of resources (CPU time, memory, etc.) a process has used and getting and setting limits on future usage.

Resource Usage
==============

The function getrusage and the data type struct rusage are used to examine the resource usage of a process.  They are declared in sys/resource.h.

 -- Function: int getrusage (int PROCESSES, struct rusage *RUSAGE)
     This function reports resource usage totals for processes specified by PROCESSES, storing the information in *RUSAGE.

     In most systems, PROCESSES has only two valid values:

     RUSAGE_SELF
          Just the current process.

     RUSAGE_CHILDREN
          All child processes (direct and indirect) that have already terminated.

     In the GNU system, you can also inquire about a particular child process by specifying its process ID.

     The return value of getrusage is zero for success, and -1 for failure.

     EINVAL
          The argument PROCESSES is not valid.

One way of getting resource usage for a particular child process is with the function wait4, which returns totals for a child when it terminates.  See BSD Wait Functions.

 -- Data Type: struct rusage
     This data type stores various resource usage statistics.  It has the following members, and possibly others:

     struct timeval ru_utime
          Time spent executing user instructions.

     struct timeval ru_stime
          Time spent in operating system code on behalf of PROCESSES.

     long int ru_maxrss
          The maximum resident set size used, in kilobytes.  That is, the maximum number of kilobytes of physical memory that PROCESSES used simultaneously.

     long int ru_ixrss
          An integral value expressed in kilobytes times ticks of execution, which indicates the amount of memory used by text that was shared with other processes.

     long int ru_idrss
          An integral value expressed the same way, which is the amount of unshared memory used for data.

     long int ru_isrss
          An integral value expressed the same way, which is the amount of unshared memory used for stack space.

     long int ru_minflt
          The number of page faults which were serviced without requiring any I/O.

     long int ru_majflt
          The number of page faults which were serviced by doing I/O.

     long int ru_nswap
          The number of times PROCESSES was swapped entirely out of main memory.

     long int ru_inblock
          The number of times the file system had to read from the disk on behalf of PROCESSES.

     long int ru_oublock
          The number of times the file system had to write to the disk on behalf of PROCESSES.

     long int ru_msgsnd
          Number of IPC messages sent.

     long int ru_msgrcv
          Number of IPC messages received.

     long int ru_nsignals
          Number of signals received.

     long int ru_nvcsw
          The number of times PROCESSES voluntarily invoked a context switch (usually to wait for some service).

     long int ru_nivcsw
          The number of times an involuntary context switch took place (because a time slice expired, or another process of higher priority was scheduled).

vtimes is a historical function that does some of what getrusage does.  getrusage is a better choice.

vtimes and its vtimes data structure are declared in sys/vtimes.h.

 -- Function: int vtimes (struct vtimes CURRENT, struct vtimes CHILD)

     vtimes reports resource usage totals for a process.

     If CURRENT is non-null, vtimes stores resource usage totals for the invoking process alone in the structure to which it points.  If CHILD is non-null, vtimes stores resource usage totals for all past children (which have terminated) of the invoking process in the structure to which it points.

      -- Data Type: struct vtimes
          This data type contains information about the resource usage of a process. Each member corresponds to a member of the struct rusage data type described above.

          vm_utime
               User CPU time.  Analogous to ru_utime in struct rusage

          vm_stime
               System CPU time.  Analogous to ru_stime in struct rusage

          vm_idsrss
               Data and stack memory.  The sum of the values that would be reported as ru_idrss and ru_isrss in struct rusage

          vm_ixrss
               Shared memory.  Analogous to ru_ixrss in struct rusage

          vm_maxrss
               Maximent resident set size.  Analogous to ru_maxrss in struct rusage

          vm_majflt
               Major page faults.  Analogous to ru_majflt in struct rusage

          vm_minflt
               Minor page faults.  Analogous to ru_minflt in struct rusage

          vm_nswap
               Swap count.  Analogous to ru_nswap in struct rusage

          vm_inblk
               Disk reads.  Analogous to ru_inblk in struct rusage

          vm_oublk
               Disk writes.  Analogous to ru_oublk in struct rusage

     The return value is zero if the function succeeds; -1 otherwise.

An additional historical function for examining resource usage, vtimes, is supported but not documented here.  It is declared in sys/vtimes.h.

Limiting Resource Usage
=======================

You can specify limits for the resource usage of a process.  When the process tries to exceed a limit, it may get a signal, or the system call by which it tried to do so may fail, depending on the resource.  Each process initially inherits its limit values from its parent, but it can subsequently change them.

There are two per-process limits associated with a resource:

current limit
     The current limit is the value the system will not allow usage to exceed.  It is also called the ``soft limit'' because the process being limited can generally raise the current limit at will.

maximum limit
     The maximum limit is the maximum value to which a process is allowed to set its current limit.  It is also called the ``hard limit'' because there is no way for a process to get around it.  A process may lower its own maximum limit, but only the superuser may increase a maximum limit.

The symbols for use with getrlimit, setrlimit, getrlimit64, and seterlimit64 are defined in sys/resource.h.

 -- Function: int getrlimit (int RESOURCE, struct rlimit *RLP)
     Read the current and maximum limits for the resource RESOURCE and store them in *RLP.

     The return value is 0 on success and -1 on failure.  The only possible errno error condition is EFAULT.

     When the sources are compiled with _FILE_OFFSET_BITS == 64 on a 32-bit system this function is in fact getrlimit64.  Thus, the LFS interface transparently replaces the old interface.

 -- Function: int getrlimit64 (int RESOURCE, struct rlimit64 *RLP)
     This function is similar to getrlimit but its second parameter is a pointer to a variable of type struct rlimit64, which allows it to read values which wouldn't fit in the member of a struct rlimit.

     If the sources are compiled with _FILE_OFFSET_BITS == 64 on a 32-bit machine, this function is available under the name getrlimit and so transparently replaces the old interface.

 -- Function: int setrlimit (int RESOURCE, const struct rlimit *RLP)
     Store the current and maximum limits for the resource RESOURCE in *RLP.

     The return value is 0 on success and -1 on failure.  The following errno error condition is possible:

     EPERM

            * The process tried to raise a current limit beyond the maximum limit.

            * The process tried to raise a maximum limit, but is not superuser.

     When the sources are compiled with _FILE_OFFSET_BITS == 64 on a 32-bit system this function is in fact setrlimit64.  Thus, the LFS interface transparently replaces the old interface.

 -- Function: int setrlimit64 (int RESOURCE, const struct rlimit64 *RLP)
     This function is similar to setrlimit but its second parameter is a pointer to a variable of type struct rlimit64 which allows it to set values which wouldn't fit in the member of a struct rlimit.

     If the sources are compiled with _FILE_OFFSET_BITS == 64 on a 32-bit machine this function is available under the name setrlimit and so transparently replaces the old interface.

 -- Data Type: struct rlimit
     This structure is used with getrlimit to receive limit values, and with setrlimit to specify limit values for a particular process and resource.  It has two fields:

     rlim_t rlim_cur
          The current limit

     rlim_t rlim_max
          The maximum limit.

     For getrlimit, the structure is an output; it receives the current values.  For setrlimit, it specifies the new values.

For the LFS functions a similar type is defined in sys/resource.h.

 -- Data Type: struct rlimit64
     This structure is analogous to the rlimit structure above, but its components have wider ranges.  It has two fields:

     rlim64_t rlim_cur
          This is analogous to rlimit.rlim_cur, but with a different type.

     rlim64_t rlim_max
          This is analogous to rlimit.rlim_max, but with a different type.

Here is a list of resources for which you can specify a limit.  Memory and file sizes are measured in bytes.

RLIMIT_CPU
     The maximum amount of CPU time the process can use.  If it runs for longer than this, it gets a signal: SIGXCPU.  The value is measured in seconds.  See Operation Error Signals.

RLIMIT_FSIZE
     The maximum size of file the process can create.  Trying to write a larger file causes a signal: SIGXFSZ.  See Operation Error Signals.

RLIMIT_DATA
     The maximum size of data memory for the process.  If the process tries to allocate data memory beyond this amount, the allocation function fails.

RLIMIT_STACK
     The maximum stack size for the process.  If the process tries to extend its stack past this size, it gets a SIGSEGV signal. See Program Error Signals.

RLIMIT_CORE
     The maximum size core file that this process can create.  If the process terminates and would dump a core file larger than this, then no core file is created.  So setting this limit to zero prevents core files from ever being created.

RLIMIT_RSS
     The maximum amount of physical memory that this process should get. This parameter is a guide for the system's scheduler and memory allocator; the system may give the process more memory when there is a surplus.

RLIMIT_MEMLOCK
     The maximum amount of memory that can be locked into physical memory (so it will never be paged out).

RLIMIT_NPROC
     The maximum number of processes that can be created with the same user ID. If you have reached the limit for your user ID, fork will fail with EAGAIN.  See Creating a Process.

RLIMIT_NOFILE
RLIMIT_OFILE
     The maximum number of files that the process can open.  If it tries to open more files than this, its open attempt fails with errno EMFILE.  See Error Codes.  Not all systems support this limit; GNU does, and 4.4 BSD does.

RLIMIT_AS
     The maximum size of total memory that this process should get.  If the process tries to allocate more memory beyond this amount with, for example, brk, malloc, mmap or sbrk, the allocation function fails.

RLIM_NLIMITS
     The number of different resource limits.  Any valid RESOURCE operand must be less than RLIM_NLIMITS.

 -- Constant: int RLIM_INFINITY
     This constant stands for a value of ``infinity'' when supplied as the limit value in setrlimit.

The following are historical functions to do some of what the functions above do.  The functions above are better choices.

ulimit and the command symbols are declared in ulimit.h.

 -- Function: int ulimit (int CMD, ...)

     ulimit gets the current limit or sets the current and maximum limit for a particular resource for the calling process according to the command CMD.a

     If you are getting a limit, the command argument is the only argument. If you are setting a limit, there is a second argument: long int LIMIT which is the value to which you are setting the limit.

     The CMD values and the operations they specify are:

     GETFSIZE
          Get the current limit on the size of a file, in units of 512 bytes.

     SETFSIZE
          Set the current and maximum limit on the size of a file to LIMIT * 512 bytes.

     There are also some other CMD values that may do things on some systems, but they are not supported.

     Only the superuser may increase a maximum limit.

     When you successfully get a limit, the return value of ulimit is that limit, which is never negative.  When you successfully set a limit, the return value is zero.  When the function fails, the return value is -1 and errno is set according to the reason:

     EPERM
          A process tried to increase a maximum limit, but is not superuser.

vlimit and its resource symbols are declared in sys/vlimit.h.

 -- Function: int vlimit (int RESOURCE, int LIMIT)

     vlimit sets the current limit for a resource for a process.

     RESOURCE identifies the resource:

     LIM_CPU
          Maximum CPU time.  Same as RLIMIT_CPU for setrlimit.

     LIM_FSIZE
          Maximum file size.  Same as RLIMIT_FSIZE for setrlimit.

     LIM_DATA
          Maximum data memory.  Same as RLIMIT_DATA for setrlimit.

     LIM_STACK
          Maximum stack size.  Same as RLIMIT_STACK for setrlimit.

     LIM_CORE
          Maximum core file size.  Same as RLIMIT_COR for setrlimit.

     LIM_MAXRSS
          Maximum physical memory.  Same as RLIMIT_RSS for setrlimit.

     The return value is zero for success, and -1 with errno set accordingly for failure:

     EPERM
          The process tried to set its current limit beyond its maximum limit.

Process Priority
================

When several processes try to run, their respective priorities determine what share of the CPU each process gets.  This section describes how you can read and set the priority of a process.  All these functions and macros are declared in sys/resource.h.

The range of valid priority values depends on the operating system, but typically it runs from -20 to 20.  A lower priority value means the process runs more often.  These constants describe the range of priority values:

PRIO_MIN
     The smallest valid priority value.

PRIO_MAX
     The largest valid priority value.

 -- Function: int getpriority (int CLASS, int ID)
     Read the priority of a class of processes; CLASS and ID specify which ones (see below).  If the processes specified do not all have the same priority, this returns the smallest value that any of them has.

     The return value is the priority value on success, and -1 on failure.  The following errno error condition are possible for this function:

     ESRCH
          The combination of CLASS and ID does not match any existing process.

     EINVAL
          The value of CLASS is not valid.

     If the return value is -1, it could indicate failure, or it could be the priority value.  The only way to make certain is to set errno = 0 before calling getpriority, then use errno != 0 afterward as the criterion for failure.

 -- Function: int setpriority (int CLASS, int ID, int PRIORITY)
     Set the priority of a class of processes to PRIORITY; CLASS and ID specify which ones (see below).

     The return value is 0 on success and -1 on failure.  The following errno error condition are defined for this function:

     ESRCH
          The combination of CLASS and ID does not match any existing process.

     EINVAL
          The value of CLASS is not valid.

     EPERM
          You tried to set the priority of some other user's process, and you don't have privileges for that.

     EACCES
          You tried to lower the priority of a process, and you don't have privileges for that.

The arguments CLASS and ID together specify a set of processes in which you are interested.  These are the possible values of CLASS:

PRIO_PROCESS
     Read or set the priority of one process.  The argument ID is a process ID.

PRIO_PGRP
     Read or set the priority of one process group.  The argument ID is a process group ID.

PRIO_USER
     Read or set the priority of one user's processes.  The argument ID is a user ID.

If the argument ID is 0, it stands for the current process, current process group, or the current user, according to CLASS.

 -- Function: int nice (int INCREMENT)
     Increment the priority of the current process by INCREMENT. The return value is the same as for setpriority.

     Here is an equivalent definition of nice:

          int
          nice (int increment)
          {
            int old = getpriority (PRIO_PROCESS, 0);
            return setpriority (PRIO_PROCESS, 0, old + increment);
          }