From 2bae3c1f3ae59901881edd53f4dce0266c213b3f Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Tue, 24 Aug 2021 19:39:53 +0200 Subject: [PATCH] WIP: [BUG] Unloading models --- Makefile | 4 ++ debian/var/models/example.xml | 2 +- include/scheduler.h | 15 ++++++- include/xml.h | 3 +- src/model.c | 80 ++++++++++++++++++++++++++--------- 5 files changed, 80 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 2dd58a2..8e980fe 100644 --- a/Makefile +++ b/Makefile @@ -117,6 +117,10 @@ install: run: all @bin/gem-graph-server -C debian/etc -M debian/var/models \ -U debian/var/users +run-gdb: all + @gdb bin/gem-graph-server \ + -ex "set args -C debian/etc -M debian/var/models -U debian/var/users" + run-both: all @bin/gem-graph-server -C debian/etc -M debian/var/models \ -U debian/var/users & sleep 1 && bin/gem-graph-ctl diff --git a/debian/var/models/example.xml b/debian/var/models/example.xml index 04108b0..0f2908a 100644 --- a/debian/var/models/example.xml +++ b/debian/var/models/example.xml @@ -9,7 +9,7 @@ Modèle de test Adrien Bourmault 1 - 2021-08-21-21h34m44s + 1629822515 1.0 diff --git a/include/scheduler.h b/include/scheduler.h index 74ea80d..6e8e61c 100644 --- a/include/scheduler.h +++ b/include/scheduler.h @@ -29,9 +29,9 @@ void SchedInit(Scheduler_t *scheduler); // -------------------------------------------------------------------------- // -// Scheduler destructor function // +// Scheduler content destructor function // // -------------------------------------------------------------------------- // -static inline void SchedDestroy(Scheduler_t *scheduler) +static inline void SchedContentDestroy(Scheduler_t *scheduler) { if (scheduler) { if (scheduler->globalDrawingSpace) { @@ -53,6 +53,17 @@ static inline void SchedDestroy(Scheduler_t *scheduler) } } +// -------------------------------------------------------------------------- // +// Scheduler destructor function // +// -------------------------------------------------------------------------- // +static inline void SchedDestroy(Scheduler_t *scheduler) +{ + if (scheduler) { + free(scheduler); + } +} + + // -------------------------------------------------------------------------- // // Scheduler wait function // // -------------------------------------------------------------------------- // diff --git a/include/xml.h b/include/xml.h index c9db7f9..f8b3c09 100644 --- a/include/xml.h +++ b/include/xml.h @@ -160,8 +160,7 @@ static inline int parseTree(ModelField_t *curTree) i--; } } - strcat(curTree->value, "\n"); - printLog("Field %s: %s", curTree->tag, curTree->value); + printLog("Field %s: %s\n", curTree->tag, curTree->value); } } else { // There aren't values in that tag diff --git a/src/model.c b/src/model.c index 4464a5b..21551d4 100644 --- a/src/model.c +++ b/src/model.c @@ -28,7 +28,10 @@ #include #define MAX_MODEL_NUMBER 1 -#define MAX_MODEL_NAME_SIZE 255 +#define MAX_MODEL_NAME_SIZE 48 +#define MAX_MODEL_FILENAME_SIZE 48 +#define MAX_AUTHOR_NAME_SIZE 48 +#define MAX_VERSION_SIZE 16 #define ARROW_NUMBER 6 #define SITE_NUMBER 2 #define MAX_CYCLES 10 @@ -57,8 +60,14 @@ void printModels(char *buf) { sprintf(buf + strlen(buf),"Known models\n"); for (int i = 0; i <= knownModelSize-1; i++) { - sprintf(buf + strlen(buf), "id: %d, addr: %p, name: %s\n", - knownModel[i]->id, knownModel[i], knownModel[i]->name); + sprintf(buf + strlen(buf), "id: %d, addr: %p, name: %s, date: %lu, " + "author: %s\n", + knownModel[i]->id, + knownModel[i], + knownModel[i]->name, + knownModel[i]->date, + knownModel[i]->author + ); } sprintf(buf + strlen(buf), "\nLoaded models\n"); @@ -68,7 +77,7 @@ void printModels(char *buf) } } -int ModelLoad(int id) // TODO unload ! +int ModelLoad(int id) { if (id <= 0 || id > knownModelSize) { return -1; @@ -79,15 +88,32 @@ int ModelLoad(int id) // TODO unload ! // Creating structure for the Scheduler knownModel[id-1]->scheduler = (Scheduler_t*) calloc(1, sizeof(Scheduler_t)); - loadedModel = - (Model_t**) realloc(loadedModel, ++loadedModelSize * sizeof(Model_t*)); + loadedModelSize++; loadedModel = (Model_t**) realloc(loadedModel, loadedModelSize * sizeof(Model_t*)); + loadedModel[loadedModelSize-1] = knownModel[id-1]; return loadedModelSize; } +void ModelUnload(int id) +{ + // Destroy scheduler + SchedDestroy(loadedModel[id-1]->scheduler); + loadedModel[id-1]->scheduler = NULL; + + memmove(&loadedModel[id-1], + &loadedModel[id-1] + sizeof(Model_t*), + loadedModelSize - (id-1)); + + // Decrement loaded model index + loadedModelSize--; + + // Resize loaded model list + loadedModel = + (Model_t**) realloc(loadedModel, loadedModelSize * sizeof(Model_t*)); +} /* -------------------------------------------------------------------------- */ int ModelRun(int id) @@ -101,8 +127,9 @@ int ModelRun(int id) if (loadedModel[id-1]->isRunning) return 0; + // loadedModel[id-1]->scheduler->globalDrawingSpace = - (Space_t*) calloc(1, sizeof(Space_t)); // TODO free this + (Space_t*) calloc(1, sizeof(Space_t)); loadedModel[id-1]->scheduler->nMaxThread = knownModel[id-1]->nmaxThread; loadedModel[id-1]->scheduler->nMaxCycles = knownModel[id-1]->nmaxCycles; @@ -111,7 +138,7 @@ int ModelRun(int id) // TODO Load space loadedModel[id-1]->scheduler->arrowArray = - (ArrowArray_t*) calloc(1, sizeof(ArrowArray_t)); // TODO free this + (ArrowArray_t*) calloc(1, sizeof(ArrowArray_t)); // TODO Load arrows @@ -133,12 +160,15 @@ int ModelStop(int id) return 0; } + // Stop model scheduler loadedModel[id-1]->scheduler->pleaseStop = true; printLog("Model %d stop bit set\n", id); + // Wait for Shceduler to stop SchedWait(loadedModel[id-1]->scheduler); - SchedDestroy(loadedModel[id-1]->scheduler); + SchedContentDestroy(loadedModel[id-1]->scheduler); + // Disable running bit loadedModel[id-1]->isRunning = false; return 1; } @@ -161,7 +191,7 @@ void ModelCreate(Model_t **newModel) // TODO manage deletion and empty slots lastModel = knownModel[knownModelSize-1]; lastModelAddr = &knownModel[knownModelSize-1]; - // cont. model population + // continue. model population knownModel[knownModelSize-1]->name = (char *) calloc(1, sizeof(char) * MAX_MODEL_NAME_SIZE); @@ -169,10 +199,10 @@ void ModelCreate(Model_t **newModel) // TODO manage deletion and empty slots (char *) calloc(1, sizeof(char) * MAX_MODEL_NAME_SIZE); knownModel[knownModelSize-1]->author = - (char *) calloc(1, sizeof(char) * MAX_MODEL_NAME_SIZE); + (char *) calloc(1, sizeof(char) * MAX_AUTHOR_NAME_SIZE); knownModel[knownModelSize-1]->version = - (char *) calloc(1, sizeof(char) * MAX_MODEL_NAME_SIZE); + (char *) calloc(1, sizeof(char) * MAX_VERSION_SIZE); knownModel[knownModelSize-1]->space_xMax = XMAX; knownModel[knownModelSize-1]->space_yMax = YMAX; @@ -184,6 +214,7 @@ void ModelCreate(Model_t **newModel) // TODO manage deletion and empty slots void ModelDelete(int id) //XXX { + // Free a model structure free(knownModel[id-1]->name); knownModel[id-1]->name = NULL; @@ -204,8 +235,10 @@ void ModelDelete(int id) //XXX void ModelShutdown(void) { + // Stop each model from running for (int i = 0; i < loadedModelSize; i++) { ModelStop(i); + ModelUnload(i); } } @@ -227,6 +260,7 @@ void ModelSystemInit(Parameters_t *parameters) printLog("Model system initiated with folder : %s\n", parameters->modelDir); + // Open model directory if ((modelDir = opendir(parameters->modelDir)) <= 0) { printLog("Could not open %s\n", parameters->modelDir); ModelSystemDestroy(); @@ -240,24 +274,25 @@ void ModelSystemInit(Parameters_t *parameters) // Creating model ModelCreate(&newModel); - // Write filename - /* strncpy(newModel->filename, modelDirEntry->d_name, */ - /* strlen(modelDirEntry->d_name)); // XXX get full path */ + // Write file path in filename strncpy(newModel->filename, parameters->modelDir, strlen(parameters->modelDir)); + // Add a / separator strcat(newModel->filename + strlen(parameters->modelDir), "/"); + // Add the file relative name strncpy(newModel->filename + strlen(parameters->modelDir) + 1, modelDirEntry->d_name, strlen(modelDirEntry->d_name)); - // Write name + // Write model name strncpy(newModel->name, modelDirEntry->d_name, extensionPosition - modelDirEntry->d_name); + // Ask to parse the new model if (ModelParseFile(newModel) != 0) { ModelDelete(newModel->id); continue; @@ -269,6 +304,7 @@ void ModelSystemInit(Parameters_t *parameters) continue; } + // Succeeded ! printLog("Loaded model %s\n", newModel->name); } } @@ -307,14 +343,14 @@ static inline int ModelParseFile(Model_t *model) strcpy(nameField.tag, "name"); nameField.mandatory = true; nameField.value = model->name; - nameField.valueSize = 255; + nameField.valueSize = MAX_MODEL_NAME_SIZE; nameField.son = NULL; nameField.next = &authorField; strcpy(authorField.tag, "author"); authorField.mandatory = true; authorField.value = model->author; - authorField.valueSize = 25; + authorField.valueSize = MAX_AUTHOR_NAME_SIZE; authorField.son = NULL; authorField.next = &dateField; @@ -328,7 +364,7 @@ static inline int ModelParseFile(Model_t *model) strcpy(versionField.tag, "version"); versionField.mandatory = true; versionField.value = model->version; - versionField.valueSize = 15; + versionField.valueSize = MAX_VERSION_SIZE; versionField.son = NULL; versionField.next = NULL; @@ -338,6 +374,7 @@ static inline int ModelParseFile(Model_t *model) openCurrentDocument(model->filename); resetDocumentRoot(); + if (parseTree(&identityField) != 0) { printLog("Invalid document, parsing can't succeed!\n"); closeCurrentDocument(); @@ -345,6 +382,11 @@ static inline int ModelParseFile(Model_t *model) } closeCurrentDocument(); + + // Interpret what needs to be + model->date = strtol(date, NULL, 0); + + // validate when we're finished model->validated = true; return 0; }