/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef ZEPHYR_INCLUDE_SYS_HEAP_LISTENER_H
#define ZEPHYR_INCLUDE_SYS_HEAP_LISTENER_H

#include <stdint.h>
#include <toolchain.h>
#include <sys/slist.h>

#ifdef __cplusplus
extern "C" {
#endif

#if defined(CONFIG_HEAP_LISTENER) || defined(__DOXYGEN__)

/**
 * @defgroup heap_listener_apis Heap Listener APIs
 * @{
 */

enum heap_event_types {
	/*
	 * Dummy event so an un-initialized but zero-ed listener node
	 * will not trigger any callbacks.
	 */
	HEAP_EVT_UNKNOWN = 0,

	HEAP_RESIZE,
	HEAP_ALLOC,
	HEAP_FREE,
	HEAP_REALLOC,

	HEAP_MAX_EVENTS
};

/**
 * @typedef heap_listener_resize_cb_t
 * @brief Callback used when heap is resized
 *
 * @note Minimal C library does not emit this event.
 *
 * @param heap_id Identifier of heap being resized
 * @param old_heap_end Pointer to end of heap before resize
 * @param new_heap_end Pointer to end of heap after resize
 */
typedef void (*heap_listener_resize_cb_t)(uintptr_t heap_id,
					  void *old_heap_end,
					  void *new_heap_end);

/**
 * @typedef heap_listener_alloc_cb_t
 * @brief Callback used when there is heap allocation
 *
 * @note Heaps managed by libraries outside of code in
 *       Zephyr main code repository may not emit this event.
 *
 * @note The number of bytes allocated may not match exactly
 *       to the request to the allocation function. Internal
 *       mechanism of the heap may allocate more than
 *       requested.
 *
 * @param heap_id Heap identifier
 * @param mem Pointer to the allocated memory
 * @param bytes Size of allocated memory
 */
typedef void (*heap_listener_alloc_cb_t)(uintptr_t heap_id,
					 void *mem, size_t bytes);

/**
 * @typedef heap_listener_free_cb_t
 * @brief Callback used when memory is freed from heap
 *
 * @note Heaps managed by libraries outside of code in
 *       Zephyr main code repository may not emit this event.
 *
 * @note The number of bytes freed may not match exactly to
 *       the request to the allocation function. Internal
 *       mechanism of the heap dictates how memory is
 *       allocated or freed.
 *
 * @param heap_id Heap identifier
 * @param mem Pointer to the freed memory
 * @param bytes Size of freed memory
 */
typedef void (*heap_listener_free_cb_t)(uintptr_t heap_id,
					void *mem, size_t bytes);

struct heap_listener {
	/** Singly linked list node */
	sys_snode_t node;

	/**
	 * Identifier of the heap whose events are listened.
	 *
	 * It can be a heap pointer, if the heap is represented as an object,
	 * or 0 in the case of the global libc heap.
	 */
	uintptr_t heap_id;

	/**
	 * The heap event to be notified.
	 */
	enum heap_event_types event;

	union {
		heap_listener_alloc_cb_t alloc_cb;
		heap_listener_free_cb_t free_cb;
		heap_listener_resize_cb_t resize_cb;
	};
};

/**
 * @brief Register heap event listener
 *
 * Add the listener to the global list of heap listeners that can be notified by
 * different heap implementations upon certain events related to the heap usage.
 *
 * @param listener Pointer to the heap_listener object
 */
void heap_listener_register(struct heap_listener *listener);

/**
 * @brief Unregister heap event listener
 *
 * Remove the listener from the global list of heap listeners that can be
 * notified by different heap implementations upon certain events related to the
 * heap usage.
 *
 * @param listener Pointer to the heap_listener object
 */
void heap_listener_unregister(struct heap_listener *listener);

/**
 * @brief Notify listeners of heap allocation event
 *
 * Notify registered heap event listeners with matching heap identifier that an
 * allocation has been done on heap
 *
 * @param heap_id Heap identifier
 * @param mem Pointer to the allocated memory
 * @param bytes Size of allocated memory
 */
void heap_listener_notify_alloc(uintptr_t heap_id, void *mem, size_t bytes);

/**
 * @brief Notify listeners of heap free event
 *
 * Notify registered heap event listeners with matching heap identifier that
 * memory is freed on heap
 *
 * @param heap_id Heap identifier
 * @param mem Pointer to the freed memory
 * @param bytes Size of freed memory
 */
void heap_listener_notify_free(uintptr_t heap_id, void *mem, size_t bytes);

/**
 * @brief Notify listeners of heap resize event
 *
 * Notify registered heap event listeners with matching heap identifier that the
 * heap has been resized.
 *
 * @param heap_id Heap identifier
 * @param old_heap_end Address of the heap end before the change
 * @param new_heap_end Address of the heap end after the change
 */
void heap_listener_notify_resize(uintptr_t heap_id, void *old_heap_end, void *new_heap_end);

/**
 * @brief Construct heap identifier from heap pointer
 *
 * Construct a heap identifier from a pointer to the heap object, such as
 * sys_heap.
 *
 * @param heap_pointer Pointer to the heap object
 */
#define HEAP_ID_FROM_POINTER(heap_pointer) ((uintptr_t)heap_pointer)

/**
 * @brief Libc heap identifier
 *
 * Identifier of the global libc heap.
 */
#define HEAP_ID_LIBC ((uintptr_t)0)

/**
 * @brief Define heap event listener node for allocation event
 *
 * Sample usage:
 * @code
 * void on_heap_alloc(uintptr_t heap_id, void *mem, size_t bytes)
 * {
 *   LOG_INF("Memory allocated at %p, size %ld", heap_id, mem, bytes);
 * }
 *
 * HEAP_LISTENER_ALLOC_DEFINE(my_listener, HEAP_ID_LIBC, on_heap_alloc);
 * @endcode
 *
 * @param name		Name of the heap event listener object
 * @param _heap_id	Identifier of the heap to be listened
 * @param _alloc_cb	Function to be called for allocation event
 */
#define HEAP_LISTENER_ALLOC_DEFINE(name, _heap_id, _alloc_cb) \
	struct heap_listener name = { \
		.heap_id = _heap_id, \
		.event = HEAP_ALLOC, \
		{ \
			.alloc_cb = _alloc_cb \
		}, \
	}

/**
 * @brief Define heap event listener node for free event
 *
 * Sample usage:
 * @code
 * void on_heap_free(uintptr_t heap_id, void *mem, size_t bytes)
 * {
 *   LOG_INF("Memory freed at %p, size %ld", heap_id, mem, bytes);
 * }
 *
 * HEAP_LISTENER_FREE_DEFINE(my_listener, HEAP_ID_LIBC, on_heap_free);
 * @endcode
 *
 * @param name		Name of the heap event listener object
 * @param _heap_id	Identifier of the heap to be listened
 * @param _free_cb	Function to be called for free event
 */
#define HEAP_LISTENER_FREE_DEFINE(name, _heap_id, _free_cb) \
	struct heap_listener name = { \
		.heap_id = _heap_id, \
		.event = HEAP_FREE, \
		{ \
			.free_cb = _free_cb \
		}, \
	}

/**
 * @brief Define heap event listener node for resize event
 *
 * Sample usage:
 * @code
 * void on_heap_resized(uintptr_t heap_id, void *old_heap_end, void *new_heap_end)
 * {
 *   LOG_INF("Libc heap end moved from %p to %p", old_heap_end, new_heap_end);
 * }
 *
 * HEAP_LISTENER_RESIZE_DEFINE(my_listener, HEAP_ID_LIBC, on_heap_resized);
 * @endcode
 *
 * @param name		Name of the heap event listener object
 * @param _heap_id	Identifier of the heap to be listened
 * @param _resize_cb	Function to be called when the listened heap is resized
 */
#define HEAP_LISTENER_RESIZE_DEFINE(name, _heap_id, _resize_cb) \
	struct heap_listener name = { \
		.heap_id = _heap_id, \
		.event = HEAP_RESIZE, \
		{ \
			.resize_cb = _resize_cb \
		}, \
	}

/** @} */

#else /* CONFIG_HEAP_LISTENER */

#define HEAP_ID_FROM_POINTER(heap_pointer) ((uintptr_t)NULL)

static inline void heap_listener_notify_alloc(uintptr_t heap_id, void *mem, size_t bytes)
{
	ARG_UNUSED(heap_id);
	ARG_UNUSED(mem);
	ARG_UNUSED(bytes);
}

static inline void heap_listener_notify_free(uintptr_t heap_id, void *mem, size_t bytes)
{
	ARG_UNUSED(heap_id);
	ARG_UNUSED(mem);
	ARG_UNUSED(bytes);
}

static inline void heap_listener_notify_resize(uintptr_t heap_id, void *old_heap_end,
					       void *new_heap_end)
{
	ARG_UNUSED(heap_id);
	ARG_UNUSED(old_heap_end);
	ARG_UNUSED(new_heap_end);
}

#endif /* CONFIG_HEAP_LISTENER */

#ifdef __cplusplus
}
#endif

#endif /* ZEPHYR_INCLUDE_SYS_HEAP_LISTENER_H */
