00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _XENO_NUCLEUS_HEAP_H
00021 #define _XENO_NUCLEUS_HEAP_H
00022
00023 #include <nucleus/queue.h>
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #if defined(__KERNEL__) || defined(__XENO_SIM__)
00046
00047 #define XNHEAP_MINLOG2 3
00048 #define XNHEAP_MAXLOG2 22
00049 #define XNHEAP_MINALLOCSZ (1 << XNHEAP_MINLOG2)
00050 #define XNHEAP_MINALIGNSZ (1 << 4)
00051 #define XNHEAP_NBUCKETS (XNHEAP_MAXLOG2 - XNHEAP_MINLOG2 + 2)
00052 #define XNHEAP_MAXEXTSZ (1 << 31)
00053
00054 #define XNHEAP_PFREE 0
00055 #define XNHEAP_PCONT 1
00056 #define XNHEAP_PLIST 2
00057
00058 typedef struct xnextent {
00059
00060 xnholder_t link;
00061
00062 #define link2extent(laddr) \
00063 ((xnextent_t *)(((char *)laddr) - (int)(&((xnextent_t *)0)->link)))
00064
00065 caddr_t membase,
00066 memlim,
00067 freelist;
00068
00069 u_char pagemap[1];
00070
00071 } xnextent_t;
00072
00073 typedef struct xnheap {
00074
00075 xnholder_t link;
00076
00077 #define link2heap(laddr) \
00078 ((xnheap_t *)(((char *)laddr) - (int)(&((xnheap_t *)0)->link)))
00079
00080 u_long extentsize,
00081 pagesize,
00082 pageshift,
00083 hdrsize,
00084 npages,
00085 ubytes,
00086 maxcont;
00087
00088 xnqueue_t extents;
00089
00090 #ifdef CONFIG_SMP
00091 xnlock_t lock;
00092 #endif
00093
00094 caddr_t buckets[XNHEAP_NBUCKETS];
00095
00096 xnholder_t *idleq;
00097
00098 xnarch_heapcb_t archdep;
00099
00100 XNARCH_DECL_DISPLAY_CONTEXT();
00101
00102 } xnheap_t;
00103
00104 extern xnheap_t kheap;
00105
00106 #define xnheap_extentsize(heap) ((heap)->extentsize)
00107 #define xnheap_page_size(heap) ((heap)->pagesize)
00108 #define xnheap_page_count(heap) ((heap)->npages)
00109 #define xnheap_usable_mem(heap) ((heap)->maxcont * countq(&(heap)->extents))
00110 #define xnheap_used_mem(heap) ((heap)->ubytes)
00111 #define xnheap_max_contiguous(heap) ((heap)->maxcont)
00112 #define xnheap_overhead(hsize,psize) \
00113 ((sizeof(xnextent_t) + (((hsize) - sizeof(xnextent_t)) / (psize)) + \
00114 XNHEAP_MINALIGNSZ - 1) & ~(XNHEAP_MINALIGNSZ - 1))
00115
00116 #define xnheap_align(size,al) (((size)+(al)-1)&(~((al)-1)))
00117
00118 #define xnmalloc(size) xnheap_alloc(&kheap,size)
00119 #define xnfree(ptr) xnheap_free(&kheap,ptr)
00120 #define xnfreesync() xnheap_finalize_free(&kheap)
00121 #define xnfreesafe(thread,ptr,ln) \
00122 do { \
00123 if (xnpod_current_thread() == thread) \
00124 xnheap_schedule_free(&kheap,ptr,ln); \
00125 else \
00126 xnheap_free(&kheap,ptr); \
00127 } while(0)
00128
00129 static inline size_t xnheap_rounded_size (size_t hsize, size_t psize)
00130 {
00131
00132
00133
00134
00135
00136
00137 hsize = xnheap_align(hsize,psize) + xnheap_overhead(hsize,psize);
00138 return xnheap_align(hsize,psize);
00139 }
00140
00141 #ifdef __cplusplus
00142 extern "C" {
00143 #endif
00144
00145
00146
00147 #ifdef __KERNEL__
00148
00149 #define XNHEAP_DEV_MINOR 254
00150
00151 int xnheap_mount(void);
00152
00153 void xnheap_umount(void);
00154
00155 int xnheap_init_mapped(xnheap_t *heap,
00156 u_long heapsize,
00157 int memflags);
00158
00159 int xnheap_destroy_mapped(xnheap_t *heap);
00160
00161 #define xnheap_mapped_offset(heap,ptr) \
00162 (((caddr_t)(ptr)) - ((caddr_t)(heap)->archdep.heapbase))
00163
00164 #define xnheap_mapped_address(heap,off) \
00165 (((caddr_t)(heap)->archdep.heapbase) + (off))
00166
00167 #define xnheap_mapped_p(heap) \
00168 ((heap)->archdep.heapbase != NULL)
00169
00170 #endif
00171
00172
00173
00174 int xnheap_init(xnheap_t *heap,
00175 void *heapaddr,
00176 u_long heapsize,
00177 u_long pagesize);
00178
00179 int xnheap_destroy(xnheap_t *heap,
00180 void (*flushfn)(xnheap_t *heap,
00181 void *extaddr,
00182 u_long extsize,
00183 void *cookie),
00184 void *cookie);
00185
00186 int xnheap_extend(xnheap_t *heap,
00187 void *extaddr,
00188 u_long extsize);
00189
00190 void *xnheap_alloc(xnheap_t *heap,
00191 u_long size);
00192
00193 int xnheap_test_and_free(xnheap_t *heap,
00194 void *block,
00195 int (*ckfn)(void *block));
00196
00197 int xnheap_free(xnheap_t *heap,
00198 void *block);
00199
00200 void xnheap_schedule_free(xnheap_t *heap,
00201 void *block,
00202 xnholder_t *link);
00203
00204 void xnheap_finalize_free_inner(xnheap_t *heap);
00205
00206 static inline void xnheap_finalize_free(xnheap_t *heap)
00207 {
00208 if (heap->idleq)
00209 xnheap_finalize_free_inner(heap);
00210 }
00211
00212 int xnheap_check_block(xnheap_t *heap,
00213 void *block);
00214
00215 #ifdef __cplusplus
00216 }
00217 #endif
00218
00219 #endif
00220
00221 #define XNHEAP_DEV_NAME "/dev/rtheap"
00222
00223 #endif