That is why we have 4 functions per module: the join function is called by any
process, and is in charge of creating the process-wide globals. If it is the
first time a process uses the module, it also calls the init function, in
That is why we have 4 functions per module: the join function is called by any
process, and is in charge of creating the process-wide globals. If it is the
first time a process uses the module, it also calls the init function, in
leave, called by any process not using the module anymore, and exit, in charge
of freeing the world-wide globals when no process use it anymore.
leave, called by any process not using the module anymore, and exit, in charge
of freeing the world-wide globals when no process use it anymore.
create process-wide globals. The fact that indeed the calling sequence goes
from join to init and not the other side is just an implementation bias ;)
create process-wide globals. The fact that indeed the calling sequence goes
from join to init and not the other side is just an implementation bias ;)
implementation, where each functions is likely to require them to work. The
position could be a stored in a global variable only visible from the module
implementation, where each functions is likely to require them to work. The
position could be a stored in a global variable only visible from the module
The need for an array in which to store the globals does not hold for
world-wide globals: only one instance of them can exist in the same unix naming
The need for an array in which to store the globals does not hold for
world-wide globals: only one instance of them can exist in the same unix naming
tables. This is why we have the ID field in the module structure: it points
exactly to the implementation side global.
tables. This is why we have the ID field in the module structure: it points
exactly to the implementation side global.
allow modules initializing other modules while tracking dependencies
properly and leave() only when needed. This would allow dynamic module
loading/unloading */
allow modules initializing other modules while tracking dependencies
properly and leave() only when needed. This would allow dynamic module
loading/unloading */
int *p_id; /* where the module stores the libdata ID (a global somewhere), to tweak it on need */
void_f_void_t init_f; /* First time the module is referenced. */
void_f_void_t exit_f; /* When last process referencing it stops doing so. */
int *p_id; /* where the module stores the libdata ID (a global somewhere), to tweak it on need */
void_f_void_t init_f; /* First time the module is referenced. */
void_f_void_t exit_f; /* When last process referencing it stops doing so. */
* @param name: name of the module, of course (beware of dupplicates!)
* @param datasize: the size of your data, ie of the state this module has on each process
* @param ID: address of a global you use as parameter to gras_module_data_by_id
* @param name: name of the module, of course (beware of dupplicates!)
* @param datasize: the size of your data, ie of the state this module has on each process
* @param ID: address of a global you use as parameter to gras_module_data_by_id
* A classical use is to declare some messages the module uses, as well as the initialization
* of module constants (accross processes boundaries in SG).
* @param exit_f: function called when the last process of this naming space unref this module.
* A classical use is to declare some messages the module uses, as well as the initialization
* of module constants (accross processes boundaries in SG).
* @param exit_f: function called when the last process of this naming space unref this module.
* It is passed the moddata already malloced, and should initialize the fields as it wants.
* It can also attach some callbacks to the module messages.
* @param leave_f: function called each time a process unrefs the module.
* It is passed the moddata already malloced, and should initialize the fields as it wants.
* It can also attach some callbacks to the module messages.
* @param leave_f: function called each time a process unrefs the module.
"Module %s reregistered with a different init_f!", name);
xbt_assert1(mod->exit_f == exit_f,
"Module %s reregistered with a different exit_f!", name);
"Module %s reregistered with a different init_f!", name);
xbt_assert1(mod->exit_f == exit_f,
"Module %s reregistered with a different exit_f!", name);
"Module %s reregistered with a different join_f!", name);
xbt_assert1(mod->leave_f == leave_f,
"Module %s reregistered with a different leave_f!", name);
"Module %s reregistered with a different join_f!", name);
xbt_assert1(mod->leave_f == leave_f,
"Module %s reregistered with a different leave_f!", name);
"Module %s reregistered with a different datasize!", name);
xbt_assert1(mod->p_id == ID,
"Module %s reregistered with a different p_id field!", name);
"Module %s reregistered with a different datasize!", name);
xbt_assert1(mod->p_id == ID,
"Module %s reregistered with a different p_id field!", name);
mod = xbt_new(s_gras_module_t, 1);
mod->name = xbt_strdup(name);
mod->name_len = strlen(name);
mod = xbt_new(s_gras_module_t, 1);
mod->name = xbt_strdup(name);
mod->name_len = strlen(name);
/* NEW */
if (mod->refcount == 0) {
VERB1("Init module %s",name);
/* NEW */
if (mod->refcount == 0) {
VERB1("Init module %s",name);