function hLib = crlHostTimer()
% CRLHOSTTIMER returns details of a host timer function

%   Copyright 2009-2016 The MathWorks, Inc.

    % If the 'advanced timer' feature is turned on, use a timer that allows for
    % thread preemption. This avoids outliers that may otherwise occur when
    % using the Time Stamp Counter if a thread is preempted while the profiled
    % section of code is executing (g733501).
    compileFlags = {};
    linkFlags = {};
    csaSettings = coder.profile.pmu.csaTimer;
    if any(strcmp(computer, {'GLNX86', 'GLNXA64'}))
        if csaSettings.CSA && ~isempty(csaSettings.HWCounter)
            [compileFlags, linkFlags] = coder.profile.pmu.HWCountConfigurationHostBasedTargets.getFlags;
        elseif csaSettings.CSA
        % On Linux use clock_gettime
            linkFlags = {'-lrt'};
        end
    end
    
    key = 'code_profile_read_timer';
    
    [timerSourceFile, headerFile, implName, dataType] = ...
        coder.profile.getHostTimerInfo();
    
    [p,f,e]=fileparts(timerSourceFile);
    implSrc = [f e];
    srcPath = p;
    [~,f,e]=fileparts(headerFile);
    implHdr = [f e];
    
    
    % Create the TFL Table with a timer entry
    hLib = RTW.TflTable;
    fcn_entry = RTW.TflCFunctionEntry;
    fcn_entry.setTflCFunctionEntryParameters( ...
        'Key',                      key, ...
        'ImplementationName',       implName, ...
        'ImplementationHeaderFile', implHdr, ...
        'ImplementationSourceFile', implSrc, ...
        'AdditionalCompileFlags',   compileFlags, ...
        'AdditionalLinkFlags',      linkFlags);
    
    fcn_entry.addAdditionalSourcePath(srcPath);
    fcn_entry.addAdditionalIncludePath(srcPath);
    
    fcn_entry.EntryInfo.CountDirection = 'RTW_TIMER_UP';
    
    arg = hLib.getTflArgFromString('y1',dataType);
    arg.IOType = 'RTW_IO_OUTPUT';
    fcn_entry.addConceptualArg(arg);
    
    % For the execution profiling timer function, the implementation arguments 
    % must be a copy of the conceptual arguments
    fcn_entry.copyConceptualArgsToImplementation();
    
    % ticks per second depends on the CPU clock frequency
    % if the clock frequency is not reliable, use the default value of zero
    if csaSettings.CSA 
        if isempty(csaSettings.HWCounter)
            % csa timer - the unit of time depends on the used API
            if ispc
                % on PCWIN64, the API returns ticks
                fcn_entry.EntryInfo.TicksPerSecond = 0;
            elseif ismac
                % on MAC, the API returns us (microseconds)
                fcn_entry.EntryInfo.TicksPerSecond = 1000000;
            else
                % on GLNXA64, the API returns ns (nanoseconds)
                fcn_entry.EntryInfo.TicksPerSecond = 1000000000;
            end
        else
            % HW counters - the unit of measurements depends on the counter
            fcn_entry.EntryInfo.TicksPerSecond = 0;
        end
    else
        fcn_entry.EntryInfo.TicksPerSecond = feval('_coder_profile_getClkSpeed');
    end
    
    hLib.addEntry( fcn_entry );
        
end

