LibGTop Reference Manual
************************

CPU Usage
=========

Library function glibtop_get_cpu:

     void glibtop_get_cpu (glibtop_cpu *buf);
     void glibtop_get_cpu_l (glibtop *server, glibtop_cpu *buf);

Declaration of glibtop_cpu in <glibtop/cpu.h>:

     typedef struct _glibtop_cpu     glibtop_cpu;

     struct _glibtop_cpu
     {
         u_int64_t   flags,
             total,
             user,
             nice,
             sys,
             idle,
             frequency,
             xcpu_total [GLIBTOP_NCPU],
             xcpu_user [GLIBTOP_NCPU],
             xcpu_nice [GLIBTOP_NCPU],
             xcpu_sys  [GLIBTOP_NCPU],
             xcpu_idle [GLIBTOP_NCPU],
             xcpu_flags;
     };

All CPU units are measured in jiffies which are normally 1/100th of a second (in which case frequency equals 100), but can also be in any other unit. To get seconds, divide them by frequency.

total
     Number of clock ticks since system boot.

user
     Number of clock ticks the system spent in user mode.

nice
     Number of clock ticks the system spent in user mode (nice).

sys
     Number of clock ticks the system spent in system mode.

idle
     Number of clock ticks the system spent in the idle task.

frequency
     Tick frequency (default is 100).

The xcpu_ values are for SMP systems - they are the same than total, user, nice, sys and idle except that they are arrays of GLIBTOP_NCPU (defined in <glibtop/limits.h>) elements and contain one value for each CPU in the system.

xcpu_flags
     This is interpreted as a bit-field: on systems like Solaris, not all CPUs need to be running all the time, so we set the corresponding bit for each CPU that is currently running.

Please note that all of the cpu values are absolute values measured in certain units (to get seconds, divide them by frequency) since system boot. To get percentual values, you need to call glibtop_cpu, save the result, wait some time and then call it again and divide the differences of the two values by the time you have waited.

Memory Usage
============

Library function glibtop_get_mem:

     void glibtop_get_mem (glibtop_mem *buf);
     void glibtop_get_mem_l (glibtop *server, glibtop_mem *buf);

Declaration of glibtop_mem in <glibtop/mem.h>:

     typedef struct _glibtop_mem     glibtop_mem;

     struct _glibtop_mem
     {
         u_int64_t   flags,
             total,
             used,
             free,
             shared,
             buffer,
             cached,
             user,
             locked;
     };

Unless explicitly stated otherwise, all memory units are in bytes.

total
     Total physical memory.

used
     Used memory size.

free
     Free memory size.

shared
     Shared memory size.

     This are both segments that are mmap()ed with MAP_SHARED and IPC Shared Memory segments.

buffer
     Size of buffers.

cached
     Size of cached memory.

user
     Memory used from user processes.

     This is normally total - free - shared - buffer.

locked
     Memory in locked segments.

Swap Usage
==========

Library function glibtop_get_swap:

     void glibtop_get_swap (glibtop_swap *buf);
     void glibtop_get_swap_l (glibtop *server, glibtop_swap *buf);

Declaration of glibtop_swap in <glibtop/swap.h>:

     typedef struct _glibtop_swap    glibtop_swap;

     struct _glibtop_swap
     {
         u_int64_t   flags,
             total,
             used,
             free,
             pagein,
             pageout;
     };

The following units are in bytes.

total
     Total swap space in the system.

used
     Used swap space.

free
     Free swap space.

You can use pagein and pageout to get some measure about how much the system is swapping at the moment. They're increased each time a page is swapped in or out, so you need to save this values, wait a little bit, get them again and then compare the two results to find out how much the system swapped in the meantime.

pagein
     Total number of swap pages that have been brought in since system boot

pageout
     Total number of swap pages that have been brought out since system boot

Uptime
======

Library function glibtop_get_uptime:

     void glibtop_get_uptime (glibtop_uptime *buf);
     void glibtop_get_uptime_l (glibtop *server, glibtop_uptime *buf);

Declaration of glibtop_uptime in <glibtop/uptime.h>:

     typedef struct _glibtop_uptime  glibtop_uptime;

     struct _glibtop_uptime
     {
         u_int64_t flags;
         double uptime,
             idletime;
         u_int64_t boot_time;
     };

When porting LibGTop to a new system, you only need to implement uptime and idletime if there's a faster or better way to obtain them as using glibtop_cpu for it. Look at sysdeps/freebsd/uptime.c for an example on how to obtain them using glibtop_cpu.

uptime
     Time in seconds since system boot.

idletime
     Time in seconds the system spent in the idle task since system boot.

The following one was from a request on the linux-kernel mailing list; on a laptop with advanced power management glibtop_cpu.total may not reflect the correct boot time of the system if the power was turned off by means of APM in the meantime.

boot_time
     Time of last system boot in seconds since the epoch.

Load Average
============

Library function glibtop_get_loadavg:

     void glibtop_get_loadavg (glibtop_loadavg *buf);
     void glibtop_get_loadavg_l (glibtop *server, glibtop_loadavg *buf);

Declaration of glibtop_loadavg in <glibtop/loadavg.h>:

     typedef struct _glibtop_loadavg glibtop_loadavg;

     struct _glibtop_loadavg
     {
         u_int64_t flags;
         double loadavg [3];
         u_int64_t nr_running,
             nr_tasks,
             last_pid;
     };

loadavg

     Number of jobs running simultaneously averaged over 1, 5 and 15 minutes.

The following fields are Linux specific and deprecated. You don't need to implement them when porting LibGTop to a new system as they may be removed in a future version.

nr_running
     Number of tasks currently running.

nr_tasks
     Total number of tasks.

last_pid
     Last PID.

Process List
============

Library function glibtop_get_proclist:

     unsigned *
     glibtop_get_proclist (glibtop_proclist *buf,
                           int64_t which, int64_t arg);

     unsigned *
     glibtop_get_proclist_l (glibtop *server, glibtop_proclist *buf,
                             int64_t which, int64_t arg);

Constants for the which argument:

     #define GLIBTOP_KERN_PROC_ALL           0
     #define GLIBTOP_KERN_PROC_PID           1
     #define GLIBTOP_KERN_PROC_PGRP          2
     #define GLIBTOP_KERN_PROC_SESSION       3
     #define GLIBTOP_KERN_PROC_TTY           4
     #define GLIBTOP_KERN_PROC_UID           5
     #define GLIBTOP_KERN_PROC_RUID          6

     #define GLIBTOP_KERN_PROC_MASK          15

     #define GLIBTOP_EXCLUDE_IDLE            0x1000
     #define GLIBTOP_EXCLUDE_SYSTEM          0x2000
     #define GLIBTOP_EXCLUDE_NOTTY           0x4000

Declaration of glibtop_proclist in <glibtop/proclist.h>:

     typedef struct _glibtop_proclist        glibtop_proclist;

     struct _glibtop_proclist
     {
         u_int64_t   flags,
             number,
             total,
             size;
     };

This function returns a list of all or a selected subset of all running processes. You can use the which and arg arguments to specify which processes should be returned.

You can use the following values for the which argument:

GLIBTOP_KERN_PROC_ALL
     Return information about all processes (the arg argument is ignored).

GLIBTOP_KERN_PROC_PID
     Return information about all process with the pid PID which is passed in arg. You can use this to find out whether some process still exists.

GLIBTOP_KERN_PROC_PGRP
     Return all processes in process group PGRP which is passed in arg.

GLIBTOP_KERN_PROC_SESSION
     Return all processes in session SESSION which is passed in arg.

GLIBTOP_KERN_PROC_TTY
     Return all processes which have the controlling tty TTY which is passed in arg (TTY is interpreted as device number).

GLIBTOP_KERN_PROC_UID
     Return all processes with effective uid UID which is passed in arg.

GLIBTOP_KERN_PROC_RUID
     Return all processes with real uid RUID which is passed in arg.

You can alter the list of returned processes by using a binary OR of which and the following constants:

GLIBTOP_EXCLUDE_IDLE
     Exclude idle processes.

GLIBTOP_EXCLUDE_SYSTEM
     Exclude system processes.

GLIBTOP_EXCLUDE_NOTTY
     Exclude processes without a controlling terminal.

The return value of glibtop_get_proclist is either NULL on error or a unsigned * list of pids. Additionally, the following fields of glibtop_proclist are set:

number
     Number of entries in the returned list.

total
     Total size of the returned list (this equals number * size).

size
     Size of a single entry in the returned list (this equals sizeof (unsigned)).

The returned list is allocated using glibtop_malloc and must be freed using glibtop_free to avoid a memory leak.

Process State
=============

Library function glibtop_get_proc_state:

     void
     glibtop_get_proc_state (glibtop_proc_state *buf, pid_t pid);

     void
     glibtop_get_proc_state_l (glibtop *server, glibtop_proc_state *buf,
                               pid_t pid);

Declaration of glibtop_proc_state in <glibtop/proc_state.h>:

     typedef struct _glibtop_proc_state      glibtop_proc_state;

     struct _glibtop_proc_state
     {
         u_int64_t flags;
         char cmd[40];
         unsigned state;
         int uid,
             gid,
             ruid,
             rgid;
         int has_cpu,
             processor,
             last_processor;

     };

cmd
     Basename of the executable file in the call to exec.

state
     Process state (see the constants defined below).

When porting LibGTop, please try hard to implement the following fields. For security reasons, it is very important that you only set the flags bits for those fields if their values are correct.

uid
     Effective UID of the process.

gid
     Effective GID of the process.

ruid
     Real UID of the process.

rgid
     Read GID of the process.

The following fields are for SMP systems:

has_cpu
     This is either 0 or 1 depending on whether the process currently has a CPU or not.

processor
     This is the processor id of the CPU this process is currently running on (which can be used as index in the xcpu_ fields of glibtop_cpu for instance; since zero is a valid processor id, you must check has_cpu in this case to find out whether the process really has a CPU).

last_processor
     The is the processor id of the CPU the process was last running on.

There are some constants for the state field:

     #define GLIBTOP_PROCESS_RUNNING                 1
     #define GLIBTOP_PROCESS_INTERRUPTIBLE           2
     #define GLIBTOP_PROCESS_UNINTERRUPTIBLE         4
     #define GLIBTOP_PROCESS_ZOMBIE                  8
     #define GLIBTOP_PROCESS_STOPPED                 16
     #define GLIBTOP_PROCESS_SWAPPING                32

GLIBTOP_PROCESS_RUNNING
     The process is currently running.

GLIBTOP_PROCESS_INTERRUPTIBLE
     The process is currently in an interruptible sleep.

GLIBTOP_PROCESS_UNINTERRUPTIBLE
     The process is currently in uninterruptible sleep (the so-called disk sleep).

GLIBTOP_PROCESS_ZOMBIE
     The process is a zombie.

GLIBTOP_PROCESS_STOPPED
     The process is currently stopped (received SIGSTOP or attached to a debugger).

GLIBTOP_PROCESS_SWAPPING
     The process is currently swapping.

Process UID and TTY information
===============================

Library function glibtop_get_proc_uid:

     void
     glibtop_get_proc_uid (glibtop_proc_uid *buf, pid_t pid);

     void
     glibtop_get_proc_uid_l (glibtop *server, glibtop_proc_uid *buf,
                             pid_t pid);

Declaration of glibtop_proc_uid in <glibtop/procuid.h>:

     typedef struct _glibtop_proc_uid        glibtop_proc_uid;

     struct _glibtop_proc_uid
     {
         u_int64_t flags;
         int uid,
             euid,
             gid,
             egid,
             suid,
             sgid,
             fsuid,
             fsgid,
             pid,
             ppid,
             pgrp,
             session,
             tty,
             tpgid,
             priority,
             nice,
             ngroups,
             groups [GLIBTOP_MAX_GROUPS];
     };

uid
     User ID

euid
     Effective User ID

gid
     Group ID

egid
     Effective Group ID

pid
     Process ID

ppid
     PID of parent process

pgrp
     Process group ID

session
     Session ID

tty
     Full device number of controlling terminal

tpgid
     Terminal process group ID

priority
     Kernel scheduling priority.

nice
     Standard unix nice level of process.

ngroups
     Number of additional process groups.

groups
     Array of additional process groups

     (GLIBTOP_MAX_GROUPS is defined in <glibtop/limits.h>).

Process Memory information
==========================

Library function glibtop_get_proc_mem:

     void
     glibtop_get_proc_mem (glibtop_proc_mem *buf, pid_t pid);

     void
     glibtop_get_proc_mem_l (glibtop *server, glibtop_proc_mem *buf,
                             pid_t pid);

Declaration of glibtop_proc_mem in <glibtop/procmem.h>:

     typedef struct _glibtop_proc_mem        glibtop_proc_mem;

     struct _glibtop_proc_mem
     {
         u_int64_t   flags,
             size,
             vsize,
             resident,
             share,
             rss,
             rss_rlim;
     };

size
     Total number of pages of memory.

vsize
     Number of pages of virtual memory.

resident
     Number of residnet set (non-swapped) pages.

share
     Number of pages of shared (mmap'd) memory.

rss
     Number of pages the process has in real memory, minus 3 for administrative purposes.

     This is just the pages which count towards text, data, or stack space. This does not include pages which have not been demand-loaded in, or which are swapped out.

rss_rlim
     Current limit in bytes on the rss of the process (usually 2,147,483,647).

The description above is taken from the manual page of the /proc filesystem under Linux and is a little bit confusing, so I make this clear here.

Note for people porting LibGTop to other systems: Every operating system has its own idea about the memory usage of a process and also system utilities like ps show different things on different systems.

Nevertheless, we should try to make LibGTop as system independent as possible, so I give you some hints here how glibtop_get_proc_mem should work.

  * When you use mmap with either MAP_SHARED or MAP_PRIVATE, this should only affect the vsize of the process and none of its size, resident, shared and rss sizes.

  * As soon as you read some of the mmap()ed pages, they will be demand- oaded and thus count towards the size of the process.

     Also - we assume there is enough free memory - they are resident in memory until they get stolen or swapped out and thus increase the resident and rss sizes of the process.

  * If the process has used MAP_SHARED and another process attaches the same file also MAP_SHARED, some of the pages are shared with this process and thus increase the shared sizes of both processes.

  * If the process has used MAP_PRIVATE and writes to the mmap()ed pages, the only difference to reading from them is that they get dirty and cannot be stolen any longer but will get swapped out.

  * When memory gets rare, clean pages are normally stolen, which decreases the size, resident, shared and rss sizes of the process.

  * When dirty pages are swapped out, this will not decrease the size of the process but only its resident and rss sizes (dirty pages cannot be shared).

  * The vsize of a process can only be changed by the process itself when it requests or frees memory but never due to swapping activity of the system.

  * If the shared size changes, this only means that the number of pages that are currently shared with other processes has changed; if this happens, this will never affect any of the other sizes of the process.

The hints above describe how it works under Linux - but we should try to make glibtop_get_proc_mem show the same behavior under every other system.