sg_comp_init(3)sg_comp_init(3)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);
DESCRIPTIONsg_comp_init() is called by sg_init() to run the initialisation for the
globals component and each registered libstatgrab component. This reg‐
istration 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(), re‐
spectively.
sg_comp_destroy() is called by sg_shutdown() to destroy all global re‐
sources, 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 de‐
struction 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 pre‐
processor 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 in‐
stantiating a component information structure for the specified compo‐
nent 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_DE‐
STROY_FN() and EASY_COMP_CLEANUP_FN(). After the amount of required
vector pointers to be stored the list of required mutexes must be spec‐
ified, finished with a NULL pointer.
EXTENDED_COMP_SETUP() cares about anything to be automatically done for
instantiating an component information structure for the specified com‐
ponent comp but the required defintion of the initialisation, destruc‐
tion and cleanup routines. The created TLS storage structure will hold
nvect pointer elements and that's it. After the amount of required vec‐
tor pointers to be stored, the list of required mutexes must be speci‐
fied, finished with a NULL pointer. All standard routines can be cre‐
ated semi-automatically using EASY_COMP_INIT_FN(), EASY_COMP_DE‐
STROY_FN() and EASY_COMP_CLEANUP_FN().
DEFAULT_INIT_COMP() just declares the prototypes for the initialisa‐
tion, destruction and cleanup routines, defines the initialisation sta‐
tus buffer, lock-names list and finally fills the component initialisa‐
tion structure. Use this when your TLS storage contains not only vec‐
tor 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 col‐
lection 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 contain‐
ing 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, en‐
tries update, etc.
MULTI_COMP_DIFF() does the same as EASY_COMP_DIFF() but for vectors
with more than one element.
SEE ALSOlibstatgrab(3)sg_intro(3)sg_set_error(3)sg_comp_init(3) sg_vec‐
tor_create(3)WEBSITE
⟨http://www.i-scream.org/libstatgrab/⟩
i-scream 2013-06-07 sg_comp_init(3)