/* * (c) Copyright, Real-Time Innovations, 2019-2024. * All rights reserved. * * No duplications, whole or partial, manual or electronic, may be made * without express written permission. Any such copies, or * revisions thereof, must display this notice unaltered. * This code contains trade secrets of Real-Time Innovations, Inc. */ #ifndef osapi_heapContext_h #define osapi_heapContext_h #include "osapi_type.h" #include "osapi_dll.h" #ifdef __cplusplus extern "C" { #endif /** @internal \ingroup RTIOsapiHeapContext * Heap context is used in heap monitoring. * It will provide extra information about the pool, the topic relate and the * function when memory is allocated. */ /* ========================================= */ /* HeapContextEntry */ /* ========================================= */ /** @internal \ingroup RTIOsapiHeapContext * Entry of the heap context. */ struct RTIOsapiHeapContextStackEntry { RTIBool poolAlloc; int poolBufferCount; int poolBufferSize; const char *topicName; const char *functionName; }; #define RTIOsapiHeapContextStackEntry_INITIALIZER \ { \ RTI_FALSE, 0, 0, "unknown", "unknown" \ } /* ========================================= */ /* HeapContextSupport */ /* ========================================= */ /** @internal \ingroup RTIOsapiHeapContextSupport * @brief Create an heap context and associate with the TSS of the thread. * - It should be called per thread. * - It should be called after RTIOsapiContextSupport_enable. * It is called in: * - RTIOsapiThreadFactory_onSpawned * - RTIOsapiThreadChild_onSpawned: * Here addContextTssToGlobalList is set to False, because the RTI threads * will handle the destruction as part of the thread spawn function. So, * we do not add the context thread specific storage to the global list. * * - DDS_DomainParticipantGlobals_create_worker_per_thread_with_nameI * Here addContextTssToGlobalList is set to True, the context thread * specific storage will be deleted upon * DDS_DomainParticipantGlobals destruction, which is only recommended for * non-RTI threads. * * @param addContextTssToGlobalList \b In. If true we add the context thread * specific storage to a global list. * * @return True if the context was initalized, False otherwise. */ extern RTIOsapiDllExport RTIBool RTIOsapiHeapContextSupport_assertContextTss(RTIBool addContextTssToGlobalList); /** @internal \ingroup RTIOsapiHeapContext * @brief Convert the heap context into a single one heap context entry. * This function will return an entry with the latest or the default value of * each field * * @param outputEntry \b Out. The entry to fill. * * @return RTI_TRUE if success, RTI_FALSE otherwise. */ extern RTIOsapiDllExport RTIBool RTIOsapiHeapContext_mergeEntries( struct RTIOsapiHeapContextStackEntry *outputEntry); /* ========================================= */ /* HeapContextScope */ /* ========================================= */ /* * We define "scope" as a block of code which: * - Starts with a RTIOsapiHeapContextScope_begin call. This function is a * macro that open the block and initializes all the stack variables needed to * support entering/leaving contexts within the block. * - Keeps track of the context entries we enter and leave. To do so: * - Within the scope, we can enter a new context entry using the following * macros: * - RTIOsapiHeapContextScope_enterActivity * - Within the scope, we can leave a context entry using the following * macro: * - RTIOsapiHeapContextScope_leaveEntries * - Starting a scope consists of beginning the scope plus entering a Context: * - RTIOsapiHeapContextScope_start * - RTIOsapiHeapContextScope_startPool * - RTIOsapiHeapContextScope_startActivity * - Ends with calling RTIOsapiHeapContextScope_end. * Upon ending a scope, any remaining entered entries will leave. */ /** @internal \ingroup RTIOsapiHeapContext * @brief Begin the heap context scope. * It initializes a RTIOsapiHeapContextStackEntry structure in the stack. * The scope should be closed calling "RTIOsapiHeapContextScope_end()". * It opens the scope. */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_begin(void); /** @internal \ingroup RTIOsapiHeapContext * @brief Begins the contextScope and enter an entry in the heap context. * This function is a macro that will create a RTIOsapiHeapContextStackEntry * structure in the stack. * This entry should be leave using "RTIOsapiHeapContextScope_end()". * It opens the scope. * * @param poolAlloc \b In. RTI_TRUE if the alloc is by the pool. * @param poolBufferCount \b In. The pool buffer count. * @param poolBufferSize \b In. The pool buffer size. * @param topicName \b In. The topic Name related to the alloc. * @param functionName \b In. The functionName where the alloc is done. */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_start( RTIBool poolAlloc, int poolBufferCount, int poolBufferSize, const char *topicName, const char *functionName); /** @internal \ingroup RTIOsapiHeapContext * @brief Begins the contextScope and enter an entry in the heap context with * the pool information. * This function is a macro that will create a RTIOsapiHeapContextStackEntry * structure in the stack. * This entry should be leave using "RTIOsapiHeapContextScope_end()". * It opens the scope. * * @param poolAlloc \b In. RTI_TRUE if the alloc is by the pool. * @param poolBufferCount \b In. The pool buffer count. * @param poolBufferSize \b In. The pool buffer size. */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_startPool( RTIBool poolAlloc, int poolBufferCount, int poolBufferSize); /** @internal \ingroup RTIOsapiHeapContext * @brief Begins the contextScope and enter an entry in the heap context with * the topicName and the functionName. * This function is a macro that will create a RTIOsapiHeapContextStackEntry * structure in the stack. * This entry should be leave using "RTIOsapiHeapContextScope_end()". * It opens the scope. * * @param topicName \b In. The topic Name related to the alloc. */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_startActivity( const char *topicName); /** @internal \ingroup RTIOsapiHeapContext * @brief Enter an entry in the heap context with the topicName and the * functionName. * This function required RTIOsapiHeapContextScope_begin() to be called. * This entry should be leave using "RTIOsapiHeapContextScope_end()". * * @param topicName \b In. The topic Name related to the alloc. */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_enterActivity( const char *topicName); /** @internal \ingroup RTIOsapiHeapContext * @brief This function is a macro leave all the entries of the heap context * entered after calling the begin macro. */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_leaveEntries(void); /** @internal \ingroup RTIOsapiHeapContext * @brief This function is a macro leave all the entries of the heap context * entered after calling the begin macro. * It closes the scope. */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_end(void); /** @internal \ingroup RTIOsapiHeapContext * * @brief Enter a test function with heap monitoring for a high-level * language binding * * This function can be used in higher-level language bindings (Java, C#...) * to add the function name being run while heap monitoring is enabled. If * a leak occurs directly in the test thread the snapshot log will include * the function name. * * RTIOsapiHeapContextScope_leaveTestFunction must be called when the function * ends. * * RTIOsapiHeapContextScope_finalizeTestSupport must be called when all the * unit tests end, after taking the last snapshot. * * @pre Heap monitoring is enabled * * @note This function doesn't need to be used in C or C++. * * @note This function can't be used in multiple threads. Only one test can run * at a time * * @note If the leak occurs in a separate thread, the function name will not be * part of the snapshot log */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_enterTestFunction( const char *functionName); /** @internal \ingroup RTIOsapiHeapContext * * @brief Leave a test function with heap monitoring in a high-level * language binding * * See RTIOsapiHeapContextScope_enterTestFunction */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_leaveTestFunction(void); /** @internal \ingroup RTIOsapiHeapContext * * @brief Finalize the global resources used by * RTIOsapiHeapContextScope_enterTestFunction * * See RTIOsapiHeapContextScope_enterTestFunction */ extern RTIOsapiDllExport void RTIOsapiHeapContextScope_finalizeTestSupport( void); /* ========================================= */ /* Internal method */ /* ========================================= */ /** @internal \ingroup RTIOsapiHeapContext * @brief Return the number of entries of the heap context. * * @return number of entries of the activity context. */ extern RTIOsapiDllExport RTI_UINT32 RTIOsapiHeapContext_getDepth(void); #ifdef __cplusplus } /* extern "C" */ #endif #include "osapi/osapi_heapContext_impl.h" #endif /* osapi_heapContext_h */