@@ -2210,8 +2210,11 @@ fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2R
22102210{
22112211 ModelInstance * comp = (ModelInstance * )c ;
22122212 fmi2CallbackFunctions * functions = (fmi2CallbackFunctions * )comp -> functions ;
2213+ threadData_t * threadData = comp -> threadData ;
2214+ jmp_buf * old_jmp = threadData -> mmc_jumper ;
22132215 int i , zc_event = 0 , time_event = 0 ;
22142216 int flag ;
2217+ int done = 0 ;
22152218
22162219 fmi2Status status = fmi2OK ;
22172220 fmi2Real * states = comp -> states ;
@@ -2229,6 +2232,12 @@ fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2R
22292232
22302233 MemPoolState doStep_pool_state = omc_util_get_pool_state ();
22312234
2235+ setThreadData (comp );
2236+
2237+ /* try */
2238+ MMC_TRY_INTERNAL (simulationJumpBuffer )
2239+ threadData -> mmc_jumper = threadData -> simulationJumpBuffer ;
2240+
22322241 eventInfo .newDiscreteStatesNeeded = fmi2False ;
22332242 eventInfo .terminateSimulation = fmi2False ;
22342243 eventInfo .nominalsOfContinuousStatesChanged = fmi2False ;
@@ -2252,7 +2261,8 @@ fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2R
22522261 }
22532262#endif
22542263
2255- internalEventIteration (c , & eventInfo );
2264+ status = internalEventIteration (c , & eventInfo );
2265+ if (status != fmi2OK ) goto doStep_cleanup ;
22562266
22572267 /* Integration loop */
22582268 while (status == fmi2OK && comp -> fmuData -> localData [0 ]-> timeValue < tEnd )
@@ -2269,22 +2279,25 @@ fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2R
22692279 double dt = comp -> fmuData -> localData [0 ]-> timeValue - t ;
22702280 double new_input_value = realInputDerivatives [mappedIndex ] + comp -> input_real_derivative [mappedIndex ] * dt ;
22712281 if (setReal (comp , i , new_input_value ) != fmi2OK ) // to be implemented by the includer of this file
2272- return fmi2Error ;
2282+ {
2283+ status = fmi2Error ;
2284+ goto doStep_cleanup ;
2285+ }
22732286 }
22742287 }
22752288#endif
22762289
22772290#if NUMBER_OF_STATES > 0
22782291 status = internalGetDerivatives (c , states_der , NUMBER_OF_STATES );
2279- if (status != fmi2OK ) return fmi2Error ;
2292+ if (status != fmi2OK ) goto doStep_cleanup ;
22802293
22812294 status = internalGetContinuousStates (c , states , NUMBER_OF_STATES );
2282- if (status != fmi2OK ) return fmi2Error ;
2295+ if (status != fmi2OK ) goto doStep_cleanup ;
22832296#endif
22842297
22852298#if NUMBER_OF_EVENT_INDICATORS > 0
22862299 status = internalGetEventIndicators (c , event_indicators_prev , NUMBER_OF_EVENT_INDICATORS );
2287- if (status != fmi2OK ) return fmi2Error ;
2300+ if (status != fmi2OK ) goto doStep_cleanup ;
22882301#endif
22892302
22902303 /* adjust for time events */
@@ -2313,16 +2326,19 @@ fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2R
23132326 if (flag < 0 )
23142327 {
23152328 FILTERED_LOG (comp , fmi2Fatal , LOG_STATUSFATAL , "fmi2DoStep: CVODE integrator step failed." )
2316- return fmi2Fatal ;
2329+ status = fmi2Fatal ;
2330+ goto doStep_cleanup ;
23172331 }
23182332#else
23192333 FILTERED_LOG (comp , fmi2Fatal , LOG_STATUSFATAL , "fmi2DoStep: FMU not compiled with SUNDIALS but solver CVODE selected." )
2320- return fmi2Fatal ;
2334+ status = fmi2Fatal ;
2335+ goto doStep_cleanup ;
23212336#endif /* WITH_SUNDIALS */
23222337 break ;
23232338 default :
23242339 FILTERED_LOG (comp , fmi2Fatal , LOG_STATUSFATAL , "fmi2DoStep: Unknown solver method %d." , comp -> solverInfo -> solverMethod )
2325- return fmi2Fatal ;
2340+ status = fmi2Fatal ;
2341+ goto doStep_cleanup ;
23262342 }
23272343
23282344 // update time
@@ -2339,25 +2355,28 @@ fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2R
23392355 double dt = comp -> fmuData -> localData [0 ]-> timeValue - t ;
23402356 double new_input_value = realInputDerivatives [mappedIndex ] + comp -> input_real_derivative [mappedIndex ] * dt ;
23412357 if (setReal (comp , i , new_input_value ) != fmi2OK ) // to be implemented by the includer of this file
2342- return fmi2Error ;
2358+ {
2359+ status = fmi2Error ;
2360+ goto doStep_cleanup ;
2361+ }
23432362 }
23442363 }
23452364#endif
23462365
23472366 /* set the continuous states */
23482367#if NUMBER_OF_STATES > 0
23492368 status = internalSetContinuousStates (c , states , NUMBER_OF_STATES );
2350- if (status != fmi2OK ) return fmi2Error ;
2369+ if (status != fmi2OK ) goto doStep_cleanup ;
23512370#endif
23522371
23532372 /* signal completed integrator step */
23542373 status = internal_CompletedIntegratorStep (c , fmi2True , & enterEventMode , & terminateSimulation );
2355- if (status != fmi2OK ) return fmi2Error ;
2374+ if (status != fmi2OK ) goto doStep_cleanup ;
23562375
23572376 /* check for events */
23582377#if NUMBER_OF_EVENT_INDICATORS > 0
23592378 status = internalGetEventIndicators (c , event_indicators , NUMBER_OF_EVENT_INDICATORS );
2360- if (status != fmi2OK ) return fmi2Error ;
2379+ if (status != fmi2OK ) goto doStep_cleanup ;
23612380
23622381 for (i = 0 ; i < NUMBER_OF_EVENT_INDICATORS ; i ++ )
23632382 {
@@ -2382,34 +2401,53 @@ fmi2Status fmi2DoStep(fmi2Component c, fmi2Real currentCommunicationPoint, fmi2R
23822401 eventInfo .valuesOfContinuousStatesChanged = fmi2True ;
23832402 eventInfo .nextEventTimeDefined = fmi2False ;
23842403 eventInfo .nextEventTime = 0.0 ;
2385- internalEventIteration (c , & eventInfo );
2404+ status = internalEventIteration (c , & eventInfo );
2405+ if (status != fmi2OK ) goto doStep_cleanup ;
23862406
23872407 if (eventInfo .valuesOfContinuousStatesChanged )
23882408 {
23892409 #if NUMBER_OF_STATES > 0
23902410 status = internalGetContinuousStates (c , states , NUMBER_OF_STATES );
2391- if (status != fmi2OK ) return fmi2Error ;
2411+ if (status != fmi2OK ) goto doStep_cleanup ;
23922412 #endif
23932413 }
23942414
23952415 if (eventInfo .nominalsOfContinuousStatesChanged )
23962416 {
23972417 #if NUMBER_OF_STATES > 0
23982418 status = internalGetNominalsOfContinuousStates (c , states , NUMBER_OF_STATES );
2399- if (status != fmi2OK ) return fmi2Error ;
2419+ if (status != fmi2OK ) goto doStep_cleanup ;
24002420 #endif
24012421 }
24022422
24032423 #if NUMBER_OF_EVENT_INDICATORS > 0
24042424 status = internalGetEventIndicators (c , event_indicators_prev , NUMBER_OF_EVENT_INDICATORS );
2405- if (status != fmi2OK ) return fmi2Error ;
2425+ if (status != fmi2OK ) goto doStep_cleanup ;
24062426 #endif
24072427
24082428 comp -> solverInfo -> didEventStep = 1 ;
24092429 }
24102430 }
24112431
2432+ done = 1 ;
2433+
2434+ /* catch */
2435+ MMC_CATCH_INTERNAL (simulationJumpBuffer )
2436+
2437+ doStep_cleanup :
2438+ threadData -> mmc_jumper = old_jmp ;
24122439 omc_util_restore_pool_state (doStep_pool_state );
2440+ resetThreadData (comp );
2441+
2442+ if (!done )
2443+ {
2444+ if (status == fmi2OK )
2445+ {
2446+ FILTERED_LOG (comp , fmi2Error , LOG_FMI2_CALL , "fmi2DoStep: terminated by an assertion." )
2447+ status = fmi2Error ;
2448+ }
2449+ }
2450+
24132451 return status ;
24142452}
24152453
0 commit comments