2 * \brief Simple allocator implementation
3 * \author Christian Helmuth
4 * \author Bjoern Doebel
7 * This simple allocator provides malloc() and free() using dm_mem dataspaces
8 * as backing store. The actual list-based allocator implementation is from
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.
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.
24 * FIXME check thread-safety and add locks where appropriate
27 #include <l4/dde/ddekit/memory.h>
28 #include <l4/dde/ddekit/printf.h>
29 #include <l4/dde/ddekit/panic.h>
31 #include <l4/sys/consts.h>
32 #include <l4/util/list_alloc.h>
33 #include <l4/re/dataspace>
36 #include <l4/re/util/cap_alloc>
41 #define ALLOC_SIZE (4 * L4_PAGESIZE)
43 /* malloc pool is a list allocator */
44 static l4la_free_t *malloc_pool = NULL;
48 * Allocate memory block via simple allocator
50 * \param size block size
51 * \return pointer to new memory block
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.
56 * Each chunk stores its size in the first word for free() to work.
58 void * DDEKit::simple_malloc(unsigned const size)
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);
66 unsigned *p = static_cast<unsigned *>(l4la_alloc(&malloc_pool, size2, 0));
68 /* fill pool if allocation fails */
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;
74 L4::Cap<L4Re::Dataspace> ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
79 int err = L4Re::Env::env()->mem_alloc()->alloc(ds_size, ds);
83 err = L4Re::Env::env()->rm()->attach(&res, ds_size, L4Re::Rm::Search_addr, L4::Ipc::make_cap_rw(ds), 0);
89 l4la_free(&malloc_pool, res, ds_size);
91 p = static_cast<unsigned *>(l4la_alloc(&malloc_pool, size2, 0));
94 /* store chunk size */
105 * Free memory block via simple allocator
107 * \param p pointer to memory block
109 void DDEKit::simple_free(void *p)
111 unsigned *chunk = (unsigned *)p - 1;
113 l4la_free(&malloc_pool, chunk, *chunk);