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