]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/dde/ddekit/src/malloc.cc
Some minor fixes.
[l4.git] / l4 / pkg / dde / ddekit / src / malloc.cc
1 /*
2  * \brief   Simple allocator implementation
3  *
4  * This simple allocator provides malloc() and free() using dm_mem dataspaces
5  * as backing store. The actual list-based allocator implementation is from
6  * l4util resp. Fiasco.
7  *
8  * For large allocations and slab-based OS-specific allocators
9  * ddekit_large_malloc and ddekit_slab_*() should be used. The blocks
10  * allocated via this allocator CANNOT be used for DMA or other device
11  * operations, i.e., there exists no virt->phys mapping.
12  */
13
14 /*
15  * This file is part of DDEKit.
16  *
17  * (c) 2006-2012 Bjoern Doebel <doebel@os.inf.tu-dresden.de>
18  *               Christian Helmuth <ch12@os.inf.tu-dresden.de>
19  *               Thomas Friebel <tf13@os.inf.tu-dresden.de>
20  *     economic rights: Technische Universitaet Dresden (Germany)
21  *
22  * This file is part of TUD:OS and distributed under the terms of the
23  * GNU General Public License 2.
24  * Please see the COPYING-GPL-2 file for details.
25  */
26
27 /*
28  * FIXME check thread-safety and add locks where appropriate
29  */
30
31 #include <l4/dde/ddekit/memory.h>
32 #include <l4/dde/ddekit/printf.h>
33 #include <l4/dde/ddekit/panic.h>
34
35 #include <l4/sys/consts.h>
36 #include <l4/util/list_alloc.h>
37 #include <l4/re/dataspace>
38 #include <l4/re/rm>
39 #include <l4/re/env>
40 #include <l4/re/util/cap_alloc>
41
42 #include <pthread.h>
43
44
45 /* configuration */
46 #define ALLOC_SIZE     (4 * L4_PAGESIZE)
47
48 /* malloc pool is a list allocator */
49 static l4la_free_t *malloc_pool = NULL;
50 static pthread_mutex_t malloc_mtx = PTHREAD_MUTEX_INITIALIZER;
51
52
53 /**
54  * Allocate memory block via simple allocator
55  *
56  * \param size  block size
57  * \return pointer to new memory block
58  *
59  * The blocks allocated via this allocator CANNOT be used for DMA or other
60  * device operations, i.e., there exists no virt->phys mapping.
61  *
62  * Each chunk stores its size in the first word for free() to work.
63  */
64 EXTERN_C void * ddekit_simple_malloc(unsigned size)
65 {
66         pthread_mutex_lock(&malloc_mtx);
67         /* we store chunk size in the first word of the chunk */
68         size += sizeof(unsigned);
69
70         /* try to allocate */
71         unsigned *p = static_cast<unsigned *>(l4la_alloc(&malloc_pool, size, 0));
72
73         /* fill pool if allocation fails */
74         if (!p) {
75                 /* size of allocated dataspace is at least ALLOC_SIZE */
76                 unsigned ds_size = l4_round_page(size);
77                 ds_size = (ds_size > ALLOC_SIZE) ? ds_size : ALLOC_SIZE;
78
79                 L4::Cap<L4Re::Dataspace> ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
80                 if (!ds.is_valid())
81                         goto err_out;
82
83                 void *res = 0;
84                 int err = L4Re::Env::env()->mem_alloc()->alloc(ds_size, ds);
85                 if (err < 0)
86                         goto err_out;
87
88                 err = L4Re::Env::env()->rm()->attach(&res, ds_size, L4Re::Rm::Search_addr, L4::Ipc::make_cap_rw(ds), 0);
89                 if (err < 0)
90                         goto err_out;
91
92                 if (!res) 
93                         goto err_out;
94
95                 l4la_free(&malloc_pool, res, ds_size);
96                 p = static_cast<unsigned *>(l4la_alloc(&malloc_pool, size, 0));
97         }
98
99         /* store chunk size */
100         if (p) {
101                 *p = size;
102                 p++;
103         }
104
105 err_out:
106         // FIXME: goto is error prone in C++
107         // FIXME: missing nearly all free operations here
108         pthread_mutex_unlock(&malloc_mtx);
109
110         return p;
111 }
112
113
114 /**
115  * Free memory block via simple allocator
116  *
117  * \param p  pointer to memory block
118  */
119 EXTERN_C void ddekit_simple_free(void *p)
120 {
121         unsigned *chunk = (unsigned *)p - 1;
122         if (p)
123         {
124                 pthread_mutex_lock(&malloc_mtx);
125                 l4la_free(&malloc_pool, chunk, *chunk);
126                 pthread_mutex_unlock(&malloc_mtx);
127         }
128 }