Provided by: libstatgrab-dev_0.92.1-1.1_amd64 bug

NAME

       sg_comp_init,   sg_comp_destroy,   sg_comp_get_tls,   sg_global_lock,  sg_global_unlock  -
       managing system statistics delivery

SYNOPSIS

       #include "tools.h"

       void *get_global_static (unsigned int id);

       sg_error sg_global_lock (void);

       sg_error sg_global_unlock (void);

DESCRIPTION

       sg_comp_init() is called by sg_init() to run the initialisation for the globals  component
       and  each  registered  libstatgrab  component.  This  registration  is  done statically by
       appending a component initialisation information structure (instance-of  sg_comp_info)  to
       the  comp_info  list in src/libstatgrab/globals.c. The instance of sg_comp_info is usually
       defined by using one of EASY_COMP_SETUP() or EXTENDED_COMP_SETUP(), respectively.

       sg_comp_destroy() is  called  by  sg_shutdown()  to  destroy  all  global  resources,  eg.
       translation  tables  for  device names or compiled regular expressions to match path names
       etc. Statistics resources are managed somewhere  else  and  are  freed  (conceptually  and
       usually) before sg_comp_destroy() is invoked.

       sg_comp_get_tls()  is  the  internal function to access the thread local storage (formerly
       static globals) of the component. Usually it's easier to rely on the  encapsulating  macro
       GLOBAL_GET_TLS().

NOTES

       Delivering  system  statistics is the job of libstatgrab, managing the delivery is the job
       of the globals component. To fulfil this job, the components to manage must be prepared:

       1.  declare component's global and TLS data structure (probably  only  on  paper,  not  in
           code)

       2.  define global initialisation, thread destruction and process destruction functions (if
           required by 1.)

       3.  define component information structure using *_COMP_SETUP()

       4.  define component accessors using one or more of

           EASY_COMP_ACCESS()
           EASY_COMP_DIFF()
           MULTI_COMP_ACCESS()
           MULTI_COMP_DIFF()

       When having done these steps, a new component delivering new statistics is born and  needs
       to  be "announced". Assuming the component is named cpu, append the line { &sg_cpu_init, 0
       } to above named comp_info list.

       Component initialisation information in detail:

       typedef sg_error (*comp_global_init_function)(unsigned id);
       typedef void (*comp_global_destroy_function)(void);
       typedef void (*comp_global_cleanup_function)(void *);

       struct sg_comp_status {
               sg_error init_error;
       };

       struct sg_comp_init {
               comp_global_init_function init_fn;
               comp_global_destroy_function destroy_fn;
               comp_global_cleanup_function cleanup_fn;
               size_t static_buf_size;
       #if defined(ENABLE_THREADS) && defined(HAVE_PTHREAD)
               const char **required_locks;
       #endif
               struct sg_comp_status *status;
       };

       Components which do not need something special can rely on EASY_COMP_SETUP():

       Initialising memory component

       EASY_COMP_SETUP(mem,1,NULL);

       When own initialisation is needed, doing it is a bit more complex:

       Initialising network component

       #define SG_NETWORK_IO_NOW_IDX 0
       #define SG_NETWORK_IO_DIFF_IDX     1
       #define SG_NETWORK_IFACE_IDX  2
       #define SG_NETWORK_MAX_IDX    3

       EXTENDED_COMP_SETUP(network,SG_NETWORK_MAX_IDX,NULL);

       #ifdef LINUX
       static regex_t network_io_rx;
       #define RX_MATCH_COUNT (8+1)
       #endif

       sg_error
       sg_network_init_comp(unsigned id) {
               GLOBAL_SET_ID(network,id);

       #ifdef LINUX
               if( regcomp( &network_io_rx, ..., REG_EXTENDED)!=0) {
                       return sg_set_error(SG_ERROR_PARSE, NULL);
               }
       #endif

               return SG_ERROR_NONE;
       }

       void
       sg_network_destroy_comp(void) {
       #ifdef LINUX
               regfree(&network_io_rx);
       #endif
       }

       EASY_COMP_CLEANUP_FN(network,SG_NETWORK_MAX_IDX)

   MACROS TO WORK WITH THE COMPONENT MANAGER
       To simplify working with the component management functions, some preprocessor macros  are
       available. They are shown here as if they were functions to ease understanding.

       void DEFAULT_INIT_COMP (identifier comp, ...);

       void EASY_COMP_SETUP (identifier comp, size_t nvect, ...);

       void EXTENDED_COMP_SETUP (identifier comp, size_t nvect, ...);

       void GLOBAL_SET_ID (identifier comp, unsigned int id);

       struct sg_##comp##_glob *GLOBAL_GET_TLS (identifier comp);

       void EASY_COMP_INIT_FN (identifier comp);

       void EASY_COMP_DESTROY_FN (identifier comp);

       void EASY_COMP_CLEANUP_FN (identifier comp, size_t nvect);

       void EASY_COMP_ACCESS (identifier fn, identifier comp, identifier stat, size_t idx);

       void MULTI_COMP_ACCESS (identifier fn, identifier comp, identifier stat, size_t idx);

       void EASY_COMP_DIFF (identifier fn, identifier getfn, identifier comp, identifier stat,
                           size_t diffidx, size_t nowidx);

       void MULTI_COMP_DIFF (identifier fn, identifier getfn, identifier comp, identifier stat,
                            size_t diffidx, size_t nowidx);

       EASY_COMP_SETUP()  cares  about  anything  to  be  automatically  done for instantiating a
       component information structure for the specified component comp.  The created TLS storage
       structure will hold nvect pointer elements and that's it.  All initialisation, destruction
       and    cleanup-routines    are    created    as    needed    using    EASY_COMP_INIT_FN(),
       EASY_COMP_DESTROY_FN()  and  EASY_COMP_CLEANUP_FN().  After  the amount of required vector
       pointers to be stored the list of required mutexes must be specified, finished with a NULL
       pointer.

       EXTENDED_COMP_SETUP()  cares  about anything to be automatically done for instantiating an
       component information  structure  for  the  specified  component  comp  but  the  required
       definition  of  the  initialisation,  destruction  and  cleanup  routines. The created TLS
       storage structure will hold nvect pointer elements and that's  it.  After  the  amount  of
       required  vector  pointers  to  be stored, the list of required mutexes must be specified,
       finished with a NULL pointer.  All standard routines  can  be  created  semi-automatically
       using EASY_COMP_INIT_FN(), EASY_COMP_DESTROY_FN() and EASY_COMP_CLEANUP_FN().

       DEFAULT_INIT_COMP()  just  declares the prototypes for the initialisation, destruction and
       cleanup routines, defines the initialisation status buffer, lock-names  list  and  finally
       fills the component initialisation structure.  Use this when your TLS storage contains not
       only vector pointers.

       GLOBAL_GET_TLS() returns the pointer to the component's thread local storage.

       GLOBAL_SET_ID() stores the component identifier, required eg. to access its TLS.

       EASY_COMP_INIT_FN() defines a default component  initialisation  routine.  It  stores  the
       component identifier and returns with SG_ERROR_NONE.

       EASY_COMP_DESTROY_FN()  defines  a  default component destructor, called at the end of the
       entire process (or when the last sg_shutdown() is called).  The  default  destructor  does
       nothing   and   usually  an  individual  initialisation  routine  requires  an  individual
       destructor, too.

       EASY_COMP_CLEANUP_FN() defines a default TLS cleanup routine, always called when a  thread
       ends to free vectors held in thread local storage.

       EASY_COMP_ACCESS()  defines  accessors  to  a  specific  statistic  containing one element
       provided by the component: the functions fn() and the fn##_r().   The  following  function
       must exists:
       sg_error  fn##_int  (sg_vector  *name##_vect);  It  accesses  the  vector  idx from TLS of
       component comp and returns sg_##name##_stats.  It manages all standard things like  memory
       and error management, return value etc.

       EASY_COMP_DIFF()  returns  the  difference  between the two statistic collection runs. The
       variant dealing with statgrab owned statistics return the difference between  the  content
       currently  in  the  vector  specified  by  nowidx and the resulting vector of getfn(). The
       result is stored in the vector diffidx. If there is no current result, simply  the  result
       of getfn() is returned.

       MULTI_COMP_ACCESS()  defines  accessors  to  a specific statistic containing 0..n elements
       provided by the component: the functions fn() and the fn##_r().   The  following  function
       must exists:
       sg_error  fn##_int  (sg_vector  **name##_vect);  It  accesses  the  vector idx from TLS of
       component comp and returns sg_##name##_stats.  It manages all standard things like  memory
       and error anagement, return values, entries update, etc.

       MULTI_COMP_DIFF()  does  the  same  as EASY_COMP_DIFF() but for vectors with more than one
       element.

SEE ALSO

       libstatgrab(3) sg_intro(3) sg_set_error(3) sg_comp_init(3) sg_vector_create(3)

WEBSITE

       ⟨https://libstatgrab.org/⟩