Entire-Metadata: .entire/metadata/fb87247f-2a75-407e-b336-cbc8c20ba5a6 Entire-Session: fb87247f-2a75-407e-b336-cbc8c20ba5a6 Entire-Strategy: manual-commit
403 lines
14 KiB
C
403 lines
14 KiB
C
/*
|
|
* (c) Copyright, Real-Time Innovations, 2002-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_heap_h
|
|
#define osapi_heap_h
|
|
|
|
#include "osapi/osapi_type.h"
|
|
#include "osapi/osapi_dll.h"
|
|
#include "osapi/osapi_alignment.h"
|
|
#include "osapi/osapi_heapContext.h"
|
|
#include "osapi/osapi_utility.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** @internal
|
|
* @brief Maximum allocation size across platforms
|
|
* We subtract 1024 because our memory allocation
|
|
* routines do operations with the allocation size
|
|
* that can cause it to overflow.
|
|
*/
|
|
#define RTI_OSAPI_HEAP_MAX_ALLOC_SIZE (RTI_INT32_MAX - 1024)
|
|
|
|
/** @internal \file
|
|
* \brief Heap utilities
|
|
*/
|
|
|
|
/** @internal \defgroup RTIOsapiHeapClass RTIOsapiHeap
|
|
* \ingroup RTIOsapiModule
|
|
*
|
|
* \brief OS-independent way to use the heap (Malloc/Free)
|
|
*
|
|
* There are 4 Allocate/Free combinations: to allocate
|
|
* a C-structure, an array of C-structures, a string and a buffer
|
|
* of chosen size and alignment. It is important that the
|
|
* correct allocation and Free method are combined.
|
|
* All methods initialize the allocated space with 0's.
|
|
*
|
|
* Memory allocation statistics are maintained if the API
|
|
* RTIOsapiHeap_enableMonitoring is called
|
|
*
|
|
* The application can get the current statistics calling RTIOsapiHeap_statGet
|
|
* statistics counter can be reset calling RTIOsapiHeap_statReset.
|
|
*
|
|
* While statistic-collection is turned on, the system will allocate a
|
|
* larger block than it is requested. The extra space is used to store some
|
|
* extra information such as the size of the block, a blockId, a pointer to
|
|
* the actual memory, etc.
|
|
*
|
|
* Statistics are updated each time a memory Allocation/Free/Reallocation is
|
|
* performed using any of the RTIOsapiHeap_* functions.
|
|
*/
|
|
|
|
/** @internal \ingroup RTIOsapiHeap
|
|
*
|
|
* @brief Memory Heap usage statistics
|
|
*
|
|
* This structure is used to return Heap statistics. The heap statistic count
|
|
* the incremental memory consumption, number of allocations and number of frees
|
|
* that have occurred since the statistics were last reset.
|
|
*
|
|
* Note that the statistics count the bytes requested (cumulative sum of the
|
|
* sizes requested on the calls to RTIOsapiHeap_* functions). The bytes actually
|
|
* consumed will be slightly greater due to the extra bytes to hold the header
|
|
* information that supports the statistics (about 16 Bytes per block). The
|
|
* reason for reporting the requested bytes is that this number will match the
|
|
* actual allocated bytes when statistics-collection is turned off which is the
|
|
* typical case for a deployed system.
|
|
*
|
|
* \b Example:
|
|
*
|
|
* The following gets the current statistics.
|
|
*
|
|
* \verbatim
|
|
* RTIOsapiHeapStat stat;
|
|
*
|
|
* RTIOsapiHeap_statGet(&stat);
|
|
* \endverbatim
|
|
*
|
|
* @see RTIOsapiHeap_statGet RTIOsapiHeap_statReset
|
|
*/
|
|
struct RTIOsapiHeapStat {
|
|
/** @internal current heap used in Bytes. This stat does not
|
|
* include the additional memory that is added as headers to
|
|
* each allocation in order to keep track of it for heap
|
|
* monitoring. That additional overhead is accounted for in the
|
|
* currentUsageWithHeaders stat.
|
|
*/
|
|
RTI_INT64 currentUsage;
|
|
/** @internal current heap used in Bytes. This stat includes
|
|
* the memory that is allocated for the headers that are
|
|
* added to each memory allocation when heap monitoring is
|
|
* enabled.
|
|
*/
|
|
RTI_INT64 currentUsageWithHeaders;
|
|
/** @internal maximum heap usage in Bytes */
|
|
RTI_INT64 highWatermark;
|
|
/** @internal minimum heap usage in Bytes */
|
|
RTI_INT64 lowWatermark;
|
|
/** @internal number of allocations (Realloc counted as Malloc + Free) */
|
|
RTI_INT64 allocCount;
|
|
/** @internal number of frees (Realloc counted as Malloc + Free) */
|
|
RTI_INT64 freeCount;
|
|
/** @internal the ID that will be assigned to the next allocated block
|
|
0 => Statistics are not being gathered
|
|
1 => No block have been allocated
|
|
This value is not affected by a call to RTIOsapiStat_statReset
|
|
*/
|
|
RTI_UINT64 nextBlockId;
|
|
};
|
|
|
|
#define RTI_OSAPI_HEAP_STAT_DEFAULT \
|
|
{ \
|
|
0 /* currentUsage */, \
|
|
0 /* currentUsageWithHeaders */, \
|
|
0 /* highWatermark */, \
|
|
0 /* lowWatermark */, \
|
|
0 /* allocCount */, \
|
|
0 /* freeCount */, \
|
|
0 /* nextBlockId */ \
|
|
}
|
|
|
|
/** @internal \ingroup RTIOsapiHeap
|
|
* All the ALLOC RTIOsapiHeapAllocatorKind share the same prefix.
|
|
* It is used to check if the signature is RTI_OSAPI_*_ALLOC and not
|
|
* RTI_OSAPI_FREED_BLOCK.
|
|
*/
|
|
#define RTI_OSAPI_HEAP_ALLOC_PREFIX 0x4E444440
|
|
|
|
typedef enum RTIOsapiHeapAllocatorKind {
|
|
RTI_OSAPI_STRUCT_ALLOC = 0x4E444441,
|
|
RTI_OSAPI_STRING_ALLOC = 0x4E444442,
|
|
RTI_OSAPI_ARRAY_ALLOC = 0x4E444443,
|
|
RTI_OSAPI_BUFFER_ALLOC = 0x4E444444,
|
|
RTI_OSAPI_BUFFER_ALIGN_ALLOC = 0x4E444445,
|
|
RTI_OSAPI_MALLOC_ALLOC = 0x4E444446,
|
|
RTI_OSAPI_FREED_BLOCK = 0x7b9b9b9b
|
|
} RTIOsapiHeapAllocatorKind;
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Get statistics on the Heap. See documentation on the
|
|
* struct RTIOsapiHeapStat for a description of the statistics.
|
|
*
|
|
* The statistics count the number of bytes and allocations since the
|
|
* last time RTIOsapiHeap_statReset was called. Therefore statistics
|
|
* taken right after RTIOsapiHeap_statReset is called and before doing
|
|
* any allocations or frees will result in all counters (with the exception
|
|
* of the lastBlockId to be zero.
|
|
*
|
|
* The counters currentUsage, lowWatermark, and freeCount can take negative
|
|
* values if an application frees more memory than it allocates after calling
|
|
* RTIOsapiHeap_statReset.
|
|
*
|
|
* This operation can be called even if heap monitoring was not enabled.
|
|
* If this is the case all statistic counters will return zero and the
|
|
* lastBlockId will be -1.
|
|
*
|
|
* @param stat \b out. Must point to valid memory. Cannot be NULL
|
|
*
|
|
* @see RTIOsapiHeap_statReset
|
|
*/
|
|
extern RTIOsapiDllExport void RTIOsapiHeap_statGet(
|
|
struct RTIOsapiHeapStat *stat);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Reset all statistics counters. Does not reset the nextBlockId.
|
|
*
|
|
* This function resets all the statistics counters with the exception
|
|
* of the nextBlockId. This is done so that blocks can still get a unique
|
|
* Id.
|
|
*
|
|
* This operation has no effect if heap monitoring is not enabled.
|
|
*
|
|
* @see RTIOsapiHeap_statGet
|
|
*/
|
|
extern RTIOsapiDllExport void RTIOsapiHeap_statReset(void);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Get information on a memory block.
|
|
*
|
|
* This function only works if heap monitoring is enabled and
|
|
* can only be used on a block allocated with one of the RTIOsapiHeap_*
|
|
* functions. If either of this is not true the function will return
|
|
* RTI_FALSE.
|
|
*
|
|
* @see RTIOsapiHeap_statGet
|
|
*/
|
|
extern RTIOsapiDllExport RTIBool RTIOsapiHeap_blockInfoGet(
|
|
const void *address,
|
|
RTI_UINT64 *blockId,
|
|
RTI_UINT64 *blockSize);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Transition function to replace malloc. Should only be used
|
|
* while refactoring
|
|
*
|
|
* This function performs the logical equivalent as a malloc() except that
|
|
* the Memory Statistics are updated and the memory is initialize to zeros
|
|
*
|
|
* This function should only be used temporarily as a convenience while
|
|
* migrating code that uses malloc(). The correct solution is to use
|
|
* the proper function that depends on what is allocated, such as
|
|
* \ref RTIOsapiHeap_allocateStructure
|
|
*/
|
|
extern RTIOsapiDllExport void *RTIOsapiHeap_malloc(size_t size);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* @brief Calling RTIOsapiHeap_malloc but forcing not removing Heap Header.
|
|
* @param size \b In. This is the size of the memory block, in bytes.
|
|
* @return A pointer to the allocated memory, or NULL if the request fails.
|
|
*/
|
|
extern RTIOsapiDllExport void *RTIOsapiHeap_mallocWithoutHeapHeader(
|
|
size_t size);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Transition function to replace calloc. Should only be used
|
|
* while refactoring
|
|
*
|
|
* This function performs the logical equivalent as a malloc() except that
|
|
* the Memory Statistics are updated and the memory is initialize to zeros
|
|
*
|
|
* This function should only be used temporarily as a convenience while
|
|
* migrating code that uses calloc(). The correct solution is to use
|
|
* the proper function that depends on what is allocated, such as
|
|
* \ref RTIOsapiHeap_allocateArray or \ref RTIOsapiHeap_allocateBuffer
|
|
*/
|
|
extern RTIOsapiDllExport void *RTIOsapiHeap_calloc(
|
|
size_t numElem,
|
|
size_t elemSize);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Transition function to replace realloc. Should only be used
|
|
* while refactoring
|
|
*
|
|
* This function performs the logical equivalent as a realloc() except that
|
|
* the Memory Statistics are updated and the memory is initialize to zeros
|
|
*
|
|
* This function should only be used temporarily as a convenience while
|
|
* migrating code that uses malloc/calloc.
|
|
*/
|
|
extern RTIOsapiDllExport void *RTIOsapiHeap_realloc(void *ptr, size_t size);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Transition function to replace free. Should only be used
|
|
* while refactoring
|
|
*
|
|
* This function performs the logical equivalent as a free() except that
|
|
* the Memory Statistics are updated and the memory is initialize to zeros
|
|
*
|
|
* This function should only be used temporarily as a convenience while
|
|
* migrating code that uses malloc/calloc.
|
|
*/
|
|
extern RTIOsapiDllExport void RTIOsapiHeap_free(void *ptr);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* @brief Calling RTIOsapiHeap_free but forcing not including Heap Header.
|
|
* @param ptr \b In. Pointer to a memory block previously allocate.
|
|
* @param ptr \b In. Size of the memory to be freed.
|
|
* It is just used to update the variable 'memCurrentIncludingHeaders'.
|
|
*/
|
|
extern RTIOsapiDllExport void RTIOsapiHeap_freeWithoutHeapHeader(
|
|
void *ptr,
|
|
size_t size);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* Specify the format of the output of the snapshot.
|
|
*/
|
|
typedef enum {
|
|
/* The output of the snapshot will be in plain text */
|
|
RTI_OSAPI_HEAP_SNAPSHOT_OUTPUT_FORMAT_STANDARD = 1,
|
|
/*
|
|
* The output of the snapshot will be compressed using
|
|
* Zlib techonology.
|
|
* The file can be uncompressed using zlib-flate.
|
|
*/
|
|
RTI_OSAPI_HEAP_SNAPSHOT_OUTPUT_FORMAT_COMPRESSED = 2,
|
|
} RTIOsapiHeapSnapshotOutputFormat;
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* It is a bitmap to decide which information of the snapshot will be displayed
|
|
* for the optional fields.
|
|
*/
|
|
typedef unsigned int RTIOsapiHeapSnapshotContentBitmap;
|
|
|
|
#define RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_BIT_TOPIC 0x1
|
|
#define RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_BIT_FUNCTION 0x2
|
|
#define RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_BIT_ACTIVITY 0x4
|
|
|
|
#define RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_MASK_DEFAULT \
|
|
(RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_BIT_TOPIC \
|
|
| RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_BIT_FUNCTION \
|
|
| RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_BIT_ACTIVITY)
|
|
|
|
#define RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_MINIMAL 0x0
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* Properties for the Heap monitoring feature.
|
|
* They will be used for configuring the format of the snapshot.
|
|
*/
|
|
struct RTIOsapiHeapMonitoringProperty {
|
|
/* Specify the format of the output of the snapshot. */
|
|
RTIOsapiHeapSnapshotOutputFormat outputFormat;
|
|
/*
|
|
* It is a bitmap to decide which information of the snapshot will be
|
|
* displayed.
|
|
*/
|
|
RTIOsapiHeapSnapshotContentBitmap contentFormat;
|
|
};
|
|
|
|
#define RTIOsapiHeapMonitoringProperty_INITIALIZER \
|
|
{ \
|
|
RTI_OSAPI_HEAP_SNAPSHOT_OUTPUT_FORMAT_STANDARD, /* outputFormat */ \
|
|
RTI_OSAPI_HEAP_SNAPSHOT_CONTENT_MASK_DEFAULT /* contentFormat */ \
|
|
}
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* @brief Initialize the fields of the RTIOsapiHeapMonitoringProperty structure.
|
|
* @param self \b In. The RTIOsapiHeapMonitoringProperty to initialize.
|
|
*/
|
|
extern RTIOsapiDllExport void RTIOsapiHeapMonitoringProperty_initialize(
|
|
struct RTIOsapiHeapMonitoringProperty *self);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* @brief Copy the fields of src into self.
|
|
* @param self \b Out. The RTIOsapiHeapMonitoringProperty to be copied.
|
|
* @param self \b In. The RTIOsapiHeapMonitoringProperty to copy.
|
|
*/
|
|
extern RTIOsapiDllExport void RTIOsapiHeapMonitoringProperty_copy(
|
|
struct RTIOsapiHeapMonitoringProperty *self,
|
|
const struct RTIOsapiHeapMonitoringProperty *src);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Disables heap monitoring
|
|
* This function is not thread safe
|
|
*/
|
|
extern RTIOsapiDllExport void RTIOsapiHeap_disableMonitoring(void);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Enables heap monitoring
|
|
* This function is not thread safe
|
|
*/
|
|
extern RTIOsapiDllExport RTIBool RTIOsapiHeap_enableMonitoring(void);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* @brief Enables heap monitoring.
|
|
*
|
|
* @param property \b In. The the properties to enable.
|
|
*
|
|
* This function is not thread safe
|
|
*/
|
|
extern RTIOsapiDllExport RTIBool RTIOsapiHeap_enableMonitoringWithParams(
|
|
const struct RTIOsapiHeapMonitoringProperty *property);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Indicates if monitoring is enabled
|
|
* This function is thread safe
|
|
*/
|
|
extern RTIOsapiDllExport RTIBool RTIOsapiHeap_isMonitoringEnabled(void);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Pauses the monitoring process.
|
|
*
|
|
* This means that statistics will not be gathered for the memory allocated
|
|
* while monitoring is paused
|
|
*
|
|
* This function is thread safe
|
|
*/
|
|
extern RTIOsapiDllExport RTIBool RTIOsapiHeap_pauseMonitoring(void);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Resumes the monitoring process.
|
|
*
|
|
* This function is thread safe
|
|
*/
|
|
extern RTIOsapiDllExport RTIBool RTIOsapiHeap_resumeMonitoring(void);
|
|
|
|
/** @internal \ingroup RTIOsapiHeapClass
|
|
* \brief Saves a heap snapshot into a file
|
|
*
|
|
* This function is thread safe
|
|
*/
|
|
extern RTIOsapiDllExport RTIBool RTIOsapiHeap_snapshot(
|
|
const char *fileName,
|
|
RTIBool printDetails,
|
|
const char *productVersion);
|
|
|
|
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
|
|
#include "osapi/osapi_heap_impl.h"
|
|
|
|
#endif /* osapi_heap_h */
|