Xenomai  3.1
heap.h
1 /*
2  * Copyright (C) 2001,2002,2003 Philippe Gerum <rpm@xenomai.org>.
3  *
4  * Xenomai is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  *
9  * Xenomai is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Xenomai; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19 #ifndef _COBALT_KERNEL_HEAP_H
20 #define _COBALT_KERNEL_HEAP_H
21 
22 #include <linux/string.h>
23 #include <linux/rbtree.h>
24 #include <cobalt/kernel/lock.h>
25 #include <cobalt/kernel/list.h>
26 #include <cobalt/uapi/kernel/types.h>
27 #include <cobalt/uapi/kernel/heap.h>
28 
34 #define XNHEAP_PAGE_SHIFT 9 /* 2^9 => 512 bytes */
35 #define XNHEAP_PAGE_SIZE (1UL << XNHEAP_PAGE_SHIFT)
36 #define XNHEAP_PAGE_MASK (~(XNHEAP_PAGE_SIZE - 1))
37 #define XNHEAP_MIN_LOG2 4 /* 16 bytes */
38 /*
39  * Use bucketed memory for sizes between 2^XNHEAP_MIN_LOG2 and
40  * 2^(XNHEAP_PAGE_SHIFT-1).
41  */
42 #define XNHEAP_MAX_BUCKETS (XNHEAP_PAGE_SHIFT - XNHEAP_MIN_LOG2)
43 #define XNHEAP_MIN_ALIGN (1U << XNHEAP_MIN_LOG2)
44 /* Maximum size of a heap (4Gb - PAGE_SIZE). */
45 #define XNHEAP_MAX_HEAPSZ (4294967295U - PAGE_SIZE + 1)
46 /* Bits we need for encoding a page # */
47 #define XNHEAP_PGENT_BITS (32 - XNHEAP_PAGE_SHIFT)
48 /* Each page is represented by a page map entry. */
49 #define XNHEAP_PGMAP_BYTES sizeof(struct xnheap_pgentry)
50 
51 struct xnheap_pgentry {
52  /* Linkage in bucket list. */
53  unsigned int prev : XNHEAP_PGENT_BITS;
54  unsigned int next : XNHEAP_PGENT_BITS;
55  /* page_list or log2. */
56  unsigned int type : 6;
57  /*
58  * We hold either a spatial map of busy blocks within the page
59  * for bucketed memory (up to 32 blocks per page), or the
60  * overall size of the multi-page block if entry.type ==
61  * page_list.
62  */
63  union {
64  u32 map;
65  u32 bsize;
66  };
67 };
68 
69 /*
70  * A range descriptor is stored at the beginning of the first page of
71  * a range of free pages. xnheap_range.size is nrpages *
72  * XNHEAP_PAGE_SIZE. Ranges are indexed by address and size in
73  * rbtrees.
74  */
75 struct xnheap_range {
76  struct rb_node addr_node;
77  struct rb_node size_node;
78  size_t size;
79 };
80 
81 struct xnheap {
82  void *membase;
83  struct rb_root addr_tree;
84  struct rb_root size_tree;
85  struct xnheap_pgentry *pagemap;
86  size_t usable_size;
87  size_t used_size;
88  u32 buckets[XNHEAP_MAX_BUCKETS];
89  char name[XNOBJECT_NAME_LEN];
90  DECLARE_XNLOCK(lock);
91  struct list_head next;
92 };
93 
94 extern struct xnheap cobalt_heap;
95 
96 #define xnmalloc(size) xnheap_alloc(&cobalt_heap, size)
97 #define xnfree(ptr) xnheap_free(&cobalt_heap, ptr)
98 
99 static inline void *xnheap_get_membase(const struct xnheap *heap)
100 {
101  return heap->membase;
102 }
103 
104 static inline
105 size_t xnheap_get_size(const struct xnheap *heap)
106 {
107  return heap->usable_size;
108 }
109 
110 static inline
111 size_t xnheap_get_used(const struct xnheap *heap)
112 {
113  return heap->used_size;
114 }
115 
116 static inline
117 size_t xnheap_get_free(const struct xnheap *heap)
118 {
119  return heap->usable_size - heap->used_size;
120 }
121 
122 int xnheap_init(struct xnheap *heap,
123  void *membase, size_t size);
124 
125 void xnheap_destroy(struct xnheap *heap);
126 
127 void *xnheap_alloc(struct xnheap *heap, size_t size);
128 
129 void xnheap_free(struct xnheap *heap, void *block);
130 
131 ssize_t xnheap_check_block(struct xnheap *heap, void *block);
132 
133 void xnheap_set_name(struct xnheap *heap,
134  const char *name, ...);
135 
136 void *xnheap_vmalloc(size_t size);
137 
138 void xnheap_vfree(void *p);
139 
140 static inline void *xnheap_zalloc(struct xnheap *heap, size_t size)
141 {
142  void *p;
143 
144  p = xnheap_alloc(heap, size);
145  if (p)
146  memset(p, 0, size);
147 
148  return p;
149 }
150 
151 static inline char *xnstrdup(const char *s)
152 {
153  char *p;
154 
155  p = xnmalloc(strlen(s) + 1);
156  if (p == NULL)
157  return NULL;
158 
159  return strcpy(p, s);
160 }
161 
162 #ifdef CONFIG_XENO_OPT_VFILE
163 void xnheap_init_proc(void);
164 void xnheap_cleanup_proc(void);
165 #else /* !CONFIG_XENO_OPT_VFILE */
166 static inline void xnheap_init_proc(void) { }
167 static inline void xnheap_cleanup_proc(void) { }
168 #endif /* !CONFIG_XENO_OPT_VFILE */
169 
172 #endif /* !_COBALT_KERNEL_HEAP_H */
void xnheap_free(struct xnheap *heap, void *block)
Release a block to a memory heap.
Definition: heap.c:618
void * xnheap_alloc(struct xnheap *heap, size_t size)
Allocate a memory block from a memory heap.
Definition: heap.c:531
void xnheap_destroy(struct xnheap *heap)
Destroys a memory heap.
Definition: heap.c:800
void xnheap_set_name(struct xnheap *heap, const char *name,...)
Set the heap&#39;s name string.
Definition: heap.c:829