Provided by: libstatgrab-dev_0.92.1-1.2build1_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/⟩