00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _XENO_NUCLEUS_HEAP_H
00023 #define _XENO_NUCLEUS_HEAP_H
00024
00025 #include <nucleus/queue.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #if defined(__KERNEL__) || defined(__XENO_SIM__)
00048
00049 #ifndef CONFIG_XENO_OPT_DEBUG_NUCLEUS
00050 #define CONFIG_XENO_OPT_DEBUG_NUCLEUS 0
00051 #endif
00052
00053 #define XNHEAP_PAGE_SIZE 512
00054 #define XNHEAP_PAGE_MASK (~(XNHEAP_PAGE_SIZE-1))
00055 #define XNHEAP_PAGE_ALIGN(addr) (((addr)+XNHEAP_PAGE_SIZE-1)&XNHEAP_PAGE_MASK)
00056
00057 #define XNHEAP_MINLOG2 3
00058 #define XNHEAP_MAXLOG2 22
00059 #define XNHEAP_MINALLOCSZ (1 << XNHEAP_MINLOG2)
00060 #define XNHEAP_MINALIGNSZ (1 << 4)
00061 #define XNHEAP_NBUCKETS (XNHEAP_MAXLOG2 - XNHEAP_MINLOG2 + 2)
00062 #define XNHEAP_MAXEXTSZ (1 << 31)
00063
00064 #define XNHEAP_PFREE 0
00065 #define XNHEAP_PCONT 1
00066 #define XNHEAP_PLIST 2
00067
00068 #define XNHEAP_GFP_NONCACHED (1 << __GFP_BITS_SHIFT)
00069
00070 struct xnpagemap {
00071 unsigned int type : 8;
00072 unsigned int bcount : 24;
00073 };
00074
00075 typedef struct xnextent {
00076
00077 xnholder_t link;
00078
00079 #define link2extent(ln) container_of(ln, xnextent_t, link)
00080
00081 caddr_t membase,
00082 memlim,
00083 freelist;
00084
00085 struct xnpagemap pagemap[1];
00086
00087 } xnextent_t;
00088
00089 typedef struct xnheap {
00090
00091 xnholder_t link;
00092
00093 #define link2heap(ln) container_of(ln, xnheap_t, link)
00094
00095 u_long extentsize,
00096 pagesize,
00097 pageshift,
00098 hdrsize,
00099 npages,
00100 ubytes,
00101 maxcont;
00102
00103 xnqueue_t extents;
00104
00105 DECLARE_XNLOCK(lock);
00106
00107 struct xnbucket {
00108 caddr_t freelist;
00109 int fcount;
00110 } buckets[XNHEAP_NBUCKETS];
00111
00112 xnholder_t *idleq[XNARCH_NR_CPUS];
00113
00114 xnarch_heapcb_t archdep;
00115
00116 XNARCH_DECL_DISPLAY_CONTEXT();
00117
00118 xnholder_t stat_link;
00119
00120 char label[XNOBJECT_NAME_LEN+16];
00121
00122 } xnheap_t;
00123
00124 extern xnheap_t kheap;
00125
00126 #if CONFIG_XENO_OPT_SYS_STACKPOOLSZ > 0
00127 extern xnheap_t kstacks;
00128 #endif
00129
00130 #define xnheap_extentsize(heap) ((heap)->extentsize)
00131 #define xnheap_page_size(heap) ((heap)->pagesize)
00132 #define xnheap_page_count(heap) ((heap)->npages)
00133 #define xnheap_usable_mem(heap) ((heap)->maxcont * countq(&(heap)->extents))
00134 #define xnheap_used_mem(heap) ((heap)->ubytes)
00135 #define xnheap_max_contiguous(heap) ((heap)->maxcont)
00136
00137 static inline size_t xnheap_align(size_t size, size_t al)
00138 {
00139
00140 return ((size+al-1)&(~(al-1)));
00141 }
00142
00143 static inline size_t xnheap_external_overhead(size_t hsize, size_t psize)
00144 {
00145 size_t pages = (hsize + psize - 1) / psize;
00146 return xnheap_align(sizeof(xnextent_t)
00147 + pages * sizeof(struct xnpagemap), psize);
00148 }
00149
00150 static inline size_t xnheap_internal_overhead(size_t hsize, size_t psize)
00151 {
00152
00153
00154
00155
00156
00157 return xnheap_align((sizeof(xnextent_t) * psize
00158 + sizeof(struct xnpagemap) * hsize)
00159 / (psize + sizeof(struct xnpagemap)), psize);
00160 }
00161
00162 #define xnmalloc(size) xnheap_alloc(&kheap,size)
00163 #define xnfree(ptr) xnheap_free(&kheap,ptr)
00164 #define xnfreesync() xnheap_finalize_free(&kheap)
00165 #define xnfreesafe(thread, ptr, ln) \
00166 do { \
00167 if (xnpod_current_p(thread)) \
00168 xnheap_schedule_free(&kheap, ptr, ln); \
00169 else \
00170 xnheap_free(&kheap,ptr); \
00171 } while(0)
00172
00173 static inline size_t xnheap_rounded_size(size_t hsize, size_t psize)
00174 {
00175
00176
00177
00178
00179
00180
00181
00182
00183 if (hsize < 2 * psize)
00184 hsize = 2 * psize;
00185 hsize += xnheap_external_overhead(hsize, psize);
00186 return xnheap_align(hsize, psize);
00187 }
00188
00189 #ifdef __cplusplus
00190 extern "C" {
00191 #endif
00192
00193
00194
00195 #ifdef __KERNEL__
00196
00197 #define XNHEAP_DEV_MINOR 254
00198
00199 int xnheap_mount(void);
00200
00201 void xnheap_umount(void);
00202
00203 void xnheap_init_proc(void);
00204
00205 void xnheap_cleanup_proc(void);
00206
00207 int xnheap_init_mapped(xnheap_t *heap,
00208 u_long heapsize,
00209 int memflags);
00210
00211 void xnheap_destroy_mapped(xnheap_t *heap,
00212 void (*release)(struct xnheap *heap),
00213 void __user *mapaddr);
00214
00215 #define xnheap_mapped_offset(heap,ptr) \
00216 (((caddr_t)(ptr)) - ((caddr_t)(heap)->archdep.heapbase))
00217
00218 #define xnheap_mapped_address(heap,off) \
00219 (((caddr_t)(heap)->archdep.heapbase) + (off))
00220
00221 #define xnheap_mapped_p(heap) \
00222 ((heap)->archdep.heapbase != NULL)
00223
00224 #endif
00225
00226
00227
00228 int xnheap_init(xnheap_t *heap,
00229 void *heapaddr,
00230 u_long heapsize,
00231 u_long pagesize);
00232
00233 void xnheap_set_label(xnheap_t *heap, const char *name, ...);
00234
00235 void xnheap_destroy(xnheap_t *heap,
00236 void (*flushfn)(xnheap_t *heap,
00237 void *extaddr,
00238 u_long extsize,
00239 void *cookie),
00240 void *cookie);
00241
00242 int xnheap_extend(xnheap_t *heap,
00243 void *extaddr,
00244 u_long extsize);
00245
00246 void *xnheap_alloc(xnheap_t *heap,
00247 u_long size);
00248
00249 int xnheap_test_and_free(xnheap_t *heap,
00250 void *block,
00251 int (*ckfn)(void *block));
00252
00253 int xnheap_free(xnheap_t *heap,
00254 void *block);
00255
00256 void xnheap_schedule_free(xnheap_t *heap,
00257 void *block,
00258 xnholder_t *link);
00259
00260 void xnheap_finalize_free_inner(xnheap_t *heap,
00261 int cpu);
00262
00263 static inline void xnheap_finalize_free(xnheap_t *heap)
00264 {
00265 int cpu = xnarch_current_cpu();
00266
00267 XENO_ASSERT(NUCLEUS,
00268 spltest() != 0,
00269 xnpod_fatal("%s called in unsafe context", __FUNCTION__));
00270
00271 if (heap->idleq[cpu])
00272 xnheap_finalize_free_inner(heap, cpu);
00273 }
00274
00275 int xnheap_check_block(xnheap_t *heap,
00276 void *block);
00277
00278 #ifdef __cplusplus
00279 }
00280 #endif
00281
00282 #endif
00283
00284 #define XNHEAP_DEV_NAME "/dev/rtheap"
00285
00286 #endif