diff --git a/include/base.h b/include/base.h index d6e24e6..b24d844 100644 --- a/include/base.h +++ b/include/base.h @@ -67,6 +67,24 @@ struct arrow_t { uint z; }; +/* + * Structure describing a transition + */ +struct transition_t { + uint id; + struct condition_t *parent; + struct arrow_t *arrows; +}; + +/* + * Structure describing a condition + */ +struct condition_t { + uint id; + struct condition_t *parent; + struct arrow_t *arrows; +}; + struct space_unit_t { bool lock; @@ -78,9 +96,9 @@ struct space_t { // Dimensions of space. // Note that a value 0 is not allowed, minimum is 1 - int x_dim; - int y_dim; - int z_dim; + uint x_dim; + uint y_dim; + uint z_dim; struct space_unit_t *units; // (flat) arraw of space_unit_t elements : // - lenght is x_dim * y_dim * z_dim @@ -93,8 +111,8 @@ struct space_t struct state_t { // Metadata - int id; - int owner_id; + uint id; + uint owner_id; time_t date; struct space_t *space; @@ -103,13 +121,13 @@ struct state_t struct model_t { // Metadata - int id; - int owner_id; + uint id; + uint owner_id; time_t date; union version { - int major; - int minor; + uint major; + uint minor; }; // User friendly metadata @@ -117,12 +135,12 @@ struct model_t { char *model_name; // Model parameters - int multiplicity; // number of sites in a space_unit - int dimension; // number of space dimensions + uint multiplicity; // number of sites in a space_unit + uint dimension; // number of space dimensions // Simulation parameters - int max_thread; - int max_cycles; + uint max_thread; + uint max_cycles; // Handler to the current space of the model struct space_t *space; @@ -130,17 +148,25 @@ struct model_t { // Handler to the saved states of the model struct state_t **states; + // Array of conditions + struct condition_t *conditions; + + // Array of transitions + struct transition_t *transitions; }; struct worker_t { - int id; - int thread_num; - int status; + uint id; + uint status; + struct arrow_t *elected_arrow; }; struct scheduler_t { - int id; - struct model_t **model; // Queue (array) of waiting models + uint id; + uint n_workers; + bool pleaseStop; + struct model_t **models; // Queue (array) of waiting models + struct worker_t **workers; // Workers array }; diff --git a/src/scheduler.c b/src/scheduler.c index d2a82f0..5ab624d 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -26,82 +26,115 @@ /* -------------------------------------------------------------------------- */ +// +// +// +// static int sched_new_id (void) { static int id = 0; return id; } - +// +// +// +// static int sched_run(struct scheduler_t *self, struct parameters_t *parameters, struct model_t *model) { int n_threads = omp_get_max_threads(); int n_arrows; - int n_workers; int workers_per_cycle; int max_cycles; int max_workers; - bool pleaseStop; - struct worker_t **workers; - //XXX - n_arrows = 10000000000; + self->pleaseStop = false; + self->n_workers = 0; + n_arrows = 2000; max_cycles = 1; - workers_per_cycle = (n_arrows / n_threads) + 1; - max_workers = workers_per_cycle * max_cycles; + workers_per_cycle = (int) round((double)n_arrows / (double)n_threads); + max_workers = workers_per_cycle * n_threads * max_cycles; - printlog("Need %d workers per cycle (%d arrows to work on) : %d\n", + printlog("Begin simulation of model %d with %d workers per cycle" + " (%d arrows to work on)\n", + model->id, workers_per_cycle, n_arrows); - pleaseStop = false; - n_workers = -1; - #pragma omp parallel { int thread_num; thread_num = omp_get_thread_num(); - while (!pleaseStop) { - workers[thread_num]->id = n_workers; - worker_start(workers[thread_num], self); + while (!self->pleaseStop) { + // Get an ID; + self->workers[thread_num]->id = self->n_workers; + + // Elect an arrow (XXX TODO) + self->workers[thread_num]->elected_arrow = NULL; + + // Launch evaluation + worker_start(self->workers[thread_num], self); + + // Check if this is the end + if (self->n_workers > max_workers) { + self->pleaseStop = true; + } } } - printlog("End of simulation\n"); - - free(workers); + printlog("End of simulation (%d workers executed)\n", + self->n_workers); return SCHED_NORMAL_EXIT; } +// +// +// +// int sched_start (struct scheduler_t *self, struct parameters_t *parameters) { int n_threads = omp_get_max_threads(); - int n_arrows; - int n_workers; - int workers_per_cycle; - int max_cycles; - int max_workers; - bool pleaseStop; - struct worker_t **workers; - + int n_models = 20; + int returnValue; self->id = sched_new_id(); - printlog("Hey, I'm the scheduler %d and I can work with %d threads !\n", + printlog("Scheduler initialized with %d threads\n", self->id, n_threads); - workers = calloc(n_threads, sizeof(struct worker_t*)); - for (int i = 0; i < n_threads; i++) { - workers[thread_num] = calloc(1, sizeof(struct worker_t)); + // 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 } - sched_run(self, parameters, NULL); - + // Allocating workers + self->workers = calloc(n_threads, sizeof(struct worker_t*)); for (int i = 0; i < n_threads; i++) { - free(workers[thread_num]); + 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]); + + // Freeing workers + for (int i = 0; i < n_threads; i++) { + free(self->workers[i]); + } + free(self->workers); + + // Freeing models + for (int i = 0; i < n_models; i++) { + free(self->models[i]); + } + free(self->models); + + return returnValue; } diff --git a/src/worker.c b/src/worker.c index 77a1d7f..00985e2 100644 --- a/src/worker.c +++ b/src/worker.c @@ -35,20 +35,11 @@ static int worker_new_id (void) void worker_start(struct worker_t *self, struct scheduler_t *scheduler) { - unsigned int random_time; - - random_time = (unsigned int)(rand() % 2); - - printlog("Coucou, c'est le worker %d (et je vais dormir %d s)\n", - self->id, - random_time); - - double a = (double)self->id * 42 / ((double)self->id + 2); - truc = a; - //sleep(random_time); - - printlog("Fin du worker %d\n", - self->id); - + // Locking ressources + #pragma omp critical + { + scheduler->n_workers++; + //XXX lock space units + } self->status = WORKER_NORMAL_EXIT; }