1 /*
2  * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
3  *     economic rights: Technische Universität Dresden (Germany)
4  *
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU General Public License 2.
7  * Please see the COPYING-GPL-2 file for details.
8  */
9 #pragma once
10 
11 #include <l4/cxx/exceptions>
12 
13 class Dbg;
14 
15 /**
16  * Base page allocator.
17  *
18  * Manages the physical memory pages available to Moe.
19  */
20 class Single_page_alloc_base
21 {
22 public:
23   enum Nothrow { nothrow };
24 
25 protected:
26   Single_page_alloc_base();
27 
28 public:
29   static void *_alloc_max(unsigned long min, unsigned long *max,
30                           unsigned align, unsigned granularity);
31   static void *_alloc(Nothrow, unsigned long size, unsigned long align = 0);
32   static void *_alloc(unsigned long size, unsigned long align = 0)
33   {
34     void *r = _alloc(nothrow, size, align);
35     if (!r)
36       throw L4::Out_of_memory();
37     return r;
38   }
39   static void _free(void *p, unsigned long size, bool initial_mem = false);
40   static unsigned long _avail();
41 
42 #ifndef NDEBUG
43   static void _dump_free(Dbg &dbg);
44 #endif
45 };
46 
47 class Single_page_unique_ptr
48 {
49 private:
50   void *_p = 0;
51   unsigned long _s;
52 
53 public:
release()54   void *release()
55   {
56     void *p = _p;
57     _p = 0;
58     return p;
59   }
60 
61   void reset(void *n = 0, unsigned long size = 0)
62   {
63     if (n == _p)
64       return;
65 
66     void *p = _p;
67     unsigned long s = _s;
68 
69     _p = n;
70     if (n)
71       _s = size;
72 
73     if (p)
74       Single_page_alloc_base::_free(p, s);
75   }
76 
size()77   unsigned long size() const { return _s; }
78 
get()79   void *get() const { return _p; }
80   void *operator * () const { return _p; }
81 
82   Single_page_unique_ptr() = default;
Single_page_unique_ptr(void * p,unsigned long size)83   Single_page_unique_ptr(void *p, unsigned long size) : _p(p), _s(size) {}
84 
~Single_page_unique_ptr()85   ~Single_page_unique_ptr()
86   { reset(); }
87 
88   Single_page_unique_ptr &operator = (Single_page_unique_ptr &&o)
89   {
90     if (this == &o)
91       return *this;
92 
93     reset(o._p, o._s);
94     o._p = 0;
95     return *this;
96   }
97 };
98