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
|
debug: build_system
|
||||||
@echo -e ${CL2}[$@] ${CL}executing...${CL3}
|
@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}
|
@echo -e ${CL2}[$@] ${CL}done.${CL3}
|
||||||
|
|
||||||
valgrind: build_system
|
valgrind: build_system
|
||||||
|
|
|
@ -36,4 +36,29 @@ struct arrow_t {
|
||||||
uint x;
|
uint x;
|
||||||
uint y;
|
uint y;
|
||||||
uint z;
|
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;
|
time_t date;
|
||||||
|
|
||||||
struct space_t *space;
|
struct space_t *space;
|
||||||
|
struct arrow_t *arrows;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct model_t
|
struct model_t
|
||||||
|
@ -115,6 +116,9 @@ struct model_t
|
||||||
// Handler to the current space of the model
|
// Handler to the current space of the model
|
||||||
struct space_t *space;
|
struct space_t *space;
|
||||||
|
|
||||||
|
// Handler to the conditions
|
||||||
|
struct condition_t *conditions;
|
||||||
|
|
||||||
// Handler to the arrows
|
// Handler to the arrows
|
||||||
struct arrow_t *arrows;
|
struct arrow_t *arrows;
|
||||||
size_t n_arrows;
|
size_t n_arrows;
|
||||||
|
@ -122,13 +126,9 @@ struct model_t
|
||||||
// Handler to the saved states array
|
// Handler to the saved states array
|
||||||
struct state_t *states;
|
struct state_t *states;
|
||||||
size_t n_states;
|
size_t n_states;
|
||||||
};
|
|
||||||
|
|
||||||
|
struct model_t *next;
|
||||||
struct model_array_t
|
struct model_t *prev;
|
||||||
{
|
|
||||||
struct model_t *models;
|
|
||||||
size_t size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------- //
|
// -------------------------------------------------------------------------- //
|
||||||
|
@ -139,7 +139,7 @@ void model_system_init (struct parameters_t *parameters);
|
||||||
// -------------------------------------------------------------------------- //
|
// -------------------------------------------------------------------------- //
|
||||||
// Model stopping function //
|
// Model stopping function //
|
||||||
// -------------------------------------------------------------------------- //
|
// -------------------------------------------------------------------------- //
|
||||||
// void model_system_shutdown (void);
|
void model_system_shutdown (void);
|
||||||
|
|
||||||
// -------------------------------------------------------------------------- //
|
// -------------------------------------------------------------------------- //
|
||||||
// Load a model ready to execute //
|
// 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);
|
returnValue = sched_start (&scheduler, ¶meters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model_system_shutdown();
|
||||||
|
|
||||||
free(parameters.userDir);
|
free(parameters.userDir);
|
||||||
free(parameters.modelDir);
|
free(parameters.modelDir);
|
||||||
free(parameters.configDir);
|
free(parameters.configDir);
|
||||||
|
|
515
src/model.c
515
src/model.c
|
@ -24,6 +24,7 @@
|
||||||
#include "../include/model.h"
|
#include "../include/model.h"
|
||||||
#include "../include/arrows.h"
|
#include "../include/arrows.h"
|
||||||
|
|
||||||
|
#define ALLOWED_RADIUS 10
|
||||||
#define READ_SITE 1 << 0
|
#define READ_SITE 1 << 0
|
||||||
#define READ_WEIGHT 1 << 1
|
#define READ_WEIGHT 1 << 1
|
||||||
#define READ_X 1 << 2
|
#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)
|
static inline xmlNodePtr getNextChild (xmlNodePtr node, xmlChar *last)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
while (node != NULL && xmlStrcmp(node->name, last)) {
|
while (node != NULL && xmlStrcmp(node->name, last)) {
|
||||||
// //printf(" <>--- line n°%lu <%s>\n", xmlGetLineNo(node), node->name);
|
// //printf(" <>--- line n°%lu <%s>\n", xmlGetLineNo(node), node->name);
|
||||||
|
@ -107,14 +49,14 @@ static inline xmlNodePtr getNextChild(xmlNodePtr node, xmlChar *last)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline xmlChar* splitStrAtSlash(xmlChar *toSplit)
|
static inline xmlChar* splitStrAtSlash (xmlChar *toSplit)
|
||||||
{
|
{
|
||||||
toSplit = (xmlChar *)xmlStrchr(toSplit, '/');
|
toSplit = (xmlChar *)xmlStrchr(toSplit, '/');
|
||||||
toSplit = xmlStrsub (toSplit, 1, xmlStrlen(toSplit));
|
toSplit = xmlStrsub (toSplit, 1, xmlStrlen(toSplit));
|
||||||
return toSplit;
|
return toSplit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline xmlChar* getFirstTag(xmlChar *path)
|
static inline xmlChar* getFirstTag (xmlChar *path)
|
||||||
{
|
{
|
||||||
xmlChar *preop = path;
|
xmlChar *preop = path;
|
||||||
path = (xmlChar *)xmlStrchr(path, '/');
|
path = (xmlChar *)xmlStrchr(path, '/');
|
||||||
|
@ -123,10 +65,10 @@ static inline xmlChar* getFirstTag(xmlChar *path)
|
||||||
return xmlStrsub (preop, 0, xmlStrlen(preop) - xmlStrlen(path) - 1);
|
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, '/'))
|
while ((ulong)xmlStrchr (path, '/'))
|
||||||
path = splitStrAtSlash((xmlChar *)path);
|
path = splitStrAtSlash ((xmlChar *)path);
|
||||||
|
|
||||||
// //printf("last tag in the path = <%s>\n", path);
|
// //printf("last tag in the path = <%s>\n", path);
|
||||||
return path; // which is no more the given path but only its last tag !
|
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;
|
xmlNodePtr node;
|
||||||
xmlChar *extrait;
|
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;
|
xmlAttr *attribute;
|
||||||
xmlChar* value;
|
xmlChar* value;
|
||||||
|
@ -200,7 +142,7 @@ static inline long model_get_node_long_attrib(xmlNodePtr node, char *id)
|
||||||
return 0;
|
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 *id,
|
||||||
char *dest)
|
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;
|
xmlAttr *attribute;
|
||||||
xmlChar* value;
|
xmlChar* value;
|
||||||
|
@ -237,7 +179,7 @@ char model_get_dim(struct model_t *self)
|
||||||
return 0;
|
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;
|
xmlAttr *attribute;
|
||||||
xmlChar *value;
|
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);
|
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;
|
xmlAttr *attribute;
|
||||||
xmlChar* value;
|
xmlChar* value;
|
||||||
|
@ -262,7 +204,7 @@ char model_get_multiplicity(struct model_t *self)
|
||||||
return 0;
|
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;
|
static xmlNodePtr cur_node = NULL;
|
||||||
xmlAttr *attribute;
|
xmlAttr *attribute;
|
||||||
|
@ -288,7 +230,7 @@ bool model_get_next_state(struct model_t *self, char *new_state_id)
|
||||||
return false;
|
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;
|
xmlNodePtr cur_node = NULL;
|
||||||
xmlAttr *attribute;
|
xmlAttr *attribute;
|
||||||
|
@ -339,7 +281,7 @@ long model_get_state_arrows_count(struct model_t *self, const char *state_id)
|
||||||
return value;
|
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,
|
struct arrow_t *new_arrow,
|
||||||
const char *state_id,
|
const char *state_id,
|
||||||
char dimension)
|
char dimension)
|
||||||
|
@ -473,11 +415,232 @@ bool model_get_next_arrow(struct model_t *self,
|
||||||
return false;
|
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)
|
bool model_load (struct model_t *self)
|
||||||
{
|
{
|
||||||
char state_id[30] = {0};
|
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))
|
if (!model_init (self))
|
||||||
return false;
|
return false;
|
||||||
|
@ -528,12 +691,12 @@ bool model_load (struct model_t *self)
|
||||||
self->multiplicity = model_get_multiplicity(self);
|
self->multiplicity = model_get_multiplicity(self);
|
||||||
printlog("Multiplicity : %d\n", self->multiplicity);
|
printlog("Multiplicity : %d\n", self->multiplicity);
|
||||||
|
|
||||||
|
// States and initial state
|
||||||
if (!model_get_next_state(self, &state_id)) {
|
if (!model_get_next_state(self, &state_id)) {
|
||||||
printerr("No valid state to load\n");
|
printerr("No valid state to load\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// States and initial state
|
|
||||||
self->states = calloc (1, sizeof(struct state_t));
|
self->states = calloc (1, sizeof(struct state_t));
|
||||||
self->n_states = 1;
|
self->n_states = 1;
|
||||||
memcpy(&self->states[0].id, &state_id, 25);
|
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);
|
printlog("Initial state : %s\n", &self->states[0].id);
|
||||||
|
|
||||||
// Initial state arrows
|
// Initial state arrows
|
||||||
self->n_arrows = model_get_state_arrows_count(self, state_id);
|
self->arrows = arrow_new (self->arrows);
|
||||||
self->arrows = calloc (self->n_arrows, sizeof(struct arrow_t));
|
|
||||||
|
|
||||||
for (int i = 0; i < self->n_arrows; i++) {
|
if (model_get_next_arrow(self,
|
||||||
model_get_next_arrow(self,
|
self->arrows,
|
||||||
&self->arrows[i],
|
&self->states[0].id,
|
||||||
&self->states[0].id,
|
self->dimension)) {
|
||||||
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);
|
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;
|
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)
|
void model_system_init (struct parameters_t *parameters)
|
||||||
{
|
{
|
||||||
struct dirent *modelDirEntry = NULL;
|
struct dirent *modelDirEntry = NULL;
|
||||||
|
struct model_t *new_model;
|
||||||
DIR *modelDir = NULL;
|
DIR *modelDir = NULL;
|
||||||
char *extensionPosition;
|
char *extensionPosition;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Allocate model storage
|
|
||||||
knownModels = calloc (1, sizeof(struct model_array_t));
|
|
||||||
|
|
||||||
// Open model directory
|
// Open model directory
|
||||||
if ((modelDir = opendir (parameters->modelDir)) <= 0) {
|
if ((modelDir = opendir (parameters->modelDir)) <= 0) {
|
||||||
printerr ("Could not open %s\n", parameters->modelDir);
|
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) {
|
while ((modelDirEntry = readdir (modelDir)) != NULL) {
|
||||||
if ((extensionPosition = strstr (modelDirEntry->d_name, ".xml"))) {
|
if ((extensionPosition = strstr (modelDirEntry->d_name, ".xml"))) {
|
||||||
|
|
||||||
i = knownModels->size;
|
new_model = model_new (parameters->modelDir, modelDirEntry->d_name);
|
||||||
|
|
||||||
// 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
|
// 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
|
// 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);
|
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 sched_start (struct scheduler_t *self, struct parameters_t *parameters)
|
||||||
{
|
{
|
||||||
int n_threads = omp_get_max_threads();
|
int n_threads = omp_get_max_threads();
|
||||||
int n_models = 20;
|
|
||||||
int returnValue;
|
int returnValue;
|
||||||
|
struct model_t *model;
|
||||||
self->id = sched_new_id();
|
self->id = sched_new_id();
|
||||||
|
|
||||||
printlog("Scheduler %d initialized with %d threads\n",
|
printlog("Scheduler %d initialized with %d threads\n",
|
||||||
self->id,
|
self->id,
|
||||||
n_threads);
|
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
|
// Allocating workers
|
||||||
self->workers = calloc(n_threads, sizeof(struct worker_t*));
|
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));
|
self->workers[i] = calloc(1, sizeof(struct worker_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run
|
// Retrieve models
|
||||||
#pragma omp for
|
model = self->models;
|
||||||
for (int i = 0; i < n_models; i++)
|
while(model) {
|
||||||
returnValue = sched_run(self, parameters, self->models[i]);
|
printlog ("Scheduling model %d\n", model->id);
|
||||||
|
returnValue = sched_run(self, parameters, self->models);
|
||||||
|
model = model->next;
|
||||||
|
}
|
||||||
|
|
||||||
// Freeing workers
|
// Freeing workers
|
||||||
for (int i = 0; i < n_threads; i++) {
|
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);
|
free(self->workers);
|
||||||
|
|
||||||
// Freeing models
|
|
||||||
for (int i = 0; i < n_models; i++) {
|
|
||||||
free(self->models[i]);
|
|
||||||
}
|
|
||||||
free(self->models);
|
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue