/** * Copyright (C) Mellanox Technologies Ltd. 2001-2018. ALL RIGHTS RESERVED. * * See file LICENSE for terms. */ #ifndef UCS_PROFILE_ON_H_ #define UCS_PROFILE_ON_H_ #include "profile_defs.h" #include #include #include BEGIN_C_DECLS /** @file profile_on.h */ /* Helper macro */ #define _UCS_PROFILE_RECORD(_type, _name, _param64, _param32, _loc_id_p) \ { \ if (*(_loc_id_p) != 0) { \ ucs_profile_record((_type), (_name), (_param64), (_param32), \ __FILE__, __LINE__, __FUNCTION__, (_loc_id_p)); \ } \ } /* Helper macro */ #define __UCS_PROFILE_CODE(_name, _loop_var) \ int _loop_var ; \ for (({ UCS_PROFILE_SCOPE_BEGIN(); _loop_var = 1;}); \ _loop_var; \ ({ UCS_PROFILE_SCOPE_END(_name); _loop_var = 0;})) /* Helper macro */ #define _UCS_PROFILE_CODE(_name, _var_suffix) \ __UCS_PROFILE_CODE(_name, UCS_PP_TOKENPASTE(loop, _var_suffix)) /** * Record a profiling event. * * @param _type Event type. * @param _name Event name. * @param _param32 Custom 32-bit parameter. * @param _param64 Custom 64-bit parameter. */ #define UCS_PROFILE(_type, _name, _param32, _param64) \ { \ static int loc_id = -1; \ _UCS_PROFILE_RECORD((_type), (_name), (_param32), (_param64), &loc_id); \ } /** * Record a profiling sample event. * * @param _name Event name. */ #define UCS_PROFILE_SAMPLE(_name) \ UCS_PROFILE(UCS_PROFILE_TYPE_SAMPLE, (_name), 0, 0) /** * Record a scope-begin profiling event. */ #define UCS_PROFILE_SCOPE_BEGIN() \ { \ UCS_PROFILE(UCS_PROFILE_TYPE_SCOPE_BEGIN, "", 0, 0); \ ucs_compiler_fence(); \ } /** * Record a scope-end profiling event. * * @param _name Scope name. */ #define UCS_PROFILE_SCOPE_END(_name) \ { \ ucs_compiler_fence(); \ UCS_PROFILE(UCS_PROFILE_TYPE_SCOPE_END, _name, 0, 0); \ } /** * Declare a profiled scope of code. * * Usage: * UCS_PROFILE_CODE() { * * } * * @param _name Scope name. */ #define UCS_PROFILE_CODE(_name) \ _UCS_PROFILE_CODE(_name, UCS_PP_UNIQUE_ID) /** * Create a profiled function. * * Usage: * UCS_PROFILE_FUNC(, , (a, b), int a, char b) * * @param _ret_type Function return type. * @param _name Function name. * @param _arglist List of argument *names* only. * @param ... Argument declarations (with types). */ #define UCS_PROFILE_FUNC(_ret_type, _name, _arglist, ...) \ static UCS_F_ALWAYS_INLINE _ret_type _name##_inner(__VA_ARGS__); \ \ _ret_type _name(__VA_ARGS__) { \ UCS_PROFILE_SCOPE_BEGIN(); \ _ret_type _ret = _name##_inner _arglist; \ UCS_PROFILE_SCOPE_END(#_name); \ return _ret; \ } \ static UCS_F_ALWAYS_INLINE _ret_type _name##_inner(__VA_ARGS__) /** * Create a profiled function whose return type is void. * * Usage: * UCS_PROFILE_FUNC_VOID(, (a, b), int a, char b) * * @param _name Function name. * @param _arglist List of argument *names* only. * @param ... Argument declarations (with types). */ #define UCS_PROFILE_FUNC_VOID(_name, _arglist, ...) \ static UCS_F_ALWAYS_INLINE void _name##_inner(__VA_ARGS__); \ \ void _name(__VA_ARGS__) { \ UCS_PROFILE_SCOPE_BEGIN(); \ _name##_inner _arglist; \ UCS_PROFILE_SCOPE_END(#_name); \ } \ static UCS_F_ALWAYS_INLINE void _name##_inner(__VA_ARGS__) /* * Profile a function call, and specify explicit name string for the profile. * Useful when calling a function by a pointer. * * Usage: * UCS_PROFILE_NAMED_CALL("name", function, arg1, arg2) * * @param _name Name string for the profile. * @param _func Function name. * @param ... Function call arguments. */ #define UCS_PROFILE_NAMED_CALL(_name, _func, ...) \ ({ \ typeof(_func(__VA_ARGS__)) retval; \ UCS_PROFILE_SCOPE_BEGIN(); \ retval = _func(__VA_ARGS__); \ UCS_PROFILE_SCOPE_END(_name); \ retval; \ }) /* * Profile a function call. * * Usage: * UCS_PROFILE_CALL(function, arg1, arg2) * * @param _func Function name. * @param ... Function call arguments. */ #define UCS_PROFILE_CALL(_func, ...) \ UCS_PROFILE_NAMED_CALL(#_func, _func, ## __VA_ARGS__) /* * Profile a function call which does not return a value, and specify explicit * name string for the profile. Useful when calling a function by a pointer. * * Usage: * UCS_PROFILE_NAMED_CALL_VOID("name", function, arg1, arg2) * * @param _name Name string for the profile. * @param _func Function name. * @param ... Function call arguments. */ #define UCS_PROFILE_NAMED_CALL_VOID(_name, _func, ...) \ { \ UCS_PROFILE_SCOPE_BEGIN(); \ _func(__VA_ARGS__); \ UCS_PROFILE_SCOPE_END(_name); \ } /* * Profile a function call which does not return a value. * * Usage: * UCS_PROFILE_CALL_VOID(function, arg1, arg2) * * @param _func Function name. * @param ... Function call arguments. */ #define UCS_PROFILE_CALL_VOID(_func, ...) \ UCS_PROFILE_NAMED_CALL_VOID(#_func, _func, ## __VA_ARGS__) /* * Profile a new request allocation. * * @param _req Request pointer. * @param _name Allocation site name. * @param _param32 Custom 32-bit parameter. */ #define UCS_PROFILE_REQUEST_NEW(_req, _name, _param32) \ UCS_PROFILE(UCS_PROFILE_TYPE_REQUEST_NEW, (_name), (_param32), (uintptr_t)(_req)); /* * Profile a request progress event. * * @param _req Request pointer. * @param _name Event name. * @param _param32 Custom 32-bit parameter. */ #define UCS_PROFILE_REQUEST_EVENT(_req, _name, _param32) \ UCS_PROFILE(UCS_PROFILE_TYPE_REQUEST_EVENT, (_name), (_param32), (uintptr_t)(_req)); /* * Profile a request progress event with status check. * * @param _req Request pointer. * @param _name Event name. * @param _param32 Custom 32-bit parameter. * @param _status Status of the last progress event. */ #define UCS_PROFILE_REQUEST_EVENT_CHECK_STATUS(_req, _name, _param32, _status) \ if (!UCS_STATUS_IS_ERR(_status)) { \ UCS_PROFILE_REQUEST_EVENT((_req), (_name), (_param32)); \ } /* * Profile a request release. * * @param _req Request pointer. */ #define UCS_PROFILE_REQUEST_FREE(_req) \ UCS_PROFILE(UCS_PROFILE_TYPE_REQUEST_FREE, "", 0, (uintptr_t)(_req)); /* * Store a new record with the given data. * SHOULD NOT be used directly - use UCS_PROFILE macros instead. * * @param [in] type Location type. * @param [in] name Location name. * @param [in] param32 custom 32-bit parameter. * @param [in] param64 custom 64-bit parameter. * @param [in] file Source file name. * @param [in] line Source line number. * @param [in] function Calling function name. * @param [in,out] loc_id_p Variable used to maintain the location ID. */ void ucs_profile_record(ucs_profile_type_t type, const char *name, uint32_t param32, uint64_t param64, const char *file, int line, const char *function, volatile int *loc_id_p); /** * Reset the internal array of profiling locations. * Used for testing purposes only. */ void ucs_profile_reset_locations(); END_C_DECLS #endif