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