forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmempool.c
119 lines (96 loc) · 2.31 KB
/
mempool.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <string.h>
#include <sys/math_extras.h>
#include <sys/util.h>
static void *z_heap_aligned_alloc(struct k_heap *heap, size_t align, size_t size)
{
uint8_t *mem;
struct k_heap **heap_ref;
size_t excess = MAX(sizeof(struct k_heap *), align);
/*
* get a block large enough to hold an initial (aligned and hidden) heap
* pointer, as well as the space the caller requested
*/
if (size_add_overflow(size, excess, &size)) {
return NULL;
}
mem = k_heap_aligned_alloc(heap, align, size, K_NO_WAIT);
if (mem == NULL) {
return NULL;
}
/* create (void *) values in the excess equal to (void *) -1 */
memset(mem, 0xff, excess);
heap_ref = (struct k_heap **)mem;
*heap_ref = heap;
/* return address of the user area part of the block to the caller */
return mem + excess;
}
static void *z_heap_malloc(struct k_heap *heap, size_t size)
{
return z_heap_aligned_alloc(heap, sizeof(void *), size);
}
void k_free(void *ptr)
{
struct k_heap **heap_ref;
if (ptr != NULL) {
for (heap_ref = &((struct k_heap **)ptr)[-1];
*heap_ref == (struct k_heap *)-1; --heap_ref) {
/* no-op */
}
ptr = (uint8_t *)heap_ref;
k_heap_free(*heap_ref, ptr);
}
}
#if (CONFIG_HEAP_MEM_POOL_SIZE > 0)
K_HEAP_DEFINE(_system_heap, CONFIG_HEAP_MEM_POOL_SIZE);
#define _SYSTEM_HEAP (&_system_heap)
void *k_aligned_alloc(size_t align, size_t size)
{
__ASSERT(align / sizeof(void *) >= 1
&& (align % sizeof(void *)) == 0,
"align must be a multiple of sizeof(void *)");
__ASSERT((align & (align - 1)) == 0,
"align must be a power of 2");
return z_heap_aligned_alloc(_SYSTEM_HEAP, align, size);
}
void *k_calloc(size_t nmemb, size_t size)
{
void *ret;
size_t bounds;
if (size_mul_overflow(nmemb, size, &bounds)) {
return NULL;
}
ret = k_malloc(bounds);
if (ret != NULL) {
(void)memset(ret, 0, bounds);
}
return ret;
}
void k_thread_system_pool_assign(struct k_thread *thread)
{
thread->resource_pool = _SYSTEM_HEAP;
}
#else
#define _SYSTEM_HEAP NULL
#endif
void *z_thread_malloc(size_t size)
{
void *ret;
struct k_heap *heap;
if (k_is_in_isr()) {
heap = _SYSTEM_HEAP;
} else {
heap = _current->resource_pool;
}
if (heap) {
ret = z_heap_malloc(heap, size);
} else {
ret = NULL;
}
return ret;
}