diff --git a/examples/main.c b/examples/main.c index be1ed7c192458fb08215035694bdb2a843400933..9cda03c14c364974a18e36c84e60227a01970dd5 100644 --- a/examples/main.c +++ b/examples/main.c @@ -611,6 +611,10 @@ int main(int argc, char *argv[]) { error("call to MPI_Finalize failed with error %i.", res); #endif + /* Clean everything */ + engine_clean(&e); + free(params); + /* Say goodbye. */ if (myrank == 0) message("done. Bye."); diff --git a/src/cell.c b/src/cell.c index ddcf8defaf8a38fe35ae9798bb33db439f4f5ce4..2796a8933e1fedc2522c833570558adda369140b 100644 --- a/src/cell.c +++ b/src/cell.c @@ -707,3 +707,15 @@ void cell_clean_links(struct cell *c, void *data) { c->force = NULL; c->nr_force = 0; } + +/** + * @brief Frees up the memory allocated for this #cell + */ +void cell_clean(struct cell *c) { + + free(c->sort); + + /* Recurse */ + for (int k = 0; k < 8; k++) + if (c->progeny[k]) cell_clean(c->progeny[k]); +} diff --git a/src/cell.h b/src/cell.h index b9e060050827e6e0bbd62c87024bbf066d3807f8..a14d94d50ce6a4d2d25e7e6005c035cb22a3720d 100644 --- a/src/cell.h +++ b/src/cell.h @@ -197,5 +197,6 @@ void cell_init_parts(struct cell *c, void *data); void cell_init_gparts(struct cell *c, void *data); void cell_convert_hydro(struct cell *c, void *data); void cell_clean_links(struct cell *c, void *data); +void cell_clean(struct cell *c); #endif /* SWIFT_CELL_H */ diff --git a/src/engine.c b/src/engine.c index 6609f7f0d53453c6649a8089d2b656f555e00f75..b33850be9415f30f6c0ac38e70a74a7d239b791e 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2864,20 +2864,22 @@ void engine_init(struct engine *e, struct space *s, if (verbose && with_aff) message("Affinity at entry: %s", buf); - int *cpuid = malloc(nr_affinity_cores * sizeof(int)); + int *cpuid = NULL; cpu_set_t cpuset; - int skip = 0; - for (int k = 0; k < nr_affinity_cores; k++) { - int c; - for (c = skip; c < CPU_SETSIZE && !CPU_ISSET(c, entry_affinity); ++c) - ; - cpuid[k] = c; - skip = c + 1; - } - if (with_aff) { + cpuid = malloc(nr_affinity_cores * sizeof(int)); + + int skip = 0; + for (int k = 0; k < nr_affinity_cores; k++) { + int c; + for (c = skip; c < CPU_SETSIZE && !CPU_ISSET(c, entry_affinity); ++c) + ; + cpuid[k] = c; + skip = c + 1; + } + #if defined(HAVE_LIBNUMA) && defined(_GNU_SOURCE) if ((policy & engine_policy_cputight) != engine_policy_cputight) { @@ -3176,8 +3178,8 @@ void engine_init(struct engine *e, struct space *s, #if defined(HAVE_SETAFFINITY) if (with_aff) { free(cpuid); - free(buf); } + free(buf); #endif /* Wait for the runner threads to be in place. */ @@ -3241,3 +3243,14 @@ void engine_compute_next_snapshot_time(struct engine *e) { message("Next output time set to t=%e.", next_snapshot_time); } } + +/** + * @brief Frees up the memory allocated for this #engine + */ +void engine_clean(struct engine *e) { + + free(e->snapshotUnits); + free(e->links); + scheduler_clean(&e->sched); + space_clean(e->s); +} diff --git a/src/engine.h b/src/engine.h index 9ec42cd3654d012fc42adda021cab7bb5a81dd58..d708198c32b67c5118bbd7f4676f1ea0fe821c7d 100644 --- a/src/engine.h +++ b/src/engine.h @@ -239,5 +239,6 @@ void engine_print_policy(struct engine *e); int engine_is_done(struct engine *e); void engine_pin(); void engine_unpin(); +void engine_clean(struct engine *e); #endif /* SWIFT_ENGINE_H */ diff --git a/src/queue.c b/src/queue.c index 9883d77e66421eda6093331e0c9a8f6ac0155ded..38f8620fdc75d744df31513792e96323dbf83647 100644 --- a/src/queue.c +++ b/src/queue.c @@ -296,3 +296,9 @@ struct task *queue_gettask(struct queue *q, const struct task *prev, /* Take the money and run. */ return res; } + +void queue_clean(struct queue *q) { + + free(q->tid); + free(q->tid_incoming); +} diff --git a/src/queue.h b/src/queue.h index 5878866c890f53f22c3deaac7fe9b6bba75d499e..c0a2fb1da6e6e3cbea813a0ef53841084ab0f933 100644 --- a/src/queue.h +++ b/src/queue.h @@ -64,5 +64,6 @@ struct task *queue_gettask(struct queue *q, const struct task *prev, int blocking); void queue_init(struct queue *q, struct task *tasks); void queue_insert(struct queue *q, struct task *t); +void queue_clean(struct queue *q); #endif /* SWIFT_QUEUE_H */ diff --git a/src/runner.c b/src/runner.c index 63243ab66d24a2efc045e19e866e24b7a0f4868c..01762dda28aaa8f1fa3e240824761d90c9f8f702 100644 --- a/src/runner.c +++ b/src/runner.c @@ -428,7 +428,6 @@ void runner_do_ghost(struct runner *r, struct cell *c) { struct xpart *xp, *xparts = c->xparts; struct cell *finger; int redo, count = c->count; - int *pid; float h_corr; const int ti_current = r->e->ti_current; const double timeBase = r->e->timeBase; @@ -450,8 +449,9 @@ void runner_do_ghost(struct runner *r, struct cell *c) { } /* Init the IDs that have to be updated. */ - if ((pid = (int *)alloca(sizeof(int) * count)) == NULL) - error("Call to alloca failed."); + int *pid = NULL; + if ((pid = malloc(sizeof(int) * count)) == NULL) + error("Can't allocate memory for pid."); for (int k = 0; k < count; k++) pid[k] = k; /* While there are particles that need to be updated... */ @@ -572,6 +572,9 @@ void runner_do_ghost(struct runner *r, struct cell *c) { if (count) message("Smoothing length failed to converge on %i particles.", count); + /* Be clean */ + free(pid); + TIMER_TOC(timer_do_ghost); } diff --git a/src/runner_doiact.h b/src/runner_doiact.h index 7d98c76490e3cc3f87fd2e54902273f2b7f3fa63..db439671ff5fee56c086444ddaa8268571c80a15 100644 --- a/src/runner_doiact.h +++ b/src/runner_doiact.h @@ -950,8 +950,8 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { sortdt_i = sort_i; countdt_i = count_i; } else if (ci->ti_end_min <= ti_current) { - if ((sortdt_i = (struct entry *)alloca(sizeof(struct entry) * count_i)) == - NULL) + if (posix_memalign((void *)&sortdt_i, VEC_SIZE * sizeof(float), + sizeof(struct entry) * count_i) != 0) error("Failed to allocate dt sortlists."); for (int k = 0; k < count_i; k++) if (parts_i[sort_i[k].i].ti_end <= ti_current) { @@ -963,8 +963,8 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { sortdt_j = sort_j; countdt_j = count_j; } else if (cj->ti_end_min <= ti_current) { - if ((sortdt_j = (struct entry *)alloca(sizeof(struct entry) * count_j)) == - NULL) + if (posix_memalign((void *)&sortdt_j, VEC_SIZE * sizeof(float), + sizeof(struct entry) * count_j) != 0) error("Failed to allocate dt sortlists."); for (int k = 0; k < count_j; k++) if (parts_j[sort_j[k].i].ti_end <= ti_current) { @@ -1270,6 +1270,11 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { IACT(r2q2[k], &dxq2[3 * k], hiq2[k], hjq2[k], piq2[k], pjq2[k]); #endif + if (ci->ti_end_max > ti_current && ci->ti_end_min <= ti_current) + free(sortdt_i); + if (cj->ti_end_max > ti_current && cj->ti_end_min <= ti_current) + free(sortdt_j); + TIMER_TOC(TIMER_DOPAIR); } @@ -1309,7 +1314,8 @@ void DOSELF1(struct runner *r, struct cell *restrict c) { /* Set up indt. */ int *indt = NULL; int countdt = 0, firstdt = 0; - if ((indt = (int *)alloca(sizeof(int) * count)) == NULL) + if (posix_memalign((void *)&indt, VEC_SIZE * sizeof(int), + count * sizeof(int)) != 0) error("Failed to allocate indt."); for (int k = 0; k < count; k++) if (parts[k].ti_end <= ti_current) { @@ -1499,6 +1505,8 @@ void DOSELF1(struct runner *r, struct cell *restrict c) { IACT(r2q2[k], &dxq2[3 * k], hiq2[k], hjq2[k], piq2[k], pjq2[k]); #endif + free(indt); + TIMER_TOC(TIMER_DOSELF); } @@ -1538,7 +1546,8 @@ void DOSELF2(struct runner *r, struct cell *restrict c) { /* Set up indt. */ int *indt = NULL; int countdt = 0, firstdt = 0; - if ((indt = (int *)alloca(sizeof(int) * count)) == NULL) + if (posix_memalign((void *)&indt, VEC_SIZE * sizeof(int), + count * sizeof(int)) != 0) error("Failed to allocate indt."); for (int k = 0; k < count; k++) if (parts[k].ti_end <= ti_current) { @@ -1701,6 +1710,8 @@ void DOSELF2(struct runner *r, struct cell *restrict c) { IACT(r2q2[k], &dxq2[3 * k], hiq2[k], hjq2[k], piq2[k], pjq2[k]); #endif + free(indt); + TIMER_TOC(TIMER_DOSELF); } diff --git a/src/scheduler.c b/src/scheduler.c index d760545ea74ddb288887a800c692136682f70d12..2c47851b36a1ca3b547d32d56ef810381a030054 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1298,3 +1298,16 @@ void scheduler_do_rewait(struct task *t_begin, struct task *t_end, } } } + +/** + * @brief Frees up the memory allocated for this #scheduler + */ +void scheduler_clean(struct scheduler *s) { + + free(s->tasks); + free(s->tasks_ind); + free(s->unlocks); + free(s->unlock_ind); + for (int i = 0; i < s->nr_queues; ++i) queue_clean(&s->queues[i]); + free(s->queues); +} diff --git a/src/scheduler.h b/src/scheduler.h index 62af23152e7e2d2bc68e0cc4d7122f4dd0483aa1..1822f54a87b199c8eff72ec64745bcf69be279aa 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -124,5 +124,6 @@ void scheduler_dump_queue(struct scheduler *s); void scheduler_print_tasks(const struct scheduler *s, const char *fileName); void scheduler_do_rewait(struct task *t_begin, struct task *t_end, unsigned int mask, unsigned int submask); +void scheduler_clean(struct scheduler *s); #endif /* SWIFT_SCHEDULER_H */ diff --git a/src/space.c b/src/space.c index d251139ee4308318d16116eb22683f362b6235b2..ea652f7f9b918e7f4f1ebe0a81e6604765691eb1 100644 --- a/src/space.c +++ b/src/space.c @@ -1558,3 +1558,15 @@ void space_link_cleanup(struct space *s) { /* Recursively apply the cell link cleaning routine */ space_map_cells_pre(s, 1, cell_clean_links, NULL); } + +/** + * @brief Frees up the memory allocated for this #space + */ +void space_clean(struct space *s) { + + for (int i = 0; i < s->nr_cells; ++i) cell_clean(&s->cells[i]); + free(s->cells); + free(s->parts); + free(s->xparts); + free(s->gparts); +} diff --git a/src/space.h b/src/space.h index dd182e2cdbfb427d086f763bddbd915f15ada514..a859ff5cb0497276ba5ae6dcec6a47d0ca5d7398 100644 --- a/src/space.h +++ b/src/space.h @@ -160,5 +160,6 @@ void space_do_split(struct space *s, struct cell *c); void space_do_parts_sort(); void space_do_gparts_sort(); void space_link_cleanup(struct space *s); +void space_clean(struct space *s); #endif /* SWIFT_SPACE_H */