2 * \brief Simple allocator implementation
4 * This simple allocator provides malloc() and free() using dm_mem dataspaces
5 * as backing store. The actual list-based allocator implementation is from
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.
15 * This file is part of DDEKit.
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)
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.
28 * FIXME check thread-safety and add locks where appropriate
31 #include <l4/dde/ddekit/memory.h>
32 #include <l4/dde/ddekit/printf.h>
33 #include <l4/dde/ddekit/panic.h>
35 #include <l4/sys/consts.h>
36 #include <l4/util/list_alloc.h>
37 #include <l4/re/dataspace>
40 #include <l4/re/util/cap_alloc>
46 #define ALLOC_SIZE (4 * L4_PAGESIZE)
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;
54 * Allocate memory block via simple allocator
56 * \param size block size
57 * \return pointer to new memory block
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.
62 * Each chunk stores its size in the first word for free() to work.
64 EXTERN_C void * ddekit_simple_malloc(unsigned size)
66 pthread_mutex_lock(&malloc_mtx);
67 /* we store chunk size in the first word of the chunk */
68 size += sizeof(unsigned);
71 unsigned *p = static_cast<unsigned *>(l4la_alloc(&malloc_pool, size, 0));
73 /* fill pool if allocation fails */
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;
79 L4::Cap<L4Re::Dataspace> ds = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
84 int err = L4Re::Env::env()->mem_alloc()->alloc(ds_size, ds);
88 err = L4Re::Env::env()->rm()->attach(&res, ds_size, L4Re::Rm::Search_addr, L4::Ipc::make_cap_rw(ds), 0);
95 l4la_free(&malloc_pool, res, ds_size);
96 p = static_cast<unsigned *>(l4la_alloc(&malloc_pool, size, 0));
99 /* store chunk size */
106 // FIXME: goto is error prone in C++
107 // FIXME: missing nearly all free operations here
108 pthread_mutex_unlock(&malloc_mtx);
115 * Free memory block via simple allocator
117 * \param p pointer to memory block
119 EXTERN_C void ddekit_simple_free(void *p)
121 unsigned *chunk = (unsigned *)p - 1;
124 pthread_mutex_lock(&malloc_mtx);
125 l4la_free(&malloc_pool, chunk, *chunk);
126 pthread_mutex_unlock(&malloc_mtx);