1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/spinlock.h>
8 #include <zephyr/sys/heap_listener.h>
9 
10 static struct k_spinlock heap_listener_lock;
11 static sys_slist_t heap_listener_list = SYS_SLIST_STATIC_INIT(&heap_listener_list);
12 
heap_listener_register(struct heap_listener * listener)13 void heap_listener_register(struct heap_listener *listener)
14 {
15 	k_spinlock_key_t key = k_spin_lock(&heap_listener_lock);
16 
17 	sys_slist_append(&heap_listener_list, &listener->node);
18 
19 	k_spin_unlock(&heap_listener_lock, key);
20 }
21 
heap_listener_unregister(struct heap_listener * listener)22 void heap_listener_unregister(struct heap_listener *listener)
23 {
24 	k_spinlock_key_t key = k_spin_lock(&heap_listener_lock);
25 
26 	sys_slist_find_and_remove(&heap_listener_list, &listener->node);
27 
28 	k_spin_unlock(&heap_listener_lock, key);
29 }
30 
heap_listener_notify_alloc(uintptr_t heap_id,void * mem,size_t bytes)31 void heap_listener_notify_alloc(uintptr_t heap_id, void *mem, size_t bytes)
32 {
33 	struct heap_listener *listener;
34 	k_spinlock_key_t key = k_spin_lock(&heap_listener_lock);
35 
36 	SYS_SLIST_FOR_EACH_CONTAINER(&heap_listener_list, listener, node) {
37 		if (listener->heap_id == heap_id
38 		    && listener->alloc_cb != NULL
39 		    && listener->event == HEAP_ALLOC) {
40 			listener->alloc_cb(heap_id, mem, bytes);
41 		}
42 	}
43 
44 	k_spin_unlock(&heap_listener_lock, key);
45 }
46 
heap_listener_notify_free(uintptr_t heap_id,void * mem,size_t bytes)47 void heap_listener_notify_free(uintptr_t heap_id, void *mem, size_t bytes)
48 {
49 	struct heap_listener *listener;
50 	k_spinlock_key_t key = k_spin_lock(&heap_listener_lock);
51 
52 	SYS_SLIST_FOR_EACH_CONTAINER(&heap_listener_list, listener, node) {
53 		if (listener->heap_id == heap_id
54 		    && listener->free_cb != NULL
55 		    && listener->event == HEAP_FREE) {
56 			listener->free_cb(heap_id, mem, bytes);
57 		}
58 	}
59 
60 	k_spin_unlock(&heap_listener_lock, key);
61 }
62 
heap_listener_notify_resize(uintptr_t heap_id,void * old_heap_end,void * new_heap_end)63 void heap_listener_notify_resize(uintptr_t heap_id, void *old_heap_end, void *new_heap_end)
64 {
65 	struct heap_listener *listener;
66 	k_spinlock_key_t key = k_spin_lock(&heap_listener_lock);
67 
68 	SYS_SLIST_FOR_EACH_CONTAINER(&heap_listener_list, listener, node) {
69 		if (listener->heap_id == heap_id
70 		    && listener->resize_cb != NULL
71 		    && listener->event == HEAP_RESIZE) {
72 			listener->resize_cb(heap_id, old_heap_end, new_heap_end);
73 		}
74 	}
75 
76 	k_spin_unlock(&heap_listener_lock, key);
77 }
78