Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit b9d5e4a

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Clear the extra memory pools on each iteration
https://trac.openmodelica.org/OpenModelica/ticket/5406 Belonging to [master]: - #3022
1 parent 09f079c commit b9d5e4a

3 files changed

Lines changed: 33 additions & 18 deletions

File tree

SimulationRuntime/c/gc/memory_pool.c

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ static list *memory_pools = NULL;
6161

6262
static void pool_init(void)
6363
{
64-
memory_pools = (list*) malloc(sizeof(list));
64+
memory_pools = (list*) omc_alloc_interface.malloc_uncollectable(sizeof(list));
6565
memory_pools->used = 0;
6666
memory_pools->size = 2*1024*1024; /* 2MB pool by default */
67-
memory_pools->memory = malloc(memory_pools->size);
67+
memory_pools->memory = omc_alloc_interface.malloc_uncollectable(memory_pools->size);
6868
memory_pools->next = NULL;
6969
}
7070

@@ -95,12 +95,12 @@ static inline void pool_expand(size_t len)
9595
if (memory_pools->size - memory_pools->used >= len) {
9696
return;
9797
}
98-
newlist = (list*) malloc(sizeof(list));
98+
newlist = (list*) omc_alloc_interface.malloc_uncollectable(sizeof(list));
9999
newlist->next = memory_pools;
100100
memory_pools = newlist;
101101
memory_pools->used = 0;
102102
memory_pools->size = upper_power_of_two(3*memory_pools->next->size/2 + len); /* expand by 1.5x the old memory pool. More if we request a very large array. */
103-
memory_pools->memory = malloc(memory_pools->size);
103+
memory_pools->memory = omc_alloc_interface.malloc_uncollectable(memory_pools->size);
104104
}
105105

106106
static void* pool_malloc(size_t sz)
@@ -120,20 +120,30 @@ static void* pool_malloc(size_t sz)
120120
return res;
121121
}
122122

123-
static int pool_free(void)
123+
static int pool_free_extra_list(void)
124124
{
125125
list *freelist = memory_pools->next;
126126
while (freelist) {
127127
list *next = freelist->next;
128-
free(freelist->memory);
129-
free(freelist);
128+
omc_alloc_interface.free_uncollectable(freelist->memory);
129+
omc_alloc_interface.free_uncollectable(freelist);
130130
freelist = next;
131131
}
132132
memory_pools->used = 0;
133133
memory_pools->next = 0;
134134
return 0;
135135
}
136136

137+
void free_memory_pool()
138+
{
139+
pool_free_extra_list();
140+
if (memory_pools) {
141+
omc_alloc_interface.free_uncollectable(memory_pools->memory);
142+
omc_alloc_interface.free_uncollectable(memory_pools);
143+
memory_pools = NULL;
144+
}
145+
}
146+
137147
static void nofree(void* ptr)
138148
{
139149
}
@@ -148,7 +158,7 @@ omc_alloc_interface_t omc_alloc_interface_pooled = {
148158
pool_malloc,
149159
(char*(*)(size_t)) malloc,
150160
strdup,
151-
pool_free,
161+
pool_free_extra_list,
152162
malloc_zero,
153163
free,
154164
malloc,
@@ -215,7 +225,7 @@ omc_alloc_interface_t omc_alloc_interface = {
215225
pool_malloc,
216226
(char*(*)(size_t)) malloc,
217227
strdup,
218-
pool_free,
228+
pool_free_extra_list,
219229
malloc_zero /* calloc, but with malloc interface */,
220230
free,
221231
malloc,

SimulationRuntime/c/gc/memory_pool.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ extern _index_t** index_alloc(int n);
4848

4949
void* generic_alloc(int n, size_t sze);
5050

51+
void free_memory_pool();
52+
5153
#if defined(__cplusplus)
5254
} /* end extern "C" */
5355
#endif

SimulationRuntime/fmi/export/openmodelica/fmu2_model_interface.c.inc

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ static inline void resetThreadData(ModelInstance* comp)
193193
if (comp->threadDataParent) {
194194
pthread_setspecific(mmc_thread_data_key, comp->threadDataParent);
195195
}
196+
/* Clear the extra memory pools */
197+
omc_alloc_interface.collect_a_little();
196198
}
197199

198200
static inline void setThreadData(ModelInstance* comp)
@@ -362,23 +364,23 @@ fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2Str
362364
* The problem is that we might overwrite the main simulation's copy of the interface...
363365
*/
364366
threadData_t *threadDataParent = (threadData_t*) pthread_getspecific(mmc_thread_data_key);
365-
if (0==threadDataParent) {
366-
/* We can only disable GC if the parent is not OM */
367-
omc_alloc_interface = omc_alloc_interface_pooled;
368-
}
369-
mmc_init_nogc();
370-
omc_alloc_interface.init();
371-
372-
// ignoring arguments: fmuResourceLocation, visible
373367
ModelInstance *comp;
374368
if (!functions->logger) {
375369
return NULL;
376370
}
377-
378371
if (!functions->allocateMemory || !functions->freeMemory) {
379372
functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error", "fmi2Instantiate: Missing callback function.");
380373
return NULL;
381374
}
375+
if (0==threadDataParent) {
376+
/* We can only disable GC if the parent is not OM */
377+
omc_alloc_interface = omc_alloc_interface_pooled;
378+
/* TODO: omc_alloc_interface.malloc_uncollectable = functions->allocateMemory; // Note that the interface is wrong. Should pass threadData to all allocations instead, and have the interface in there. */
379+
}
380+
mmc_init_nogc();
381+
omc_alloc_interface.init();
382+
383+
// ignoring arguments: fmuResourceLocation, visible
382384
if (!instanceName || strlen(instanceName) == 0) {
383385
functions->logger(functions->componentEnvironment, instanceName, fmi2Error, "error", "fmi2Instantiate: Missing instance name.");
384386
return NULL;
@@ -544,6 +546,7 @@ void fmi2FreeInstance(fmi2Component c)
544546
if (comp->functions) comp->functions->freeMemory((void*)comp->functions);
545547
/* free comp */
546548
freeMemory(comp);
549+
free_memory_pool();
547550
}
548551

549552
fmi2Status fmi2SetupExperiment(fmi2Component c, fmi2Boolean toleranceDefined, fmi2Real tolerance, fmi2Real startTime, fmi2Boolean stopTimeDefined, fmi2Real stopTime)

0 commit comments

Comments
 (0)