Initial commit of firmware

This commit is contained in:
2025-04-12 13:30:57 +01:00
commit 264a3462e0
374 changed files with 332649 additions and 0 deletions

View File

@@ -0,0 +1,631 @@
/***************************************************************************//**
* @file
* @brief Macros and functions for memory profiling
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* SPDX-License-Identifier: Zlib
*
* The licensor of this software is Silicon Laboratories Inc.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
******************************************************************************/
#ifndef SLI_MEMORY_PROFILER_H
#define SLI_MEMORY_PROFILER_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "sl_status.h"
#if defined(SL_COMPONENT_CATALOG_PRESENT)
// The component catalog is present, so we're in an application build and can
// check if the Memory Profiler is present
#include "sl_component_catalog.h"
#if defined(SL_CATALOG_MEMORY_PROFILER_PRESENT)
// The Memory Profiler is present. Use its configuration and enable profiling.
#include "sli_memory_profiler_config.h"
#define SLI_MEMORY_PROFILER_ENABLE_PROFILING 1
#else
// The Memory Profiler is not present. Disable profiling.
#define SLI_MEMORY_PROFILER_ENABLE_PROFILING 0
#endif // defined(SL_CATALOG_MEMORY_PROFILER_PRESENT)
#else // defined(SL_COMPONENT_CATALOG_PRESENT)
// The component catalog is not present, so we're in a library build. The build
// environment of the library must specify the configuration defines that affect
// the macros in this header if it wants a non-default configuration. We default
// to enabling basic profiling but disabling ownership tracking.
#if !defined(SLI_MEMORY_PROFILER_ENABLE_PROFILING)
#define SLI_MEMORY_PROFILER_ENABLE_PROFILING 1
#endif
#if !defined(SLI_MEMORY_PROFILER_ENABLE_OWNERSHIP_TRACKING)
#define SLI_MEMORY_PROFILER_ENABLE_OWNERSHIP_TRACKING 0
#endif
#endif // defined(SL_COMPONENT_CATALOG_PRESENT)
#ifdef __cplusplus
extern "C" {
#endif
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
/***************************************************************************//**
* @addtogroup memory_profiler Memory Profiler
* @{
*
* @brief Memory profiler for tracking and reporting system RAM usage
*
* This memory profiler component provides a tool for tracking and reporting of
* system RAM usage. It is implemented as a combination of a simple component
* running in the Device Under Test (DUT) and a Python script running on a
* computer. The on-DUT component is a relatively thin layer that uses J-Link
* RTT (Real Time Transfer) to output events about memory allocation on the
* device. The Python script on the computer receives these events and maintains
* the memory usage bookkeeping. The script is available in
* `platform/service/memory_manager/profiler/scripts/memory_profiler_platform.py`.
*
* The memory profiler represents memory in a hierarchical structure with the
* physical RAM as the root of the tree. The physical RAM is split into
* allocations such as stack and heap, and the heap is further split into
* allocations for different uses of memory.
*
* Each node in the tree is represented by one instance of a memory tracker.
* Each tracker has a short description and records the current and peak number
* of bytes allocated. Leaves in the tree represent concrete uses of RAM, for
* example allocations of a particular object types in a wireless stack.
* Intermediate nodes typically correspond to memory allocation abstractions,
* such as memory pools or helper functions that are used by the concrete users
* of memory.
*
* The trackers can represent two different types of allocation behavior:
*
* 1. Pool trackers represent memory abstractions that make one contiguous
* allocation from their parent memory to allocate a pool. Portions of that
* pool are then given to callers that allocate memory from the pool
* abstraction. The Memory Manager (MM) heap is one example of such a
* pool. The MM heap reserves some portion of the physical RAM at
* initialization time and gives portions of that pool to its callers.
* Another example of a pool tracker are the individual pools that can be
* created and deleted at runtime using the MM Pool API. Each pool is
* associated with a pool tracker to track the allocation and freeing of the
* pool items during the lifetime of the pool.
*
* 2. Trackers that are not pools are used to collect the allocation statistics
* of a certain type of allocation or use case so that the memory use of that
* particular type can be easily distinguished from all the other users of
* memory. For example, the Memory Manager creates a separate tracker
* for long-term heap allocations, short-term heap allocations, and heap
* reservations, so that these can be counted individually. Components such
* as wireless stacks may create their own trackers for tracking things like
* the total sum of allocations made by a particular component, or more
* granularly the allocations made for a particular type of a resource.
*
* The Memory Manager is integrated to the Memory Profiler and all
* allocations from the heap are automatically tracked by the top-level trackers
* for the heap. This provides the usage tracking for the heap as a whole, i.e.
* how many bytes of heap are used in total. If a component or an application
* wants to track how many bytes it has allocated from the heap, it can create a
* new memory profiler tracker. Pool memory trackers are created with a call to
* `sli_memory_profiler_create_pool_tracker()` and other trackers are created
* with `sli_memory_profiler_create_tracker()`.
*
* Both types of trackers are identified by a handle of type
* `sli_memory_tracker_handle_t`, which is just a void pointer that is provided
* by the code that creates the tracker. Code that creates a tracker can use any
* void pointer that is guaranteed to be unique among all trackers for the
* duration of the tracker lifetime, i.e. until the tracker is deleted with a
* call to `sli_memory_profiler_delete_tracker()`. A good approach is to use a
* pointer that is tightly associated with the tracked object or use case. For
* example, a tracker for a memory pool can use the pool handle as the tracker
* handle. A function that wants to track the allocations it makes can use its
* own function pointer as the tracker handle.
*
* Top-level trackers for the heap are created at platform initialization time
* and are never deleted. Other trackers have the same lifetime as the entity or
* component that is being tracked. For example, when a memory pool is created,
* a tracker is created for the pool. When the pool is deleted, the tracker is
* also deleted. Similarly if a component creates a tracker for its memory use
* when the component is initialized or started, the component would typically
* delete the tracker for its memory when the component is de-initialized or
* stopped. Trackers are deleted with a call to
* `sli_memory_profiler_delete_tracker()`.
*
* The memory profiler implementation aims to minimize the impact of the memory
* profiler calls on both RAM and CPU usage when the profiling is not enabled by
* including the component in the SW configuration. To keep the calling code
* clean of conditional compilation but still allow completely removing the
* tracking calls when the profiler is not used, the calling code is encouraged
* to do the tracking via the macros such as @ref
* SLI_MEMORY_PROFILER_TRACK_ALLOC() and @ref SLI_MEMORY_PROFILER_TRACK_FREE().
* These macros will automatically expand to empty when the profiling is
* disabled at build time.
*
* If a component is compiled into a library (as opposed to being compiled at
* application build time), the library may contain calls to the Memory Profiler
* API even if tracking will be disabled in the application. In this case the SW
* is linked with a stub Memory Profiler API implementation that provides dummy
* functions. The stub implementation does not use any RAM or RTT, so the
* overhead is minimized.
*
* Trackers use @ref SLI_MEMORY_PROFILER_TRACK_ALLOC() to track the allocation of
* memory blocks and include the bytes of RAM to the counts in the trackers. To
* make sure that any arbitrary pointer can be correctly mapped to the
* allocation it belongs to, every tracker must accurately track the pointer and
* size of the memory block that they are operating with. As an example, when an
* allocation from the MM heap is made, the MM heap implementation tracks the
* full allocation RAM block including any extra metadata or size padding that
* is used around the block returned to the caller. The caller will track the
* allocation using the size it requested from the heap (which is smaller than
* the full block needed to satisfy the allocation), and the pointer it received
* from the heap (which is within the full block allocated from the RAM).
*
* Trackers use @ref SLI_MEMORY_PROFILER_TRACK_FREE() to mark the freeing of a
* memory block. Here too the callers must accurately identify the freed block
* by providing the same pointer they provided in the corresponding call to
* track the allocation. The tracking of the free does not need to be fully
* symmetric, though. As an example, assume that an app has created the tracker
* `app_mallocs` and is using @ref SLI_MEMORY_PROFILER_TRACK_ALLOC() to track on
* that tracker every block it received from @ref sl_malloc(). When the
* application calls @ef sl_free() to free a memory block, the application does
* not need to call @ref SLI_MEMORY_PROFILER_TRACK_FREE() to mark the freeing.
* The MM heap will track the freeing in `sl_free()` and the freeing of the
* memory is automatically counted in the `app_mallocs` tracker as well.
*
******************************************************************************/
/**
* @brief Memory tracker handle type
*/
typedef const void* sli_memory_tracker_handle_t;
/**
* @brief Value used to indicate an invalid memory tracker handle
*/
#define SLI_INVALID_MEMORY_TRACKER_HANDLE ((sli_memory_tracker_handle_t) NULL)
/**
* @brief Initialize the memory profiler
*
* Memory Profiler initialization is handled internally by the Platform
* initialization. Applications do not need to and should not call this function
* directly.
*/
void sli_memory_profiler_init();
/**
* @brief Get the current program counter
*
* This helper can be used to obtain the current program counter when invoking
* @ref SLI_MEMORY_PROFILER_TRACK_OWNERSHIP() with the intention of assigning
* the ownership to the location that is invoking the tracking macro.
*
* @return Current program counter
*/
#if defined(__GNUC__)
__attribute__( (always_inline) ) static inline void * sli_memory_profiler_get_pc(void)
{
void *pc;
__asm volatile ("MOV %0, PC" : "=r" (pc));
return pc;
}
#elif defined(__IAR_SYSTEMS_ICC__)
_Pragma("inline=forced") static inline void * sli_memory_profiler_get_pc(void)
{
void *pc;
__asm volatile ("MOV %0, PC" : "=r" (pc));
return pc;
}
#else
static inline void * sli_memory_profiler_get_pc(void)
{
// Memory Profiler supports ownership tracking only with the GCC or IAR compiler
return NULL;
}
#endif
/**
* @brief Get the return address of the current function
*
* This helper can be used to obtain the return address of the current function
* when invoking @ref SLI_MEMORY_PROFILER_TRACK_OWNERSHIP() with the intention
* of assigning the ownership to the location that made the call to the function
* that is invoking the tracking macro.
*
* Note that the IAR compiler does not provide a mechanism to reliably obtain
* the return address, so we must emulate that by taking the content of the link
* register. This is never completely reliable, but is guaranteed to fail if
* `sli_memory_profiler_get_return_address()` is used in a function after calls
* to other functions have already been made. Therefore this function should
* always be called right at the beginning of the function that wants to know
* the return address.
*
* @return The return address of the current function
*/
#if defined(__GNUC__)
__attribute__( (always_inline) ) static inline void * sli_memory_profiler_get_return_address(void)
{
return __builtin_extract_return_addr(__builtin_return_address(0));
}
#elif defined(__IAR_SYSTEMS_ICC__)
_Pragma("inline=forced") static inline void * sli_memory_profiler_get_return_address(void)
{
uint32_t lr;
lr = __get_LR();
return (void *)lr;
}
#else
static inline void * sli_memory_profiler_get_return_address(void)
{
// Memory Profiler supports ownership tracking only with the GCC or IAR compiler
return NULL;
}
#endif
/**
* @brief Create a pool memory tracker
*
* This function creates a memory tracker for a memory use case that allocates
* one fixed-size pool from some allocator and then allocates portions of the
* pool to its own clients.
*
* The memory block specified by @p pointer and @p size must match a memory
* allocation that the pool implementation has successfully obtained from some
* memory allocator that has tracked the allocation. If the pool implementation
* later frees the pool memory block (for example when the component that uses
* the pool is de-initialized), the pool implementation must delete the pool
* tracker with a call to @ref sli_memory_profiler_delete_tracker before it
* frees the memory block that the pool was using.
*
* @param[in] tracker_handle The handle to identify the tracker. The handle must
* remain unique among all trackers until the tracker is deleted with @ref
* sli_memory_profiler_delete_tracker.
* @param[in] description Short description of the usage of the tracker memory,
* or NULL to omit the description. The description can be set or updated
* later with a call to @ref sli_memory_profiler_describe_tracker.
* @param[in] ptr Pointer to the pool block allocated from the parent memory
* @param[in] size The size of the pool block allocated from the parent memory
*
* @return SL_STATUS_OK if a tracker was created, SL_STATUS_NOT_AVAILABLE if the
* Memory Profiler is not included in the application.
*/
sl_status_t sli_memory_profiler_create_pool_tracker(sli_memory_tracker_handle_t tracker_handle,
const char *description,
void* ptr,
size_t size);
/**
* @brief Create a memory tracker
*
* This function creates a memory tracker for a use case that allocates blocks
* from tracked parent allocator.
*
* @param[in] tracker_handle The handle to identify the tracker. The handle must
* remain unique among all trackers until the tracker is deleted with @ref
* sli_memory_profiler_delete_tracker.
* @param[in] description Short description of the usage of the tracker memory,
* or NULL to omit the description. The description can be set or updated
* later with a call to @ref sli_memory_profiler_describe_tracker.
*
* @return SL_STATUS_OK if a tracker was created, SL_STATUS_NOT_AVAILABLE if the
* Memory Profiler is not included in the application.
*/
sl_status_t sli_memory_profiler_create_tracker(sli_memory_tracker_handle_t tracker_handle,
const char *description);
/**
* @brief Add or update a description to a previously created memory tracker
*
* This function is typically used to assign a description to a tracker that has
* been created by a lower layer that does not know the use case of the memory.
* For example, when the Memory Manager creates a memory pool object, it
* creates a Memory Profiler tracker with the same handle as the pool handle but
* cannot assign a descriptive name, as it cannot know what the pool is used
* for. The caller that created the pool can then use this function with the
* pool handle to assign a description for the pool memory.
*
* @param[in] tracker_handle The handle of the memory tracker
* @param[in] description Short description of the usage of the tracker memory,
* or NULL to clear the description.
*/
void sli_memory_profiler_describe_tracker(sli_memory_tracker_handle_t tracker_handle,
const char *description);
/**
* @brief Delete a memory tracker
*
* This function deletes a previously created memory tracker.
*
* @param[in] tracker_handle The handle of the memory tracker
*/
void sli_memory_profiler_delete_tracker(sli_memory_tracker_handle_t tracker_handle);
/**
* @brief Track the allocation of a memory block
*
* NOTE: This function is intended to be called via the @ref
* SLI_MEMORY_PROFILER_TRACK_ALLOC() macro.
*
* @param[in] tracker_handle The handle of the memory tracker
* @param[in] ptr Pointer to the allocated memory or NULL if allocation failed
* @param[in] size The number of bytes allocated, or attempted to allocate
*/
void sli_memory_profiler_track_alloc(sli_memory_tracker_handle_t tracker_handle,
void * ptr,
size_t size);
/**
* @brief Track the reallocation of a previously allocated memory block
*
* NOTE: This function is intended to be called via the @ref
* SLI_MEMORY_PROFILER_TRACK_REALLOC() macro.
*
* NOTE: Reallocation is a special operation that is intended to be tracked only
* by the underlying heap allocator in the Memory Manager. Any
* higher-level allocations that are tracked within the reallocated block are
* automatically moved and resized without any tracking calls from the
* higher-level trackers.
*
* If the realloc operation involves allocating a new block and freeing the
* previous block, the Memory Manager heap must track the realloc when
* the allocation of the new memory has been tracked but the old memory block
* has not been freed yet. This is needed to guarantee that both @p ptr and @p
* realloced_ptr are valid and owned by the calling thread when the realloc is
* tracked.
*
* @param[in] tracker_handle The handle of the lowest-layer heap memory tracker
* @param[in] ptr Pointer to the original memory block
* @param[in] realloced_ptr Pointer to the resized or allocated memory
* @param[in] size The size that the block was reallocated to
*/
void sli_memory_profiler_track_realloc(sli_memory_tracker_handle_t tracker_handle,
void * ptr,
void * realloced_ptr,
size_t size);
/**
* @brief Track the allocation of a memory block and record ownership
*
* NOTE: This function is intended to be called via the @ref
* SLI_MEMORY_PROFILER_TRACK_ALLOC_WITH_OWNERSHIP() macro.
*
* @param[in] tracker_handle The handle of the memory tracker
* @param[in] ptr Pointer to the allocated memory or NULL if allocation failed
* @param[in] size The number of bytes allocated, or attempted to allocate
* @param[in] pc The program counter at the location of the allocation
*/
void sli_memory_profiler_track_alloc_with_ownership(sli_memory_tracker_handle_t tracker_handle,
void * ptr,
size_t size,
void * pc);
/**
* @brief Track the freeing of a memory block
*
* NOTE: This function is intended to be called via the
* @ref SLI_MEMORY_PROFILER_TRACK_FREE() macro.
*
* @param[in] tracker_handle The handle of the memory tracker
* @param[in] ptr Pointer to the allocated memory
*/
void sli_memory_profiler_track_free(sli_memory_tracker_handle_t tracker_handle,
void * ptr);
/**
* @brief Track the transfer of memory allocation ownership
*
* NOTE: This function is intended to be called via @ref
* SLI_MEMORY_PROFILER_TRACK_OWNERSHIP() or @ref
* SLI_MEMORY_PROFILER_TRACK_OWNERSHIP_ON_TRACKER() macros.
*
* @param[in] tracker_handle Handle of the tracker level at which the ownership
* is taken. This is used to disambiguate in cases where nested allocations
* start at the same memory location, and the caller is specifically taking
* ownership of one of the outer blocks that may contain smaller allocations
* that have their own (more detailed) owners. If set to
* `SLI_INVALID_MEMORY_TRACKER_HANDLE`, the ownership of the innermost
* allocation is taken.
* @param[in] ptr Pointer to the allocated memory for which ownership is taken.
* The caller may pass a NULL pointer to indicate that the location pointer to
* be @p pc has failed to obtain a valid pointer, for example because a memory
* allocation that was meant to provide the pointer has failed.
* @param[in] pc The program counter at the location that took ownership
*/
void sli_memory_profiler_track_ownership(sli_memory_tracker_handle_t tracker_handle,
void * ptr,
void * pc);
/**
* @brief Trigger the creation of a snapshot of the current state
*
* This function can be used by the device to trigger the analysis software on
* the PC or Mac to take a snapshot of the current state of the allocation
* bookkeeping. This would typically be used by test cases that communicate with
* the device under test and want to synchronously record the state of the
* allocations at a known point in the test sequence.
*
* @param[in] name Short name for the snapshot that is being created. The name
* is immediately sent in the RTT event to the analysis software and does not
* need to be retained in the device.
*/
void sli_memory_profiler_take_snapshot(const char *name);
/**
* @brief Output a generic log event in the RTT event stream
*
* This function is meant to be used for temporary debugging purposes only. When
* debugging a memory leak requires visibility to software actions other than
* memory allocation or free, calls to this generic logging mechanism can be
* added so that the sequence of software events can be seen with respect to the
* allocation and free events that are visible in the normal Memory Profiler
* events.
*
* @param[in] log_id Numeric identifier of this log event. This is passed in the
* RTT event to the analysis tool and the ID appears in the log produced by
* the analyzer but the value is not otherwise used by the Memory Profiler. It
* is the responsibility of the caller to use values that are sufficiently
* unique that the developer can identify the logs.
*
* @param[in] arg1 Arbitrary 32-bit argument that's relevant for the developer
*
* @param[in] arg2 Arbitrary 32-bit argument that's relevant for the developer
*
* @param[in] arg3 Arbitrary 32-bit argument that's relevant for the developer
*
* @param[in] pc The program counter at the location of the log call
*/
void sli_memory_profiler_log(uint32_t log_id,
uint32_t arg1,
uint32_t arg2,
uint32_t arg3,
void * pc);
// The macros expand to their full content only when profiling is included
#if SLI_MEMORY_PROFILER_ENABLE_PROFILING
/**
* @brief Macro to wrap calls to @ref sli_memory_profiler_track_alloc
*/
#define SLI_MEMORY_PROFILER_TRACK_ALLOC(tracker_handle, ptr, size) \
do { \
sli_memory_profiler_track_alloc((tracker_handle), (ptr), (size)); \
} while (0)
/**
* @brief Macro to wrap calls to @ref sli_memory_profiler_track_alloc_with_ownership
*
* If ownership tracking is disabled at build time, the macro reduces to normal
* tracking without ownership.
*/
#if SLI_MEMORY_PROFILER_ENABLE_OWNERSHIP_TRACKING
#define SLI_MEMORY_PROFILER_TRACK_ALLOC_WITH_OWNERSHIP(tracker_handle, ptr, size, pc) \
do { \
void * volatile _pc = (pc); \
sli_memory_profiler_track_alloc_with_ownership((tracker_handle), (ptr), (size), _pc); \
} while (0)
#else // SLI_MEMORY_PROFILER_ENABLE_OWNERSHIP_TRACKING
#define SLI_MEMORY_PROFILER_TRACK_ALLOC_WITH_OWNERSHIP(tracker_handle, ptr, size, pc) \
do { \
(void) (pc); \
sli_memory_profiler_track_alloc((tracker_handle), (ptr), (size)); \
} while (0)
#endif // SLI_MEMORY_PROFILER_ENABLE_OWNERSHIP_TRACKING
/**
* @brief Macro to wrap calls to @ref sli_memory_profiler_track_realloc
*/
#define SLI_MEMORY_PROFILER_TRACK_REALLOC(tracker_handle, ptr, realloced_ptr, size) \
do { \
sli_memory_profiler_track_realloc((tracker_handle), (ptr), (realloced_ptr), (size)); \
} while (0)
/**
* @brief Macro to wrap calls to @ref sli_memory_profiler_track_free
*/
#define SLI_MEMORY_PROFILER_TRACK_FREE(tracker_handle, ptr) \
do { \
sli_memory_profiler_track_free((tracker_handle), (ptr)); \
} while (0)
#else // SLI_MEMORY_PROFILER_ENABLE_PROFILING
// Empty implementation of tracking macros when memory profiling calls are
// excluded at build time
#define SLI_MEMORY_PROFILER_TRACK_ALLOC(tracker_handle, ptr, size) \
do { \
(void) (tracker_handle); \
(void) (ptr); \
(void) (size); \
} while (0)
#define SLI_MEMORY_PROFILER_TRACK_ALLOC_WITH_OWNERSHIP(tracker_handle, ptr, size, pc) \
do { \
(void) (tracker_handle); \
(void) (ptr); \
(void) (size); \
(void) (pc); \
} while (0)
#define SLI_MEMORY_PROFILER_TRACK_REALLOC(tracker_handle, ptr, realloced_ptr, size) \
do { \
(void) (tracker_handle); \
(void) (ptr); \
(void) (realloced_ptr); \
(void) (size); \
} while (0)
#define SLI_MEMORY_PROFILER_TRACK_FREE(tracker_handle, ptr) \
do { \
(void) (tracker_handle); \
(void) (ptr); \
} while (0)
#endif // SLI_MEMORY_PROFILER_ENABLE_PROFILING
// Ownership tracking calls are included based on dedicated configuration
#if SLI_MEMORY_PROFILER_ENABLE_PROFILING && SLI_MEMORY_PROFILER_ENABLE_OWNERSHIP_TRACKING
/**
* @brief Macro to wrap calls to @ref sli_memory_profiler_track_ownership
*/
#define SLI_MEMORY_PROFILER_TRACK_OWNERSHIP(ptr, pc) \
do { \
void * volatile _pc = (pc); \
sli_memory_profiler_track_ownership(SLI_INVALID_MEMORY_TRACKER_HANDLE, (ptr), _pc); \
} while (0)
/**
* @brief Macro to wrap calls to @ref sli_memory_profiler_track_ownership
*/
#define SLI_MEMORY_PROFILER_TRACK_OWNERSHIP_ON_TRACKER(tracker_handle, ptr, pc) \
do { \
void * volatile _pc = (pc); \
sli_memory_profiler_track_ownership((tracker_handle), (ptr), _pc); \
} while (0)
#else // SLI_MEMORY_PROFILER_ENABLE_PROFILING && SLI_MEMORY_PROFILER_ENABLE_OWNERSHIP_TRACKING
#define SLI_MEMORY_PROFILER_TRACK_OWNERSHIP(ptr, pc) \
do { \
(void) (ptr); \
(void) (pc); \
} while (0)
#define SLI_MEMORY_PROFILER_TRACK_OWNERSHIP_ON_TRACKER(tracker_handle, ptr, pc) \
do { \
(void) (tracker_handle); \
(void) (ptr); \
(void) (pc); \
} while (0)
#endif // SLI_MEMORY_PROFILER_ENABLE_PROFILING && SLI_MEMORY_PROFILER_ENABLE_OWNERSHIP_TRACKING
/** @} end memory_profiler */
/// @endcond
#ifdef __cplusplus
}
#endif
#endif // SLI_MEMORY_PROFILER_H

View File

@@ -0,0 +1,126 @@
/***************************************************************************//**
* @file
* @brief Stub implementation of memory profiler
*******************************************************************************
* # License
* <b>Copyright 2023 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* SPDX-License-Identifier: Zlib
*
* The licensor of this software is Silicon Laboratories Inc.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
******************************************************************************/
#include "sli_memory_profiler.h"
#include "sl_status.h"
/* Create a memory tracker */
sl_status_t sli_memory_profiler_create_tracker(sli_memory_tracker_handle_t tracker_handle,
const char *description)
{
(void) tracker_handle;
(void) description;
return SL_STATUS_NOT_AVAILABLE;
}
/* Create a pool memory tracker */
sl_status_t sli_memory_profiler_create_pool_tracker(sli_memory_tracker_handle_t tracker_handle,
const char *description,
void* ptr,
size_t size)
{
(void) tracker_handle;
(void) description;
(void) ptr;
(void) size;
return SL_STATUS_NOT_AVAILABLE;
}
/* Add or update a description to a previously created memory tracker */
void sli_memory_profiler_describe_tracker(sli_memory_tracker_handle_t tracker_handle,
const char *description)
{
(void) tracker_handle;
(void) description;
}
/* Delete a memory tracker */
void sli_memory_profiler_delete_tracker(sli_memory_tracker_handle_t tracker_handle)
{
(void) tracker_handle;
}
/* Track the allocation of a memory block */
void sli_memory_profiler_track_alloc(sli_memory_tracker_handle_t tracker_handle, void * ptr, size_t size)
{
(void) tracker_handle;
(void) ptr;
(void) size;
}
/* Track the allocation of a memory block and record ownership */
void sli_memory_profiler_track_alloc_with_ownership(sli_memory_tracker_handle_t tracker_handle,
void * ptr,
size_t size,
void * pc)
{
(void) tracker_handle;
(void) ptr;
(void) size;
(void) pc;
}
/* Track the freeing of a memory block */
void sli_memory_profiler_track_free(sli_memory_tracker_handle_t tracker_handle, void * ptr)
{
(void) tracker_handle;
(void) ptr;
}
/* Track the transfer of memory allocation ownership */
void sli_memory_profiler_track_ownership(sli_memory_tracker_handle_t tracker_handle,
void * ptr,
void * pc)
{
(void) tracker_handle;
(void) ptr;
(void) pc;
}
/* Trigger the creation of a snapshot of the current state */
void sli_memory_profiler_take_snapshot(const char *name)
{
(void) name;
}
/* Send a generic log */
void sli_memory_profiler_log(uint32_t log_id,
uint32_t arg1,
uint32_t arg2,
uint32_t arg3,
void * pc)
{
(void) log_id;
(void) arg1;
(void) arg2;
(void) arg3;
(void) pc;
}