%%Copyright1994-2012TheMathWorks,Inc.
%%
%%Abstract:
%%Librarythatprovideshooksfortargetstospecifyprofilingcode.
%%
 
%%Whatprofilinghooksdoweprovide?
%%-----------------------------------
%%Foranytarget,weprovidehooksforaddingprofilingcodeto
%%varioussectionsofthegeneratedcode.Thesevarioushooksare
%%asfollows:
%%-Hooktoaddheaderfile(s)whichcontainsprofilingfunction
%%declarations
%%-Hooktoaddtypedefsthatsupporttheprofiler
%%-Hooktocreateglobalvariablesforprofilerobjects
%%-Hooktoaddglobalexterndeclarationsofprofilerobjects
%%-Hooktoadddeclarationsofprofilervariableswithinthe
%%scopeofaSystem'sOutput/Update/OutputUpdate/Derivatives
%%function
%%-Hooktoaddfunctionalityforstartingtheprofileoperation
%%atthebeginningofthecodesegmentforaSystem's
%%Output/Update/OutputUpdate/Derivativesfunction
%%-Hooktoaddfunctionalityforendingtheprofileoperation
%%attheendofthecodesegmentforaSystem's
%%Output/Update/OutputUpdate/Derivativesfunction
%%-Hooktotabulatetheprofilerresultsintheterminate
%%functionofasystem.
%%
 
%%Howdoyouusetheprofilinghooksinyourtarget?
%%--------------------------------------------------
%%1.Foryourtarget,createaTLCfilecontainingfunctionsthat
%%arewrittenaccordingtotheformatspecifiedinStep3.
%%
%%2.Inyourtarget.tlcfile,createaglobalvariable
%%'ProfilerTLC'andassigntoitthenameofyourprofiling
%%TLCfile.ToturnprofilingOn/OfffromyourtargetTLC
%%file,useanotherglobalcalled'ProfileGenCode'.Makethis
%%variablehaveavalueof'TLC_TRUE'toturnonprofiling.
%%
%%3.Formatfortarget-specificprofilingTLCfile:
%%
%%Functionssection-
%%Inthissection,youshouldimplementtheTLCfunctions
%%correspondingtooneormoreofthehooksspecified
%%above.Eachfunctioniswrittenwithpre-determinedinputs
%%andoutputs.Thefunctionsandtheiroutputtypeisspecified
%%below:
%%
%%FunctionInputArgsOutputType
%%-----------------------------------------------------------
%%ProfHeadersvoidReturnarrayofheaderfilenames
%%
%%ProfTypedefsvoidOutputtypedefs
%%
%%ProfGlobalDatasystemOutputglobaldataforgivensystem
%%
%%ProfExternDataDeclssystemOutputexterndeclsforgivensystem
%%
%%ProfSysDeclsystemOutputdeclarationsforgivensystem
%%functionTypeforgivenfunctionType
%%
%%ProfSysStartsystemOutputprofilerstartcommandsfor
%%functionTypegivensystem&functionType
%%
%%ProfSysEndsystemOutputprofilerendcommandsfor
%%functionTypegivensystem&functionType
%%
%%ProfSysTerminatesystemOutputprofilerterminationcode
%%forgivensystem
 
%if EXISTS("_PROF_") == 0
%assign _PROF_ = 1
 
%function SLibSetupProf() void
 
  %if EXISTS(ProfileIncludePath) && ProfileIncludePath != ""
    %addincludepath ProfileIncludePath
  %endif
 
  %if EXISTS(ProfileGenCode) && ProfileGenCode && ...
    EXISTS(ProfilerTLC)
     
    %if !FILE_EXISTS(ProfilerTLC)
      %assign tmpStr = "fileparts(which('%<ProfilerTLC>'))"
      %assign fPath = FEVAL("eval", tmpStr)
      %if ISEMPTY(fPath)
    %assign errTxt = "%<ProfilerTLC> does not exist. You must add " ...
    "this file to the MATLAB path"
    %<LibReportError(errTxt)>
      %else
    %addincludepath fPath
      %endif
    %endif
     
    %if IsModelReferenceSimTarget()
      %assign ::ProfilerTLC = ""
      %assign warnMsg = "The Model Reference simulation target does not support " ...
    "profiling. No profiling code is generated"
      %warning %<warnMsg>
    %else
      %generatefile ProfilerType "%<ProfilerTLC>"
    %endif
  %else
    %assign ::ProfilerTLC = ""
  %endif
   
  %createrecord ::ProfilerRecord { /
    Type "ProfilerType"; /
    ProfTLCFile ProfilerTLC /
  }
   
%endfunction
   
%function ProfilerFunctionExists(fcnName) void
  %assign retVal = TLC_FALSE
  %if ::ProfilerRecord.ProfTLCFile != ""
    %assign retVal = GENERATE_FUNCTION_EXISTS(::ProfilerRecord, fcnName)
  %endif
  %return retVal
%endfunction
 
%function GetNumEffectiveSystems()
  %with ::CompiledModel
    %if IsModelReferenceTarget()
      %assign numSS = NumSystems-1
    %else
      %assign numSS = NumSystems
    %endif
 %endwith
 %return numSS
%endfunction
 
%%Function:SLibGetProfCache=============================================
%%Abstract:
%%ReturnstheProfCacherecordifitexists,emptystringotherwise
%%SLibGetProfCacheandSLibSetProfCacheareusedforpassingprofilercode
%%relatedinformationbetweenfunctions.Forexample,wecanpassglobal
%%variablenamesofprofilerobjectsbetweenProfGlbExtDataandProfGlbData
%%functionsusingthisfunctionpair.
%%
%function SLibGetProfCache(system) void
   
  %<LibReportWarning("SLibGetProfCache is obsolete. Use LibGetProfCache instead.")>
   
  %if ISFIELD(system,"ProfCache")
    %return system.ProfCache
  %else
    %return ""
  %endif
%endfunction
 
%%DocFunction{AdvancedFunctions}:LibGetProfCache============================
%%Abstract:
%%Getprofilercache.Thisfunctionisusedforpassingprofilerrelated
%%codesuchasglobalvariablenamesofprofilerobjectsbetweenTLCfunctions
%%relatedtoprofiling.
%%
%%Callsyntax:
%%%assignrec=LibGetProfCache(system)
%%
%%Returns:
%%Returnstheprofilercache.
%function LibGetProfCache(system) void
  %if ISFIELD(system,"ProfCache")
    %return system.ProfCache
  %else
    %return ""
  %endif
%endfunction
 
%%Function:SLibSetProfCache=============================================
%%Abstract:
%%AddtheProfCacherecordtosystem
%function SLibSetProfCache(system, rec) void
   
  %<LibReportWarning("SLibSetProfCache is obsolete. Use LibSetProfCache instead.")>
  
  %addtorecord system ProfCache rec
   
%endfunction
 
%%DocFunction{AdvancedFunctions}:LibSetProfCache============================
%%Abstract:
%%Addarecordtoprofilercache.Thisfunctionisusedforpassingprofiler
%%relatedcodesuchasglobalvariablenamesofprofilerobjectsbetweenTLC
%%functionsrelatedtoprofiling.
%%
%%Callsyntax:
%%LibSetProfCache(system,rec)
%%
%function LibSetProfCache(system, rec) void
  
  %addtorecord system ProfCache rec
   
%endfunction
 
%%Function:SLibGenProfHeaders============================================
%%Abstract:
%%Generatecodeforincludingprofilingheaderfiles
%%
%function SLibGenProfHeaders() void
  %assign hdr = ""
  %if ProfilerFunctionExists("ProfilerHeaders")
    %assign hdr = GENERATE(::ProfilerRecord, "ProfilerHeaders")
  %endif
  %if !ISEMPTY(hdr)
    %% hdr contains an array of header files
    %assign s = SIZE(hdr)
    %assign numHdr = s[1]
    %foreach hIdx = numHdr
      %<LibAddToCommonIncludes(hdr[hIdx])>
    %endforeach
  %endif
%endfunction
 
%%Function:SLibGenProfTypeDef============================================
%%Abstract:
%%Generatecodefortypedefsofprofilerobjects
%function SLibGenProfTypeDef() Output
  %if ProfilerFunctionExists("ProfilerTypeDefs")
    %assign tmp = GENERATE(::ProfilerRecord, "ProfilerTypeDefs")
    %<tmp>
  %endif
%endfunction
 
%%Function:SLibGenProfGlbExtData============================================
%%Abstract:
%%Generatecodeforglobalexternvariabledeclarationsofprofiler
%%objects
%function SLibGenProfGlbExtData() Output
  %if ProfilerFunctionExists("ProfilerGlobalExterns")
    %with ::CompiledModel
      %% For each system in ::CompiledModel, we check if the AddProfilerCode
      %% option is turned on, if so, generate code for global extern variable
      %% declarations of profiler objects
      %assign numSS = GetNumEffectiveSystems()
      %foreach idx = numSS
    %assign sys = System[idx]
    %assign tmp = GENERATE(::ProfilerRecord, "ProfilerGlobalExterns", sys)
    %<tmp>
      %endforeach
    %endwith
  %endif
%endfunction
 
%%Function:SLibGenProfGlbData============================================
%%Abstract:
%%Generatecodeforcreatingglobalvariablesofprofilerobjects
%function SLibGenProfGlbData() Output
  %if ProfilerFunctionExists("ProfilerGlobalData")
    %with ::CompiledModel
      %% For each system in ::CompiledModel, we check if the AddProfilerCode
      %% option is turned on, if so, generate code for creating global variables
      %% of profiler objects
      %assign numSS = GetNumEffectiveSystems()
      %foreach idx = numSS
    %assign sys = System[idx]
    %assign tmp = GENERATE(::ProfilerRecord, "ProfilerGlobalData", sys)
    %<tmp>
      %endforeach
    %endwith
  %endif
%endfunction
 
%%Function:SLibGenProfSysDeclare============================================
%%Abstract:
%%Generatecodeforaddingdeclarationsofprofilervariableswithinthe
%%scopeofaSystem'sfcn(Output/Update/OutputUpdate/Derivatives)function
%function SLibGenProfSysDeclare(system, fcn)
  %if ProfilerFunctionExists("ProfilerSystemDecls")
    %openfile tmpBuff
    %assign tmp = GENERATE(::ProfilerRecord, "ProfilerSystemDecls", system, fcn)
    %% If InLine option is turned on, we add an extra { in generated code,
    %% but only if there is anything to be emitted
    %if LibSystemIsInlined(system) && !ISEMPTY(tmp)
      {
    %endif
    %<tmp>
    %closefile tmpBuff
    %return tmpBuff
  %else
    %return ""
  %endif
%endfunction
 
%%Function:SLibGenProfSysStart============================================
%%Abstract:
%%Generatecodeforstartingtheprofileoperationatthebeginningofthe
%%codesegmentforaSystem'sfcn(Output/Update/OutputUpdate/Derivatives)
%%function
%function SLibGenProfSysStart(system, fcn)
  %if ProfilerFunctionExists("ProfilerSystemStart")
    %openfile tmpBuff
    %assign tmp = GENERATE(::ProfilerRecord, "ProfilerSystemStart", system, fcn)
    %<tmp>
    %closefile tmpBuff
    %return tmpBuff
  %else
    %return ""
  %endif
   
%endfunction
 
%%Function:SLibGenProfSysEnd============================================
%%Abstract:
%%Generatecodeforendingtheprofileoperationatthebeginningofthe
%%codesegmentforaSystem'sfcn(Output/Update/OutputUpdate/Derivatives)
%%function
%function SLibGenProfSysEnd(system, fcn)
  %if ProfilerFunctionExists("ProfilerSystemFinish")
    %openfile tmpBuff
    %assign tmp = GENERATE(::ProfilerRecord, "ProfilerSystemFinish", system, fcn)
    %<tmp>
    %% If InLine option is turned on, we add } in the generated code,
    %% but only if there was anything emitted in the decls section. Easiest
    %% thing to do is figure it out again.
    %if LibSystemIsInlined(system)
        %assign tmp = GENERATE(::ProfilerRecord, "ProfilerSystemDecls", system, fcn)
        %if !ISEMPTY(tmp)
            }
        %endif
    %endif
    %closefile tmpBuff
    %return tmpBuff
  %else
    %return ""
  %endif
%endfunction
 
%%Function:SLibGenProfSysTerminate========================================
%%Abstract:
%%Generatecodefortabulatingtheprofilerresultsintheterminate
%%functionofasystem
%function SLibGenProfSysTerminate(system)
  %if ProfilerFunctionExists("ProfilerSystemTerminate")
    %openfile tmpBuff
    %assert IsBaseSystem(system)
    %with ::CompiledModel
      %assign numSS = GetNumEffectiveSystems()
      %foreach idx = numSS
    %assign sys = System[idx]
    %assign tmp = GENERATE(::ProfilerRecord, "ProfilerSystemTerminate", sys)
    %<tmp>
      %endforeach
      %closefile tmpBuff
    %endwith
    %return tmpBuff
  %else
    %return ""
  %endif
%endfunction
 
%endif %% _PROF_
 
%%[EOF]prof.tlc