hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
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
/*
 * Copyright (C) 2018 Philippe Gerum <rpm@xenomai.org>.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 */
#include <stdlib.h>
#include "boilerplate/heapmem.h"
#include "copperplate/heapobj.h"
#include "copperplate/debug.h"
#include "copperplate/tunables.h"
#include "xenomai/init.h"
 
#define MIN_HEAPMEM_HEAPSZ  (64 * 1024)
 
struct heap_memory heapmem_main;
 
int __heapobj_init_private(struct heapobj *hobj, const char *name,
              size_t size, void *mem)
{
   struct heap_memory *heap;
   void *_mem = mem;
   int ret;
 
   heap = malloc(sizeof(*heap));
   if (heap == NULL)
       return -ENOMEM;
 
   if (mem == NULL) {
       size = HEAPMEM_ARENA_SIZE(size); /* Count meta-data in. */
       mem = malloc(size);
       if (mem == NULL) {
           free(heap);
           return -ENOMEM;
       }
   }
   
   if (name)
       snprintf(hobj->name, sizeof(hobj->name), "%s", name);
   else
       snprintf(hobj->name, sizeof(hobj->name), "%p", hobj);
 
   hobj->pool = heap;
   hobj->size = size;
 
   ret = heapmem_init(hobj->pool, mem, size);
   if (ret) {
       if (_mem == NULL)
           free(mem);
       free(heap);
       return ret;
   }
 
   return 0;
}
 
int heapobj_init_array_private(struct heapobj *hobj, const char *name,
                  size_t size, int elems)
{
   size_t log2;
 
   if (size == 0 || elems <= 0)
       return __bt(-EINVAL);
 
   log2 = sizeof(size) * CHAR_BIT - 1 -
       xenomai_count_leading_zeros(size);
 
   /*
    * Heapmem aligns individual object sizes on the next ^2
    * boundary, do likewise when determining the overall heap
    * size, so that we can allocate as many as @elems items.
    */
   if (size & (size - 1))
       log2++;
 
   size = 1 << log2;
 
   return __bt(__heapobj_init_private(hobj, name,
                      size * elems, NULL));
}
 
int heapobj_pkg_init_private(void)
{
   size_t size;
   void *mem;
   int ret;
 
#ifdef CONFIG_XENO_PSHARED
   size = MIN_HEAPMEM_HEAPSZ;
#else
   size = __copperplate_setup_data.mem_pool;
   if (size < MIN_HEAPMEM_HEAPSZ)
       size = MIN_HEAPMEM_HEAPSZ;
#endif
   size = HEAPMEM_ARENA_SIZE(size);
   mem = malloc(size);
   if (mem == NULL)
       return -ENOMEM;
 
   ret = heapmem_init(&heapmem_main, mem, size);
   if (ret) {
       free(mem);
       return ret;
   }
 
   return 0;
}