]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/examples/libs/l4re/c++/mem_alloc/ma+rm.cc
d154e052e20db55fa47d947546f31cfd73a52a76
[l4.git] / l4 / pkg / examples / libs / l4re / c++ / mem_alloc / ma+rm.cc
1 /**
2  * \file
3  * \brief  Example of coarse grained memory allocation, in C++.
4  */
5 /*
6  * (c) 2009 Technische Universität Dresden
7  * This file is part of TUD:OS and distributed under the terms of the
8  * GNU General Public License 2.
9  * Please see the COPYING-GPL-2 file for details.
10  */
11
12 #include <l4/re/mem_alloc>
13 #include <l4/re/rm>
14 #include <l4/re/env>
15 #include <l4/re/dataspace>
16 #include <l4/re/util/cap_alloc>
17 #include <l4/sys/err.h>
18 #include <cstdio>
19 #include <cstring>
20
21 /**
22  * \brief Allocate memory, given in bytes in the granularity of pages.
23  *
24  * \param size_in_bytes   Size to allocate, in bytes, will be truncates to
25  *                          whole pages (L4_PAGESIZE).
26  * \param flags           Flags to control memory allocation:
27  *                          L4Re::Mem_alloc::Continuous:  Physically continuous memory
28  *                          L4Re::Mem_alloc::Pinned:      Pinned memory
29  *                          L4Re::Mem_alloc::Super_pages: Use big pages
30  * \retval virt_addr      Virtual address the memory is accessible under,
31  *                          undefined if return code != 0
32  *
33  * \return 0 on success, error code otherwise
34  */
35 static int allocate_mem(unsigned long size_in_bytes, unsigned long flags,
36                         void **virt_addr)
37 {
38   int r;
39   L4::Cap<L4Re::Dataspace> d;
40
41   /* Allocate a free capability index for our data space */
42   d = L4Re::Util::cap_alloc.alloc<L4Re::Dataspace>();
43   if (!d.is_valid())
44     return -L4_ENOMEM;
45
46   size_in_bytes = l4_trunc_page(size_in_bytes);
47
48   /* Allocate memory via a dataspace */
49   if ((r = L4Re::Env::env()->mem_alloc()->alloc(size_in_bytes, d, flags)))
50     return r;
51
52   /* Make the dataspace visible in our address space */
53   *virt_addr = 0;
54   if ((r = L4Re::Env::env()->rm()->attach(virt_addr, size_in_bytes,
55                                           L4Re::Rm::Search_addr, d, 0,
56                                           flags & L4Re::Mem_alloc::Super_pages
57                                             ? L4_SUPERPAGESHIFT : L4_PAGESHIFT)))
58     return r;
59
60   /* Done, virtual address is in virt_addr */
61   return 0;
62 }
63
64 /**
65  * \brief Free previously allocated memory.
66  *
67  * \param virt_addr    Virtual address return by allocate_mem
68  *
69  * \return 0 on success, error code otherwise
70  */
71 static int free_mem(void *virt_addr)
72 {
73   int r;
74   L4::Cap<L4Re::Dataspace> ds;
75
76   /* Detach memory from our address space */
77   if ((r = L4Re::Env::env()->rm()->detach(virt_addr, &ds)))
78     return r;
79
80   /* Free memory at our memory allocator, this is optional */
81   if ((r = L4Re::Env::env()->mem_alloc()->free(ds)))
82     return r;
83
84   /* Release and return capability slot to allocator */
85   L4Re::Util::cap_alloc.free(ds, L4Re::Env::env()->task().cap());
86
87   /* All went ok */
88   return 0;
89 }
90
91 int main(void)
92 {
93   void *virt;
94
95   /* Allocate memory: 16k Bytes (usually) */
96   if (allocate_mem(4 * L4_PAGESIZE, 0, &virt))
97     return 1;
98
99   printf("Allocated memory.\n");
100
101   /* Do something with the memory */
102   memset(virt, 0x12, 4 * L4_PAGESIZE);
103
104   printf("Touched memory.\n");
105
106   /* Free memory */
107   if (free_mem(virt))
108     return 2;
109
110   printf("Freed and done. Bye.\n");
111
112   return 0;
113 }