Skip to content

Commit

Permalink
Fix some unsafe code using setjmp/longjmp
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@16390 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Jun 18, 2013
1 parent 8d1b09a commit 1609ed0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 63 deletions.
11 changes: 3 additions & 8 deletions SimulationRuntime/c/simulation/solver/dassl.c
Original file line number Diff line number Diff line change
Expand Up @@ -504,25 +504,20 @@ int functionODE_residual(double *t, double *y, double *yd, double *delta,
saveJumpState = currectJumpState;
currectJumpState = ERROR_INTEGRATOR;

mem_state = get_memory_state();
/* try */
if (!setjmp(integratorJmpbuf))
{
mem_state = get_memory_state();

functionODE(data);

/* get the difference between the temp_xd(=localData->statesDerivatives)
and xd(=statesDerivativesBackup) */
for(i=0; i < data->modelData.nStates; i++)
{
for(i=0; i < data->modelData.nStates; i++) {
delta[i] = data->localData[0]->realVars[data->modelData.nStates + i] - yd[i];
}

restore_memory_state(mem_state);
}
/* catch */
else
{
} else { /* catch */
restore_memory_state(mem_state);
*ires = -1;
}
Expand Down
71 changes: 30 additions & 41 deletions SimulationRuntime/c/simulation/solver/nonlinearSolverHybrd.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ static int wrapper_fvec_hybrj(integer* n, double* x, double* f, double* fjac, in
*
* \author wbraun
*/
int solveHybrd(DATA *data, int sysNumber)
static int solveHybrdWork(DATA *data, int sysNumber)
{
NONLINEAR_SYSTEM_DATA* systemData = &(data->simulationInfo.nonlinearSystemData[sysNumber]);
DATA_HYBRD* solverData = (DATA_HYBRD*)systemData->solverData;
Expand All @@ -406,7 +406,6 @@ int solveHybrd(DATA *data, int sysNumber)
int assertCalled = 0;
int assertRetries = 0;
int assertMessage = 0;
state mem_state;

modelica_boolean* relationsPreBackup;
relationsPreBackup = (modelica_boolean*) malloc(data->modelData.nRelations*sizeof(modelica_boolean));
Expand Down Expand Up @@ -445,20 +444,14 @@ int solveHybrd(DATA *data, int sysNumber)
solverData->useXScaling = 0;

/* try */
if (!setjmp(nonlinearJmpbuf))
{
mem_state = get_memory_state();
if (!setjmp(nonlinearJmpbuf)) {
wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, data);
restore_memory_state(mem_state);
}
/* catch */
else
{
restore_memory_state(mem_state);
} else { /* catch */
WARNING(LOG_STDOUT, "Non-Linear Solver try to handle a problem with a called assert.");
}
if(scaling)
if(scaling) {
solverData->useXScaling = 1;
}
}

/* start solving loop */
Expand All @@ -469,56 +462,49 @@ int solveHybrd(DATA *data, int sysNumber)
solverData->xScalefactors[i] = fmax(fabs(solverData->x[i]), systemData->nominal[i]);

/* debug output */
if(ACTIVE_STREAM(LOG_NLS_V))
{
if(ACTIVE_STREAM(LOG_NLS_V)) {
printVector(solverData->xScalefactors, &(solverData->n), LOG_NLS_V, "scaling factors x vector");
printVector(solverData->x, &(solverData->n), LOG_NLS_V, "Iteration variable values");
}

/* Scaling x vector */
if(solverData->useXScaling)
for(i=0; i<solverData->n; i++)
if(solverData->useXScaling) {
for(i=0; i<solverData->n; i++) {
solverData->x[i] = (1.0/solverData->xScalefactors[i]) * solverData->x[i];
}
}

/* debug output */
if(ACTIVE_STREAM(LOG_NLS_V))
if (ACTIVE_STREAM(LOG_NLS_V)) {
printVector(solverData->x, &solverData->n, LOG_NLS_V, "Iteration variable values (scaled)");
}

/* set residual function continuous
*/
if(continuous)
if(continuous) {
((DATA*)data)->simulationInfo.solveContinuous = 1;
else
} else {
((DATA*)data)->simulationInfo.solveContinuous = 0;
}

giveUp = 1;

/* try */
if (!setjmp(nonlinearJmpbuf))
{
mem_state = get_memory_state();
if (!setjmp(nonlinearJmpbuf)) {
_omc_hybrj_(wrapper_fvec_hybrj, &solverData->n, solverData->x,
solverData->fvec, solverData->fjac, &solverData->ldfjac, &solverData->xtol,
&solverData->maxfev, solverData->diag, &solverData->mode,
&solverData->factor, &solverData->nprint, &solverData->info,
&solverData->nfev, &solverData->njev, solverData->r__,
&solverData->lr, solverData->qtf, solverData->wa1,
solverData->wa2, solverData->wa3, solverData->wa4, data);
restore_memory_state(mem_state);
if (assertCalled){
INFO(LOG_NLS, "After asserts was called, values reached which avoided assert call.");
memcpy(systemData->nlsxOld, solverData->x, solverData->n*(sizeof(double)));
}

assertRetries = 0;
assertCalled = 0;

}
/* catch */
else
{
restore_memory_state(mem_state);

} else { /* catch */
if (!assertMessage){
INDENT(LOG_STDOUT);
WARNING(LOG_STDOUT, "While solving non-linear system an assert was called.");
Expand All @@ -536,10 +522,11 @@ int solveHybrd(DATA *data, int sysNumber)
}

/* set residual function continuous */
if(continuous)
if (continuous) {
((DATA*)data)->simulationInfo.solveContinuous = 0;
else
} else {
((DATA*)data)->simulationInfo.solveContinuous = 1;
}

/* re-scaling x vector */
if(solverData->useXScaling)
Expand All @@ -564,15 +551,8 @@ int solveHybrd(DATA *data, int sysNumber)
/* try */
if (!setjmp(nonlinearJmpbuf))
{
mem_state = get_memory_state();
wrapper_fvec_hybrj(&solverData->n, solverData->x, solverData->fvec, solverData->fjac, &solverData->ldfjac, &iflag, data);
restore_memory_state(mem_state);
}
/* catch */
else
{
restore_memory_state(mem_state);

} else { /* catch */
WARNING(LOG_STDOUT, "Non-Linear Solver try to handle a problem with a called assert.");

solverData->info = -1;
Expand Down Expand Up @@ -978,3 +958,12 @@ int solveHybrd(DATA *data, int sysNumber)

return success;
}

int solveHybrd(DATA *data, int sysNumber)
{
int res;
state mem_state = get_memory_state();
res = solveHybrdWork(data,sysNumber);
restore_memory_state(mem_state);
return res;
}
18 changes: 9 additions & 9 deletions SimulationRuntime/c/simulation/solver/perform_simulation.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,16 +114,15 @@ int performSimulation(DATA* data, SOLVER_INFO* solverInfo)
/***** Start main simulation loop *****/
while(solverInfo->currentTime < simInfo->stopTime)
{
mem_state = get_memory_state();
/* try */
if (!setjmp(simulationJmpbuf))
{
mem_state = get_memory_state();
if (!setjmp(simulationJmpbuf)) {
currectJumpState = ERROR_SIMULATION;

if(measure_time_flag)
{
for(i = 0; i < data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++)
if (measure_time_flag) {
for(i = 0; i < data->modelData.modelDataXml.nFunctions + data->modelData.modelDataXml.nProfileBlocks; i++) {
rt_clear(i + SIM_TIMER_FIRST_FUNCTION);
}
rt_clear(SIM_TIMER_STEP);
rt_tick(SIM_TIMER_STEP);
}
Expand All @@ -138,14 +137,15 @@ int performSimulation(DATA* data, SOLVER_INFO* solverInfo)
if(solverInfo->offset + DBL_EPSILON > simInfo->stepSize)
solverInfo->offset = 0;
INFO1(LOG_SOLVER, "offset value for the next step: %.10f", solverInfo->offset);
}
else
} else {
solverInfo->offset = 0;
}
solverInfo->currentStepSize = simInfo->stepSize - solverInfo->offset;

/* adjust final step? */
if(solverInfo->currentTime + solverInfo->currentStepSize > simInfo->stopTime)
if(solverInfo->currentTime + solverInfo->currentStepSize > simInfo->stopTime) {
solverInfo->currentStepSize = simInfo->stopTime - solverInfo->currentTime;
}
/***** End calculation next step size *****/

/* check for next time event */
Expand Down
11 changes: 6 additions & 5 deletions SimulationRuntime/c/util/memory_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,7 @@ void pop_memory_states(void* new_states)

state get_memory_state(void)
{
if(current_states == NULL)
{
if (current_states == NULL) {
push_memory_states(1);
}
return current_states[get_thread_index()].current_state;
Expand All @@ -86,18 +85,19 @@ void print_current_state(void)
state current_state = current_states[0].current_state;
printf("=== Current state ===\n");
printf(" buffer: %d\n",(int)current_state.buffer);
printf(" offste: %d\n",(int)current_state.offset);
printf(" offset: %d\n",(int)current_state.offset);
}

void print_state(state s)
{
printf("=== State ===\n");
printf(" buffer: %d\n",(int)s.buffer);
printf(" offste: %d\n",(int)s.offset);
printf(" offset: %d\n",(int)s.offset);
}

void restore_memory_state(state restore_state)
{
assert(restore_state.buffer == 0);
current_states[get_thread_index()].current_state = restore_state;
}

Expand All @@ -119,8 +119,9 @@ void* alloc_elements(int n, int sz)
if(current_states[ix].nbuffers == (current_states[ix].current_state.buffer + 1)) {
/* We need to allocate another region */
current_states[ix].buffer=realloc(current_states[ix].buffer,sizeof(int*)*current_states[ix].nbuffers);
current_states[ix].buffer[current_states[ix].nbuffers]=malloc(sizeof(int)*NR_ELEMENTS);
assert(current_states[ix].buffer);
current_states[ix].buffer[current_states[ix].nbuffers]=malloc(sizeof(int)*NR_ELEMENTS);
assert(current_states[ix].buffer[current_states[ix].nbuffers]);
}
current_states[ix].current_state.buffer = current_states[ix].nbuffers++;
current_states[ix].current_state.offset = 0;
Expand Down

0 comments on commit 1609ed0

Please sign in to comment.