Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
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);

DESCRIPTION
       sg_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 definition 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 ALSO
       libstatgrab(3)  sg_intro(3)  sg_set_error(3)  sg_comp_init(3)   sg_vec-
       tor_create(3)

WEBSITE
       <https://libstatgrab.org/>

libstatgrab			  2019-10-03		       sg_comp_init(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=sg_global_lock&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help