%%
%%
%%
%%
%%Copyright1994-2019TheMathWorks,Inc.
%%
%%Abstract:
%%LibrarytosupportthenotionofanrtModelobject.
%%CurrentlyalsocontainsroutinesforrootSimStruct
%%
 
%if EXISTS("_RTMDLSUPLIB_") == 0
%assign _RTMDLSUPLIB_ = 1
 
%%Function:SLibSkipMallocForCoderDataGroup========================================
%%Abstract:
%%returntrueifneedtoallocatememoryforacoderdatagroup
%%
%function SLibSkipMallocForCoderDataGroup(group) void
  %if LibCoderDataGroupStructIsEmpty(group) || ...
    !SLibAccessViaPointerInSelf(group) || ...
    (group.IsSelf && group.AsStructure != "None")
    %return TLC_TRUE
  %else
    %return TLC_FALSE
  %endif
%endfunction
 
%%Function:SLibFreeCoderDataGroups========================================
%%Abstract:
%%Freememoryforcoderdatagroups
%%
%function SLibFreeCoderDataGroups() Output
  %foreach idx = ::CompiledModel.NumCoderDataGroups
    %assign group = ::CompiledModel.CoderDataGroup[idx]
     
    %if !SLibSkipMallocForCoderDataGroup(group)
      /* Free %<group.Identification> */
      %if SLibIsSelfStructured() && group.AsStructure == "InParent"
        rt_FREE(%<SLibGetCoderDataGroupPointerFromRTM(group, 0)>);
      %else
        %if ::CompiledModel.HasSimStructVars == 0
          %assign rtmField = SLibCoderDataGroupRTMFieldName(group)
          rt_FREE(%<RTMGet(rtmField)>);
        %endif
      %endif
    %endif
  %endforeach
%endfunction
 
%%Function:SLibGenRootTermMemFreeCode========================================
%%Abstract:
%%DumpmemoryfreecodeinMdlTerminatewhenweareusingUsingMalloc
%%
%function SLibGenRootTermMemFreeCode() Output
  %assign isSfcnCF = (CodeFormat == "S-Function")
  %assign s = ::tChildSimStruct
 
  %% Free the rest of the model. Note these dependencies.
  %% o free everything in mdlInfo
  %% o free mdlInfo
  %% o free SimStruct
  %%
  %if isSfcnCF
    #if defined(RT_MALLOC) || defined(MATLAB_MEX_FILE)
  %endif
  %if NumChildSFunctions > 0 && !SLibIsERTCodeFormat()
       
    /* child S-function code */
    if( %<RTMuGet("SFunctions")> ) {
      %foreach childIdx = NumChildSFunctions
    %assign thisBlock = ChildSFunctionList[childIdx]
    %with thisBlock
      /* %<TypeLevel> Block: '%<Name>' (%<ParamSettings.FunctionName>) */
      {
        SimStruct *%<s> = %<RTMGetIdxed("SFunction", childIdx)>;
        %<SLibGenChildSfcnTermMemFreeCode(s)>
      }
    %endwith
      %endforeach
      %%
      %% Free all the child SimStructs in one shot. All children
      %% were allocated in a single malloc.
      %%
      rt_FREE(%<RTMGetIdxed("SFunction", 0)>)
       
      %% Free the array of child SimStruct pointers
      rt_FREE(%<RTMuGet("SFunctions")>);
    }
  %endif %% NumChildSFunctions > 0
  
  %if isSfcnCF
    %% Free memory allocated in model_malloc()
    if ( %<RTMGet("UserData")> != %<SLibGetNullDefinitionFromTfl()> ) {
      %if NumBlockSignals > 0
    rt_FREE(%<RTMGet("LocalBlockIO")>);
      %endif
      %if NumZCEvents > 0
    rt_FREE(%<RTMuGet("PrevZCSigState")>);
      %endif
      %if SolverType == "VariableStep" && ...
    SolverResetInfo.NumNonContDerivSignals > 0
        rt_FREE(%<RTMGet("LocalNonContDerivSig")>);
      %endif
    }
    rt_FREE(%<RTMGet("UserData")>);
  %else
    %if !IsModelReferenceTarget() && !LibIsDeploymentDiagram() && !PurelyIntegerCode && ...
      (LibIsContinuous(0) || NumChildSFunctions) || GenerateGRTWrapper
      %% If the above checks are changed, please also update the checks for
      %% solver data creation code (ertlib.tlc)
      rt_FREE(%<RTMGet("RTWSolverInfo")>);
    %endif
    %% Conversion of grt malloc to ert core means that the
    %% solverInfo member of the RT model struct is now an
    %% inlined structure rather than a pointer to dynamically
    %% allocated memory.
    %if !SLibIsERTCodeFormat()
      rt_FREE(%<RTMGet("RTWSfcnInfo")>);
    %endif
 
    /* model code */
    %if !LibBlockIOStructIsEmpty() && !SLibIsSelfStructured()
      rt_FREE(%<RTMGet("BlockIO")>);
    %endif
    %if !LibContStatesStructIsEmpty()
      rt_FREE(%<RTMGet("ContStates")>);
    %endif
    %if !LibPeriodicCStatesStructIsEmpty()
      rt_FREE(%<RTMGet("PeriodicContStateIndices")>);
      rt_FREE(%<RTMGet("PeriodicContStateRanges")>);
    %endif
    %if !LibExternalInputsStructIsEmpty() && ::CompiledModel.RootIOFormat == "Part of model data structure"
      rt_FREE(%<RTMGet("U")>);
    %endif
    %if !LibExternalOutputsStructIsEmpty() && ::CompiledModel.RootIOFormat == "Part of model data structure"
      rt_FREE(%<RTMGet("Y")>);
    %endif
    %if !LibParametersStructIsEmpty() && !FcnParamsAreGlobalStruct()
      if (%<RTMGet("ParamIsMalloced")>) {
        rt_FREE(%<RTMGet("DefaultParam")>);
      }
    %endif
    %if !LibDWorkStructIsEmpty() && !SLibIsSelfStructured()
      rt_FREE(%<RTMGet("RootDWork")>);
    %endif
    %if !LibPrevZCStatesStructIsEmpty() && !SLibIsSelfStructured()
      rt_FREE(%<RTMGet("PrevZCSigState")>);
    %endif
    %if ExtMode == 1
      {
    DataTypeTransInfo *dtInfo = (DataTypeTransInfo *) ...
      %<RTMGet("ModelMappingInfo")>;
    %if !LibBlockIOStructIsEmpty()
      DataTypeTransitionTable *BTransTable = ...
        dtGetBIODataTypeTrans(dtInfo);
    %endif
     
    %if !LibBlockIOStructIsEmpty()
      rt_FREE(dtGetTransitions(BTransTable));
      rt_FREE(BTransTable);
    %endif
    %if LibGetNumDataTypesInModel() > 0
      rt_FREE(dtGetDataTypeSizes(dtInfo));
      {
        void *ptr = (void *) dtGetDataTypeNames(dtInfo);
        rt_FREE(ptr);
      }
    %endif
    rt_FREE(dtInfo);
      }
    %endif
     
    %if !SLibIsERTCodeFormat()
        rt_FREE(%<RTMGet("SampleTimePtr")>);
        rt_FREE(%<RTMGet("OffsetTimePtr")>);
        rt_FREE(%<RTMGet("SampleTimeTaskIDPtr")>);
        rt_FREE(%<RTMGet("TPtr")>);
        rt_FREE(%<RTMGet("SampleHitPtr")>);
        %if ::CompiledModel.SolverType == "FixedStep"
          %if ::CompiledModel.FixedStepOpts.SolverMode == "MultiTasking"
            rt_FREE(%<RTMGet("PerTaskSampleHitsPtr")>);
          %endif
        %endif
    %endif
    %if MatFileLogging
      {
    void *xptr = (void *) %<RTMLoggingGet("LogXSignalPtrs")>;
    void *yptr = (void *) %<RTMLoggingGet("LogYSignalPtrs")>;
    rt_FREE(xptr);
    rt_FREE(yptr);
      }
      rt_FREE(%<RTMGet("RTWLogInfo")>);
    %endif
    %if !GenRTModel
      rt_FREE(%<RTMGet("MdlInfoPtr")>);
    %endif
    %if (RTWCAPI && (::CompiledModel.NumDataAddrInMap > 0) && !SLibIsERTCodeFormat())
    rt_FREE(%<RTMGet("DataMapInfo")>.mmi.InstanceMap.dataAddrMap);
    %endif
     
    %if UsingMalloc
      %<SLibFreeCoderDataGroups()>
    %endif
     
    rt_FREE(%<RTMGetModelSS()>);
  %endif
  %if isSfcnCF
    #endif
  %endif
%endfunction %% SLibGenRootTermMemFreeCode
 
 
%endif %% _RTMDLSUPLIB_
 
%%[EOF]rtmdlsuplib.tlc