diff --git a/data/models/dimers random walk.xml b/data/models/dimers random walk.xml index 12ae465..277f9ef 100644 --- a/data/models/dimers random walk.xml +++ b/data/models/dimers random walk.xml @@ -34,7 +34,7 @@ - 3 + 2 @@ -75,19 +75,19 @@ - - + + - + + and the dimer identified by conditions (0,1) can be moved to East. --> - + + and the dimer identified by conditions (0,1) can be moved to West. --> diff --git a/data/models/dimers_random_walk_recursif.xml b/data/models/dimers_random_walk_recursif.xml index 0bd387c..976512c 100644 --- a/data/models/dimers_random_walk_recursif.xml +++ b/data/models/dimers_random_walk_recursif.xml @@ -34,7 +34,7 @@ - 3 + 2 diff --git a/include/model.h b/include/model.h index fc1ebd7..1056233 100644 --- a/include/model.h +++ b/include/model.h @@ -76,17 +76,17 @@ struct space_t struct state_t { // Metadata - int id; + char id[25]; int owner_id; time_t date; struct space_t *space; }; -struct model_t { - +struct model_t +{ // Metadata - int id; + char id; int owner_id; time_t date; union version @@ -96,12 +96,13 @@ struct model_t { }; // XML handlers - xmlDocPtr model; - xmlHashTablePtr model_hashtable; + xmlDocPtr doc; + xmlHashTablePtr hashtable; // User friendly metadata char *owner_name; char *model_name; + char *filename; // Model parameters int multiplicity; // number of sites in a space_unit @@ -114,14 +115,26 @@ struct model_t { // Handler to the current space of the model struct space_t *space; - // Handler to the saved states of the model - struct state_t **states; + // Handler to the arrows + struct arrow_t *arrows; + size_t n_arrows; + + // Handler to the saved states array + struct state_t *states; + size_t n_states; +}; + + +struct model_array_t +{ + struct model_t *models; + size_t size; }; // -------------------------------------------------------------------------- // // Model init function (and model discovery) // // -------------------------------------------------------------------------- // -// void model_system_init (parameters_t *parameters); +void model_system_init (struct parameters_t *parameters); // -------------------------------------------------------------------------- // // Model stopping function // @@ -131,20 +144,13 @@ struct model_t { // -------------------------------------------------------------------------- // // Load a model ready to execute // // -------------------------------------------------------------------------- // -// int model_load (int id); - -bool model_init(struct model_t *self, - const char *content, - size_t length, - const char *basename); +bool model_load (struct model_t *self); // -------------------------------------------------------------------------- // // Unload a model // // -------------------------------------------------------------------------- // // int model_unload (int id); -bool model_shutdown(struct model_t *self); - // -------------------------------------------------------------------------- // // Add a model to the known model list // // -------------------------------------------------------------------------- // diff --git a/src/main.c b/src/main.c index 3bd8ad7..05743ea 100644 --- a/src/main.c +++ b/src/main.c @@ -114,12 +114,12 @@ int main(int argc, char **argv) // Initializing random generator t = time(&t); - srand((unsigned)t); + srand ((unsigned)t); /* server = calloc(1, sizeof(*server)); */ - /* // Initializing model system */ - /* model_system_init(¶meters); */ + // Initializing model system + model_system_init (¶meters); /* // Launching server */ /* server_init(server); */ diff --git a/src/model.c b/src/model.c index 06b8f80..b631363 100644 --- a/src/model.c +++ b/src/model.c @@ -35,10 +35,11 @@ /* -------------------------------------------------------------------------- */ -bool model_init(struct model_t *self, - const char *content, - size_t length, - const char *basename) +struct model_array_t *knownModels; + +/* -------------------------------------------------------------------------- */ + +static bool model_init(struct model_t *self) { xmlNode *node; @@ -49,41 +50,42 @@ bool model_init(struct model_t *self, */ LIBXML_TEST_VERSION - self->model = xmlReadMemory(content, length, basename, NULL, 0); + self->doc = xmlReadFile(self->filename, NULL, 0); - if (self->model == NULL ) { + if (self->doc == NULL ) { + printerr("Error trying to open the XML model !\n"); return false; } - node = xmlDocGetRootElement(self->model); + node = xmlDocGetRootElement(self->doc); if (node == NULL) { - fprintf(stderr, "Empty XML model !\n"); - xmlFreeDoc(self->model); + printerr("Empty XML model !\n"); + xmlFreeDoc(self->doc); return false; } if (xmlStrcmp(node->name, (xmlChar *) "gem-graph-model")) { - fprintf(stderr, "document of the wrong type, root node != gem-graph-model\n"); - xmlFreeDoc(self->model); + printerr("document of the wrong type, root node != gem-graph-model\n"); + xmlFreeDoc(self->doc); return false; } - self->model_hashtable = xmlHashCreate(0); + self->hashtable = xmlHashCreate(0); - if (self->model_hashtable == NULL) { - fprintf(stderr, "Can't create model hash table !\n"); - xmlFreeDoc(self->model); + if (self->hashtable == NULL) { + printerr("Can't create model hash table !\n"); + xmlFreeDoc(self->doc); return false; } return true; } -bool model_shutdown(struct model_t *self) +static bool model_shutdown(struct model_t *self) { - xmlFreeDoc(self->model); - xmlHashFree(self->model_hashtable, NULL); + xmlFreeDoc(self->doc); + xmlHashFree(self->hashtable, NULL); // Cleanup function for the XML library xmlCleanupParser(); @@ -139,7 +141,7 @@ static xmlNodePtr model_get_node(struct model_t *self, xmlChar *path) xmlChar *reste, *last, *affich; // Lookup for node from path in hash table - node = xmlHashLookup(self->model_hashtable, path); + node = xmlHashLookup(self->hashtable, path); // Found a node in hash table if (node) { @@ -150,7 +152,7 @@ static xmlNodePtr model_get_node(struct model_t *self, xmlChar *path) reste = path; affich = reste; last = getLastTag(reste); - node = xmlDocGetRootElement(self->model); + node = xmlDocGetRootElement(self->doc); while (xmlStrchr (reste, '/')) { extrait = getFirstTag(reste); @@ -165,7 +167,7 @@ static xmlNodePtr model_get_node(struct model_t *self, xmlChar *path) while (node && xmlStrcmp(node->name, last)) { node = node->next; } - xmlHashAddEntry (self->model_hashtable, path, node); + xmlHashAddEntry (self->hashtable, path, node); } return node; @@ -473,4 +475,138 @@ bool model_get_next_arrow(struct model_t *self, /* -------------------------------------------------------------------------- */ +bool model_load (struct model_t *self) +{ + char state_id[30] = {0}; + if (!model_init (self)) + return false; + + printlog ("Loading %s...\n", self->filename); + + // Dimension + self->dimension = model_get_dim (self); + printlog ("Dimension : %d\n", self->dimension); + + // Dimensions + self->space = calloc (1, sizeof(struct space_t)); + self->space->x_dim = 1; + self->space->y_dim = 1; + self->space->z_dim = 1; + + switch(self->dimension) { + case 3: + // even in 1D, we must be able to see a grid, so prevent to be 0 + if (self->space->z_dim) + self->space->z_dim = model_get_dim_value (self, "z"); + case 2: + // even in 1D, we must be able to see a grid, so prevent to be 0 + if (self->space->y_dim) + self->space->y_dim = model_get_dim_value (self, "y"); + case 1: + // even in 1D, we must be able to see a grid, so prevent to be 0 + if (self->space->x_dim) + self->space->x_dim = model_get_dim_value (self, "x"); + + printlog("x_dim=%d, y_dim=%d, z_dim=%d\n", + self->space->x_dim, + self->space->y_dim, + self->space->z_dim); + break; + default: + printerr ("Invalid dimension value : %d\n", self->dimension); + return false; + } + + // Space allocation + self->space->units = calloc (self->space->x_dim + * self->space->y_dim + * self->space->z_dim, + sizeof(struct space_unit_t)); + + // Multiplicity + self->multiplicity = model_get_multiplicity(self); + printlog("Multiplicity : %d\n", self->multiplicity); + + if (!model_get_next_state(self, &state_id)) { + printerr("No valid state to load\n"); + return false; + } + + // States and initial state + self->states = calloc (1, sizeof(struct state_t)); + self->n_states = 1; + memcpy(&self->states[0].id, &state_id, 25); + self->states[0].space = self->space; + + printlog("Initial state : %s\n", &self->states[0].id); + + // Initial state arrows + self->n_arrows = model_get_state_arrows_count(self, state_id); + self->arrows = calloc (self->n_arrows, sizeof(struct arrow_t)); + + for (int i = 0; i < self->n_arrows; i++) { + model_get_next_arrow(self, + &self->arrows[i], + &self->states[0].id, + self->dimension); + } + + printlog("Loaded %d arrows\n", self->n_arrows); + + return true; +} + +void model_system_init (struct parameters_t *parameters) +{ + struct dirent *modelDirEntry = NULL; + DIR *modelDir = NULL; + char *extensionPosition; + int i; + + // Allocate model storage + knownModels = calloc (1, sizeof(struct model_array_t)); + + // Open model directory + if ((modelDir = opendir (parameters->modelDir)) <= 0) { + printerr ("Could not open %s\n", parameters->modelDir); + } + + while ((modelDirEntry = readdir (modelDir)) != NULL) { + if ((extensionPosition = strstr (modelDirEntry->d_name, ".xml"))) { + + i = knownModels->size; + + // Creating model + knownModels->models = reallocarray (knownModels->models, + ++knownModels->size, + sizeof(struct model_t)); + + // Allocate filename with trailing '\0' + knownModels->models[i].filename = + calloc (1, strlen (parameters->modelDir) + + sizeof((char)'/') + + strlen (modelDirEntry->d_name) + + sizeof((char)'\0')); + + memcpy (knownModels->models[i].filename, + parameters->modelDir, + strlen (parameters->modelDir)); + + knownModels->models[i].filename[ + strlen (parameters->modelDir)] = '/'; + + memcpy (knownModels->models[i].filename + + strlen (parameters->modelDir) + + sizeof((char)'/'), + modelDirEntry->d_name, + strlen (modelDirEntry->d_name)); + + // Ask to parse the new model + if (model_load (&knownModels->models[i])) + // XXX Check model is valid and/or parsed + printlog ("Loaded %s\n", knownModels->models[i].filename); + } + } + free(modelDir); +} diff --git a/src/scheduler.c b/src/scheduler.c index 5ab624d..d2affad 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -102,7 +102,7 @@ int sched_start (struct scheduler_t *self, struct parameters_t *parameters) int returnValue; self->id = sched_new_id(); - printlog("Scheduler initialized with %d threads\n", + printlog("Scheduler %d initialized with %d threads\n", self->id, n_threads);