WIP: working on conditions
This commit is contained in:
parent
575612a77d
commit
e9ba5643bb
3
Makefile
3
Makefile
|
@ -118,7 +118,8 @@ run: build_system
|
|||
|
||||
debug: build_system
|
||||
@echo -e ${CL2}[$@] ${CL}executing...${CL3}
|
||||
@gdb $(BINDIR)/gem-graph-server
|
||||
@gdb --args $(BINDIR)/gem-graph-server -C data/config -M data/models \
|
||||
-U data/users
|
||||
@echo -e ${CL2}[$@] ${CL}done.${CL3}
|
||||
|
||||
valgrind: build_system
|
||||
|
|
|
@ -36,4 +36,29 @@ struct arrow_t {
|
|||
uint x;
|
||||
uint y;
|
||||
uint z;
|
||||
|
||||
struct arrow_t *next;
|
||||
struct arrow_t *prev;
|
||||
};
|
||||
|
||||
struct condition_t {
|
||||
uint id;
|
||||
uint load;
|
||||
uint site;
|
||||
uint x;
|
||||
uint y;
|
||||
uint z;
|
||||
|
||||
struct condition_t *child;
|
||||
struct condition_t *parent;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
struct arrow_t *arrow_new(struct arrow_t *self);
|
||||
|
||||
struct arrow_t *arrow_destroy(struct arrow_t *self);
|
||||
|
||||
struct condition_t *condition_new(struct condition_t *self);
|
||||
|
||||
struct condition_t *condition_destroy(struct condition_t *self);
|
||||
|
|
|
@ -81,6 +81,7 @@ struct state_t
|
|||
time_t date;
|
||||
|
||||
struct space_t *space;
|
||||
struct arrow_t *arrows;
|
||||
};
|
||||
|
||||
struct model_t
|
||||
|
@ -115,6 +116,9 @@ struct model_t
|
|||
// Handler to the current space of the model
|
||||
struct space_t *space;
|
||||
|
||||
// Handler to the conditions
|
||||
struct condition_t *conditions;
|
||||
|
||||
// Handler to the arrows
|
||||
struct arrow_t *arrows;
|
||||
size_t n_arrows;
|
||||
|
@ -122,13 +126,9 @@ struct model_t
|
|||
// 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;
|
||||
struct model_t *next;
|
||||
struct model_t *prev;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
|
@ -139,7 +139,7 @@ void model_system_init (struct parameters_t *parameters);
|
|||
// -------------------------------------------------------------------------- //
|
||||
// Model stopping function //
|
||||
// -------------------------------------------------------------------------- //
|
||||
// void model_system_shutdown (void);
|
||||
void model_system_shutdown (void);
|
||||
|
||||
// -------------------------------------------------------------------------- //
|
||||
// Load a model ready to execute //
|
||||
|
|
64
src/arrows.c
64
src/arrows.c
|
@ -25,3 +25,67 @@
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
struct arrow_t *arrow_new(struct arrow_t *self)
|
||||
{
|
||||
if (self == NULL) {
|
||||
return calloc (1, sizeof(struct arrow_t));
|
||||
}
|
||||
|
||||
self->next = calloc (1, sizeof(struct arrow_t));
|
||||
self->next->prev = self;
|
||||
|
||||
return self->next;
|
||||
}
|
||||
|
||||
struct arrow_t *arrow_destroy(struct arrow_t *self)
|
||||
{
|
||||
struct arrow_t *res = NULL;
|
||||
|
||||
if (self->next)
|
||||
if (self->prev) {
|
||||
self->prev->next = self->next;
|
||||
} else {
|
||||
res = self->next;
|
||||
self->next->prev = NULL;
|
||||
}
|
||||
|
||||
if (self->prev)
|
||||
if (self->next) {
|
||||
self->next->prev = self->prev;
|
||||
} else {
|
||||
res = self->prev;
|
||||
self->prev->next = NULL;
|
||||
}
|
||||
|
||||
free(self);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct condition_t *condition_new(struct condition_t *self)
|
||||
{
|
||||
if (self == NULL) {
|
||||
return calloc (1, sizeof(struct condition_t));
|
||||
}
|
||||
|
||||
self->child = calloc (1, sizeof(struct condition_t));
|
||||
self->child->parent = self;
|
||||
|
||||
return self->child;
|
||||
}
|
||||
|
||||
struct condition_t *condition_destroy(struct condition_t *self)
|
||||
{
|
||||
struct condition_t *res = NULL;
|
||||
|
||||
if (self->child) {
|
||||
condition_destroy(self->child);
|
||||
}
|
||||
|
||||
if (self->parent)
|
||||
self->parent->child = NULL;
|
||||
|
||||
free(self);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -137,6 +137,8 @@ int main(int argc, char **argv)
|
|||
returnValue = sched_start (&scheduler, ¶meters);
|
||||
}
|
||||
|
||||
model_system_shutdown();
|
||||
|
||||
free(parameters.userDir);
|
||||
free(parameters.modelDir);
|
||||
free(parameters.configDir);
|
||||
|
|
515
src/model.c
515
src/model.c
|
@ -24,6 +24,7 @@
|
|||
#include "../include/model.h"
|
||||
#include "../include/arrows.h"
|
||||
|
||||
#define ALLOWED_RADIUS 10
|
||||
#define READ_SITE 1 << 0
|
||||
#define READ_WEIGHT 1 << 1
|
||||
#define READ_X 1 << 2
|
||||
|
@ -35,70 +36,11 @@
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
struct model_array_t *knownModels;
|
||||
struct model_t *knownModels = NULL;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static bool model_init(struct model_t *self)
|
||||
{
|
||||
xmlNode *node;
|
||||
|
||||
/*
|
||||
* this initialize the library and check potential ABI mismatches
|
||||
* between the version it was compiled for and the actual shared
|
||||
* library used.
|
||||
*/
|
||||
LIBXML_TEST_VERSION
|
||||
|
||||
self->doc = xmlReadFile(self->filename, NULL, 0);
|
||||
|
||||
if (self->doc == NULL ) {
|
||||
printerr("Error trying to open the XML model !\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
node = xmlDocGetRootElement(self->doc);
|
||||
|
||||
if (node == NULL) {
|
||||
printerr("Empty XML model !\n");
|
||||
xmlFreeDoc(self->doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlStrcmp(node->name, (xmlChar *) "gem-graph-model")) {
|
||||
printerr("document of the wrong type, root node != gem-graph-model\n");
|
||||
xmlFreeDoc(self->doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
self->hashtable = xmlHashCreate(0);
|
||||
|
||||
if (self->hashtable == NULL) {
|
||||
printerr("Can't create model hash table !\n");
|
||||
xmlFreeDoc(self->doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool model_shutdown(struct model_t *self)
|
||||
{
|
||||
xmlFreeDoc(self->doc);
|
||||
xmlHashFree(self->hashtable, NULL);
|
||||
|
||||
// Cleanup function for the XML library
|
||||
xmlCleanupParser();
|
||||
|
||||
// This is to debug memory for regression tests
|
||||
xmlMemoryDump();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static inline xmlNodePtr getNextChild(xmlNodePtr node, xmlChar *last)
|
||||
static inline xmlNodePtr getNextChild (xmlNodePtr node, xmlChar *last)
|
||||
{
|
||||
while (node != NULL && xmlStrcmp(node->name, last)) {
|
||||
// //printf(" <>--- line n°%lu <%s>\n", xmlGetLineNo(node), node->name);
|
||||
|
@ -107,14 +49,14 @@ static inline xmlNodePtr getNextChild(xmlNodePtr node, xmlChar *last)
|
|||
return node;
|
||||
}
|
||||
|
||||
static inline xmlChar* splitStrAtSlash(xmlChar *toSplit)
|
||||
static inline xmlChar* splitStrAtSlash (xmlChar *toSplit)
|
||||
{
|
||||
toSplit = (xmlChar *)xmlStrchr(toSplit, '/');
|
||||
toSplit = xmlStrsub (toSplit, 1, xmlStrlen(toSplit));
|
||||
return toSplit;
|
||||
}
|
||||
|
||||
static inline xmlChar* getFirstTag(xmlChar *path)
|
||||
static inline xmlChar* getFirstTag (xmlChar *path)
|
||||
{
|
||||
xmlChar *preop = path;
|
||||
path = (xmlChar *)xmlStrchr(path, '/');
|
||||
|
@ -123,10 +65,10 @@ static inline xmlChar* getFirstTag(xmlChar *path)
|
|||
return xmlStrsub (preop, 0, xmlStrlen(preop) - xmlStrlen(path) - 1);
|
||||
}
|
||||
|
||||
static inline xmlChar* getLastTag(xmlChar *path)
|
||||
static inline xmlChar* getLastTag (xmlChar *path)
|
||||
{
|
||||
while ((ulong)xmlStrchr (path, '/'))
|
||||
path = splitStrAtSlash((xmlChar *)path);
|
||||
path = splitStrAtSlash ((xmlChar *)path);
|
||||
|
||||
// //printf("last tag in the path = <%s>\n", path);
|
||||
return path; // which is no more the given path but only its last tag !
|
||||
|
@ -134,7 +76,7 @@ static inline xmlChar* getLastTag(xmlChar *path)
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static xmlNodePtr model_get_node(struct model_t *self, xmlChar *path)
|
||||
static xmlNodePtr model_get_node (struct model_t *self, xmlChar *path)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
xmlChar *extrait;
|
||||
|
@ -179,7 +121,7 @@ static xmlNodePtr model_get_node(struct model_t *self, xmlChar *path)
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static inline long model_get_node_long_attrib(xmlNodePtr node, char *id)
|
||||
static inline long model_get_node_long_attrib (xmlNodePtr node, char *id)
|
||||
{
|
||||
xmlAttr *attribute;
|
||||
xmlChar* value;
|
||||
|
@ -200,7 +142,7 @@ static inline long model_get_node_long_attrib(xmlNodePtr node, char *id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline bool model_get_node_str_attrib(xmlNodePtr node,
|
||||
static inline bool model_get_node_str_attrib (xmlNodePtr node,
|
||||
char *id,
|
||||
char *dest)
|
||||
{
|
||||
|
@ -224,7 +166,7 @@ static inline bool model_get_node_str_attrib(xmlNodePtr node,
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
char model_get_dim(struct model_t *self)
|
||||
char model_get_dim (struct model_t *self)
|
||||
{
|
||||
xmlAttr *attribute;
|
||||
xmlChar* value;
|
||||
|
@ -237,7 +179,7 @@ char model_get_dim(struct model_t *self)
|
|||
return 0;
|
||||
}
|
||||
|
||||
long model_get_dim_value(struct model_t *self, const char *axis)
|
||||
long model_get_dim_value (struct model_t *self, const char *axis)
|
||||
{
|
||||
xmlAttr *attribute;
|
||||
xmlChar *value;
|
||||
|
@ -248,7 +190,7 @@ long model_get_dim_value(struct model_t *self, const char *axis)
|
|||
return model_get_node_long_attrib(node, axis);
|
||||
}
|
||||
|
||||
char model_get_multiplicity(struct model_t *self)
|
||||
char model_get_multiplicity (struct model_t *self)
|
||||
{
|
||||
xmlAttr *attribute;
|
||||
xmlChar* value;
|
||||
|
@ -262,7 +204,7 @@ char model_get_multiplicity(struct model_t *self)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool model_get_next_state(struct model_t *self, char *new_state_id)
|
||||
bool model_get_next_state (struct model_t *self, char *new_state_id)
|
||||
{
|
||||
static xmlNodePtr cur_node = NULL;
|
||||
xmlAttr *attribute;
|
||||
|
@ -288,7 +230,7 @@ bool model_get_next_state(struct model_t *self, char *new_state_id)
|
|||
return false;
|
||||
}
|
||||
|
||||
long model_get_state_arrows_count(struct model_t *self, const char *state_id)
|
||||
long model_get_state_arrows_count (struct model_t *self, const char *state_id)
|
||||
{
|
||||
xmlNodePtr cur_node = NULL;
|
||||
xmlAttr *attribute;
|
||||
|
@ -339,7 +281,7 @@ long model_get_state_arrows_count(struct model_t *self, const char *state_id)
|
|||
return value;
|
||||
}
|
||||
|
||||
bool model_get_next_arrow(struct model_t *self,
|
||||
bool model_get_next_arrow (struct model_t *self,
|
||||
struct arrow_t *new_arrow,
|
||||
const char *state_id,
|
||||
char dimension)
|
||||
|
@ -473,11 +415,232 @@ bool model_get_next_arrow(struct model_t *self,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool model_get_next_conditions (struct model_t *self, char *new_cond_id)
|
||||
{
|
||||
static xmlNodePtr cur_node = NULL;
|
||||
xmlAttr *attribute;
|
||||
xmlChar *value;
|
||||
|
||||
if (cur_node == NULL) {
|
||||
// Get first state
|
||||
cur_node = model_get_node(self, (xmlChar *)"conditions");
|
||||
|
||||
} else {
|
||||
// Get next state
|
||||
if (cur_node->next)
|
||||
cur_node = cur_node->next;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
// Lookup in properties
|
||||
if (model_get_node_str_attrib(cur_node, "id", new_cond_id))
|
||||
return true;
|
||||
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool model_get_next_condition (struct model_t *self,
|
||||
struct condition_t *new_condition,
|
||||
const char *cond_id,
|
||||
char dimension)
|
||||
{
|
||||
static xmlNodePtr cur_node = NULL;
|
||||
xmlAttr *attribute;
|
||||
xmlChar *value;
|
||||
bool found = false;
|
||||
char temp_char[25];
|
||||
uint check = 0; // bit field checker
|
||||
|
||||
//printf("NEW CALL : cur_node = %p\n", cur_node);
|
||||
|
||||
assert(new_condition);
|
||||
assert(cond_id);
|
||||
|
||||
if (cur_node == NULL) {
|
||||
// Get first state node
|
||||
cur_node = model_get_node(self, (xmlChar *)"conditions");
|
||||
|
||||
// Lookup in properties
|
||||
while (cur_node && cur_node->properties) {
|
||||
attribute = cur_node->properties;
|
||||
|
||||
// Look for the id attribute
|
||||
if (model_get_node_str_attrib(cur_node, "id", &temp_char)) {
|
||||
if (!xmlStrcmp(temp_char, (const xmlChar *)cond_id)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
|
||||
// Check if the state has been found
|
||||
if (!found) {
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get first arrow
|
||||
if (cur_node->children) {
|
||||
cur_node = cur_node->children;
|
||||
|
||||
found = false;
|
||||
while (cur_node && cur_node->name) {
|
||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
cur_node = cur_node->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the state has been found
|
||||
if (!found) {
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Get next condition
|
||||
found = false;
|
||||
while (cur_node->next) {
|
||||
cur_node = cur_node->next;
|
||||
if (!xmlStrcmp(cur_node->name, (const xmlChar *)"arrow")) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the state has been found
|
||||
if (!found) {
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("DURING CALL : cur_node = %p\n", cur_node);
|
||||
//printf("DURING CALL : cur_node->name = %s\n", cur_node->name);
|
||||
|
||||
// Lookup in properties
|
||||
if (cur_node && cur_node->properties) {
|
||||
attribute = cur_node->properties;
|
||||
|
||||
while(attribute && attribute->name && attribute->children) {
|
||||
//printf("attr name : %s\n", attribute->name);
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"site")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_condition->site = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_SITE;
|
||||
}
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"weight")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_condition->load = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_WEIGHT;
|
||||
}
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"x")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_condition->x = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_X;
|
||||
}
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"y")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_condition->y = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_Y;
|
||||
}
|
||||
if (!xmlStrcmp(attribute->name, (const xmlChar *)"z")) {
|
||||
value = xmlNodeListGetString(cur_node->doc, attribute->children, 1);
|
||||
new_condition->z = strtol((char *)value, NULL, 0);
|
||||
xmlFree(value);
|
||||
check |= READ_Z;
|
||||
}
|
||||
attribute = attribute->next;
|
||||
}
|
||||
|
||||
switch(dimension) {
|
||||
case 3:
|
||||
return (bool)(check & SUCCESSFUL_READ_ARROW_XYZ);
|
||||
case 2:
|
||||
return (bool)(check & SUCCESSFUL_READ_ARROW_XY);
|
||||
case 1:
|
||||
return (bool)(check & SUCCESSFUL_READ_ARROW_X);
|
||||
}
|
||||
}
|
||||
cur_node = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static bool model_init(struct model_t *self)
|
||||
{
|
||||
xmlNode *node;
|
||||
|
||||
/*
|
||||
* this initialize the library and check potential ABI mismatches
|
||||
* between the version it was compiled for and the actual shared
|
||||
* library used.
|
||||
*/
|
||||
LIBXML_TEST_VERSION
|
||||
|
||||
self->doc = xmlReadFile(self->filename, NULL, 0);
|
||||
|
||||
if (self->doc == NULL ) {
|
||||
printerr("Error trying to open the XML model !\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
node = xmlDocGetRootElement(self->doc);
|
||||
|
||||
if (node == NULL) {
|
||||
printerr("Empty XML model !\n");
|
||||
xmlFreeDoc(self->doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (xmlStrcmp(node->name, (xmlChar *) "gem-graph-model")) {
|
||||
printerr("document of the wrong type, root node != gem-graph-model\n");
|
||||
xmlFreeDoc(self->doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
self->hashtable = xmlHashCreate(0);
|
||||
|
||||
if (self->hashtable == NULL) {
|
||||
printerr("Can't create model hash table !\n");
|
||||
xmlFreeDoc(self->doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool model_shutdown(struct model_t *self)
|
||||
{
|
||||
xmlFreeDoc(self->doc);
|
||||
xmlHashFree(self->hashtable, NULL);
|
||||
// This is to debug memory for regression tests
|
||||
//xmlMemoryDump();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
bool model_load (struct model_t *self)
|
||||
{
|
||||
char state_id[30] = {0};
|
||||
char conditions_id[30] = {0};
|
||||
struct arrow_t *arrow;
|
||||
struct arrow_t *arrow_next;
|
||||
struct arrow_t *arrow_prev;
|
||||
int n_conditions;
|
||||
|
||||
|
||||
if (!model_init (self))
|
||||
return false;
|
||||
|
@ -528,12 +691,12 @@ bool model_load (struct model_t *self)
|
|||
self->multiplicity = model_get_multiplicity(self);
|
||||
printlog("Multiplicity : %d\n", self->multiplicity);
|
||||
|
||||
// States and initial state
|
||||
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);
|
||||
|
@ -542,31 +705,155 @@ bool model_load (struct model_t *self)
|
|||
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));
|
||||
self->arrows = arrow_new (self->arrows);
|
||||
|
||||
for (int i = 0; i < self->n_arrows; i++) {
|
||||
model_get_next_arrow(self,
|
||||
&self->arrows[i],
|
||||
&self->states[0].id,
|
||||
self->dimension);
|
||||
if (model_get_next_arrow(self,
|
||||
self->arrows,
|
||||
&self->states[0].id,
|
||||
self->dimension)) {
|
||||
self->n_arrows++;
|
||||
|
||||
while (model_get_next_arrow(self,
|
||||
arrow_new (self->arrows),
|
||||
&self->states[0].id,
|
||||
self->dimension)) {
|
||||
self->n_arrows++;
|
||||
}
|
||||
}
|
||||
|
||||
printlog("Loaded %d arrows\n", self->n_arrows);
|
||||
|
||||
self->states[0].arrows = self->arrows;
|
||||
|
||||
// Conditions
|
||||
if (!model_get_next_conditions(self, &conditions_id)) {
|
||||
printerr("No valid conditions to load\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loading each condition
|
||||
self->conditions = condition_new (self->conditions);
|
||||
|
||||
if (model_get_next_condition(self,
|
||||
self->conditions,
|
||||
&conditions_id,
|
||||
self->dimension)) {
|
||||
n_conditions = 1;
|
||||
while (model_get_next_arrow(self,
|
||||
condition_new (self->conditions),
|
||||
&conditions_id,
|
||||
self->dimension)) {
|
||||
n_conditions++;
|
||||
}
|
||||
}
|
||||
|
||||
printlog("Loaded %d conditions\n", n_conditions);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool model_unload (struct model_t *self)
|
||||
{
|
||||
if (!model_shutdown (self))
|
||||
return false;
|
||||
|
||||
if (self->owner_name) {
|
||||
free(self->owner_name);
|
||||
self->owner_name = NULL;
|
||||
}
|
||||
if (self->model_name) {
|
||||
free(self->model_name);
|
||||
self->model_name = NULL;
|
||||
}
|
||||
if (self->space) {
|
||||
if (self->space->units) {
|
||||
free(self->space->units);
|
||||
self->space->units = NULL;
|
||||
}
|
||||
free(self->space);
|
||||
self->space = NULL;
|
||||
}
|
||||
if (self->arrows) {
|
||||
while (self->arrows) {
|
||||
self->arrows = arrow_destroy (self->arrows);
|
||||
}
|
||||
}
|
||||
if (self->states) {
|
||||
free(self->states);
|
||||
self->states = NULL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct model_t *model_new(const char *path, const char *basename)
|
||||
{
|
||||
struct model_t *self = NULL;
|
||||
struct model_t *prev = NULL;
|
||||
|
||||
// Allocate and insert in the list
|
||||
self = calloc (1, sizeof(struct model_t));
|
||||
|
||||
// We want a cyclic chain
|
||||
// This is the first model
|
||||
if (!knownModels) {
|
||||
knownModels = self;
|
||||
self->next = self;
|
||||
self->prev = self;
|
||||
|
||||
// This is not the first model
|
||||
} else {
|
||||
self->next = knownModels->next;
|
||||
knownModels->next = self;
|
||||
self->prev = knownModels;
|
||||
}
|
||||
|
||||
// Allocate filename with trailing '\0'
|
||||
self->filename =
|
||||
calloc (1, strlen (path)
|
||||
+ sizeof((char)'/')
|
||||
+ strlen (basename)
|
||||
+ sizeof((char)'\0'));
|
||||
|
||||
memcpy (self->filename,
|
||||
path,
|
||||
strlen (path));
|
||||
|
||||
self->filename[
|
||||
strlen (path)] = '/';
|
||||
|
||||
memcpy (self->filename
|
||||
+ strlen (path)
|
||||
+ sizeof((char)'/'),
|
||||
basename,
|
||||
strlen (basename));
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void model_destroy(struct model_t *self)
|
||||
{
|
||||
if (self->filename) {
|
||||
free(self->filename);
|
||||
self->filename = NULL;
|
||||
}
|
||||
|
||||
if (self->next != self) {
|
||||
self->prev->next = self->next;
|
||||
self->next->prev = self->prev;
|
||||
}
|
||||
|
||||
free(self);
|
||||
}
|
||||
|
||||
void model_system_init (struct parameters_t *parameters)
|
||||
{
|
||||
struct dirent *modelDirEntry = NULL;
|
||||
struct model_t *new_model;
|
||||
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);
|
||||
|
@ -575,38 +862,40 @@ void model_system_init (struct parameters_t *parameters)
|
|||
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));
|
||||
new_model = model_new (parameters->modelDir, modelDirEntry->d_name);
|
||||
|
||||
// Ask to parse the new model
|
||||
if (model_load (&knownModels->models[i]))
|
||||
if (model_load (new_model)) {
|
||||
// XXX Check model is valid and/or parsed
|
||||
printlog ("Loaded %s\n", knownModels->models[i].filename);
|
||||
printlog ("Loaded %s\n", new_model->filename);
|
||||
} else {
|
||||
printerr ("Failed to load %s\n", new_model->filename);
|
||||
model_unload (new_model);
|
||||
model_destroy (new_model);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(modelDir);
|
||||
}
|
||||
|
||||
void model_system_shutdown (void)
|
||||
{
|
||||
struct model_t *model = knownModels;
|
||||
struct model_t *next = NULL;
|
||||
|
||||
while ((model != model->next)) {
|
||||
printlog ("Freeing %s\n", model->filename);
|
||||
next = model->next;
|
||||
model_unload(model);
|
||||
model_destroy(model);
|
||||
model = next;
|
||||
}
|
||||
|
||||
if (model) {
|
||||
model_unload (model);
|
||||
model_destroy (model);
|
||||
}
|
||||
|
||||
// Cleanup function for the XML library
|
||||
xmlCleanupParser();
|
||||
}
|
||||
|
|
|
@ -98,20 +98,14 @@ static int sched_run(struct scheduler_t *self,
|
|||
int sched_start (struct scheduler_t *self, struct parameters_t *parameters)
|
||||
{
|
||||
int n_threads = omp_get_max_threads();
|
||||
int n_models = 20;
|
||||
int returnValue;
|
||||
struct model_t *model;
|
||||
self->id = sched_new_id();
|
||||
|
||||
printlog("Scheduler %d initialized with %d threads\n",
|
||||
self->id,
|
||||
n_threads);
|
||||
|
||||
// Allocating models
|
||||
self->models = calloc(n_models, sizeof(struct model_t*));
|
||||
for (int i = 0; i < n_models; i++) {
|
||||
self->models[i] = calloc(1, sizeof(struct model_t));
|
||||
//XXX populate model
|
||||
}
|
||||
|
||||
// Allocating workers
|
||||
self->workers = calloc(n_threads, sizeof(struct worker_t*));
|
||||
|
@ -119,10 +113,13 @@ int sched_start (struct scheduler_t *self, struct parameters_t *parameters)
|
|||
self->workers[i] = calloc(1, sizeof(struct worker_t));
|
||||
}
|
||||
|
||||
// Run
|
||||
#pragma omp for
|
||||
for (int i = 0; i < n_models; i++)
|
||||
returnValue = sched_run(self, parameters, self->models[i]);
|
||||
// Retrieve models
|
||||
model = self->models;
|
||||
while(model) {
|
||||
printlog ("Scheduling model %d\n", model->id);
|
||||
returnValue = sched_run(self, parameters, self->models);
|
||||
model = model->next;
|
||||
}
|
||||
|
||||
// Freeing workers
|
||||
for (int i = 0; i < n_threads; i++) {
|
||||
|
@ -130,11 +127,7 @@ int sched_start (struct scheduler_t *self, struct parameters_t *parameters)
|
|||
}
|
||||
free(self->workers);
|
||||
|
||||
// Freeing models
|
||||
for (int i = 0; i < n_models; i++) {
|
||||
free(self->models[i]);
|
||||
}
|
||||
free(self->models);
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue