# rtai_malloc.h

    00001 /*
    00002  * Copyright (C) 2001,2002,2003,2004 Philippe Gerum <rpm@xenomai.org>.
    00003  *
    00004  * RTAI is free software; you can redistribute it and/or modify it
    00005  * under the terms of the GNU General Public License as published by
    00006  * the Free Software Foundation; either version 2 of the License, or
    00007  * (at your option) any later version.
    00008  *
    00009  * RTAI is distributed in the hope that it will be useful, but WITHOUT
    00010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    00011  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
    00012  * License for more details.
    00013  *
    00014  * You should have received a copy of the GNU General Public License
    00015  * along with RTAI; if not, write to the Free Software Foundation,
    00016  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    00017  *
    00018  * This file provides the interface to the RTAI dynamic memory
    00019  * allocator based on the algorithm described in "Design of a General
    00020  * Purpose Memory Allocator for the 4.3BSD Unix Kernel" by Marshall
    00021  * K. McKusick and Michael J. Karels.
    00022  */
    00023
    00024 #ifndef _RTAI_MALLOC_H
    00025 #define _RTAI_MALLOC_H
    00026
    00027 #include <rtai_types.h>
    00028
    00029 #ifdef __KERNEL__
    00030
    00031 #ifndef __cplusplus
    00032
    00033 #include <linux/kernel.h>
    00034 #include <linux/list.h>
    00035 #include <linux/spinlock.h>
    00036
    00037 /*
    00038  * LIMITS:
    00039  *
    00040  * Minimum page size is 2 ** RTHEAP_MINLOG2 (must be large enough to
    00041  * hold a pointer).
    00042  *
    00043  * Maximum page size is 2 ** RTHEAP_MAXLOG2.
    00044  *
    00045  * Minimum block size equals the minimum page size.
    00046  *
    00047  * Requested block size smaller than the minimum block size is
    00048  * rounded to the minimum block size.
    00049  *
    00050  * Requested block size larger than 2 times the page size is rounded
    00051  * to the next page boundary and obtained from the free page
    00052  * list. So we need a bucket for each power of two between
    00053  * RTHEAP_MINLOG2 and RTHEAP_MAXLOG2 inclusive, plus one to honor
    00054  * requests ranging from the maximum page size to twice this size.
    00055  */
    00056
    00057 #define RTHEAP_MINLOG2    4
    00058 #define RTHEAP_MAXLOG2    22
    00059 #define RTHEAP_MINALLOCSZ (1 << RTHEAP_MINLOG2)
    00060 #define RTHEAP_MINALIGNSZ RTHEAP_MINALLOCSZ
    00061 #define RTHEAP_NBUCKETS   (RTHEAP_MAXLOG2 - RTHEAP_MINLOG2 + 2)
    00062 #define RTHEAP_MAXEXTSZ   (1 << 24) /* i.e. 16 Mo */
    00063 #define RTHEAP_GLOBALSZ   (CONFIG_RTAI_MALLOC_HEAPSZ * 1024)
    00064
    00065 #define RTHEAP_PFREE   0
    00066 #define RTHEAP_PCONT   1
    00067 #define RTHEAP_PLIST   2
    00068
    00069 #define KMALLOC_LIMIT  (128 * 1024)
    00070
    00071 #define RTHEAP_NOMEM   (-1)
    00072 #define RTHEAP_PARAM   (-2)
    00073
    00074 typedef struct rtextent {
    00075
    00076     struct list_head link;
    00077
    00078     caddr_t membase,    /* Base address of the page array */
    00079             memlim,     /* Memory limit of page array */
    00080             freelist;   /* Head of the free page list */
    00081
    00082     u_char pagemap[1];  /* Beginning of page map */
    00083
    00084 } rtextent_t;
    00085
    00086 /* Creation flag */
    00087 #define RTHEAP_EXTENDABLE 0x1
    00088
    00089 /* Allocation flags */
    00090 #define RTHEAP_EXTEND    0x1
    00091
    00092 typedef struct rtheap {
    00093
    00094     spinlock_t lock;
    00095
    00096     int flags;
    00097
    00098     u_long extentsize,
    00099            pagesize,
    00100            pageshift,
    00101            hdrsize,
    00102            npages,      /* Number of pages per extent */
    00103            ubytes,
    00104            maxcont;
    00105
    00106     struct list_head extents;
    00107
    00108     caddr_t buckets[RTHEAP_NBUCKETS];
    00109
    00110 } rtheap_t;
    00111
    00112 #else /* __cplusplus */
    00113
    00114 struct rtheap;
    00115
    00116 typedef struct rtheap rtheap_t;
    00117
    00118 #endif /* !__cplusplus */
    00119
    00120 extern rtheap_t rtai_global_heap;
    00121
    00122 #define rtheap_page_size(heap)   ((heap)->pagesize)
    00123 #define rtheap_page_count(heap)  ((heap)->npages)
    00124 #define rtheap_used_mem(heap)    ((heap)->ubytes)
    00125
    00126 #define rt_malloc(sz)  rtheap_alloc(&rtai_global_heap,sz,0)
    00127 #define rt_free(p)     rtheap_free(&rtai_global_heap,p)
    00128
    00129 #ifdef __cplusplus
    00130 extern "C" {
    00131 #endif
    00132
    00133 int __rtai_heap_init(void);
    00134
    00135 void __rtai_heap_exit(void);
    00136
    00137 int rtheap_init(rtheap_t *heap,
    00138                 void *heapaddr,
    00139                 u_long heapsize,
    00140                 u_long pagesize);
    00141
    00142 void rtheap_destroy(rtheap_t *heap);
    00143
    00144 void *rtheap_alloc(rtheap_t *heap,
    00145                    u_long size,
    00146                    int flags);
    00147
    00148 int rtheap_free(rtheap_t *heap,
    00149                 void *block);
    00150
    00151 #ifdef __cplusplus
    00152 }
    00153 #endif
    00154
    00155 #endif /* __KERNEL__ */
    00156
    00157 #endif /* !_RTAI_MALLOC_H */