2 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>,
4 * Carsten Weinhold <weinhold@os.inf.tu-dresden.de>
5 * economic rights: Technische Universität Dresden (Germany)
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.
14 #include <l4/cxx/iostream>
15 #include <l4/sys/kdebug.h>
17 Mem_man Mem_man::_ram;
20 Mem_man::find(Region const &r, bool force) const
25 Tree::Const_iterator n = _tree.find(r);
29 if (n->contains(r) || force)
36 Mem_man::add(Region const &r)
38 /* try to merge with prev region */
42 rs.start(rs.start()-1);
44 Tree::Node n = _tree.find_node(rs);
45 if (n && n->owner() == r.owner())
48 int err = _tree.remove(*n);
50 { L4::cout << "err=" << err << " dump:\n"; dump(); enter_kdebug("BUG");}
54 /* try to merge with next region */
56 if (rs.end() + 1 != 0)
60 Tree::Node n = _tree.find_node(rs);
61 if (n && n->owner() == r.owner())
64 int err = _tree.remove(*n);
66 { L4::cout << "err=" << err << " dump:\n"; dump(); enter_kdebug("BUG");}
70 /* do throw away regions owned by myself */
71 if (r.owner() == sigma0_taskno)
74 while (_tree.insert(r).second == -_tree.E_nomem)
75 if (!ram()->morecore())
78 L4::cout << PROG_NAME": Out of memory\n";
86 Mem_man::add_free(Region const &r)
91 // calculate the combined set of all overlapping regions within the tree
94 Tree::Node n = _tree.find_node(r);
99 if (n->start() < r.start())
101 if (n->end() > r.end())
104 int err = _tree.remove(*n);
106 { L4::cout << "err=" << err << " dump:\n"; dump(); enter_kdebug("BUG");}
113 Mem_man::alloc_from(Region const *r2, Region const &_r)
116 if (r2->owner() && r2->owner() != r.owner())
119 if (r2->owner() == r.owner())
124 // L4::cout << "dump " << r << " " << *r2 << "\n"; dump();
125 int err = _tree.remove(*r2);
127 { L4::cout << "err=" << err << " dump:\n"; dump(); enter_kdebug("BUG"); }
131 if (r.start() == r2->start())
133 r2->start(r.end()+1);
134 //L4::cout << "move start to " << *r2 << '\n';
139 if (r.end() == r2->end())
141 r2->end(r.start()-1);
142 //L4::cout << "shrink end to " << *r2 << '\n';
147 Region const nr(r.end()+1, r2->end(),r2->owner());
148 r2->end(r.start()-1);
149 //L4::cout << "split to " << *r2 << "; " << nr << '\n';
159 Mem_man::alloc(Region const &r, bool force)
163 Region const *r2 = find(r, force);
167 //L4::cout << "alloc_from(" << *r2 << ", " << r << ")\n";
168 if (!alloc_from(r2, r))
175 Mem_man::reserve(Region const &r)
180 Region const *r2 = find(r, true);
184 return alloc_from(r2, r);
191 Tree::Item_type *n = 0;
192 for (Tree::Rev_iterator i = _tree.rbegin(); i != _tree.rend(); ++i)
197 l4_addr_t st = l4_round_page(i->start());
199 if (st < i->end() && i->end()-st >= L4_PAGESIZE-1)
208 if (debug_memory_maps)
209 L4::cout << PROG_NAME": morecore did not find more free memory\n";
213 Region a = Region::bs(l4_round_page(n->end() - L4_PAGESIZE -1), L4_PAGESIZE, sigma0_taskno);
215 Page_alloc_base::free((void*)a.start());
219 if (debug_memory_maps)
220 L4::cout << PROG_NAME": morecore: total=" << Page_alloc_base::total() / 1024
221 << "kB avail=" << Page_alloc_base::allocator()->avail() / 1024
222 << "kB: added " << a << '\n';
227 Mem_man::alloc_first(unsigned long size, unsigned owner)
229 Tree::Item_type *n = 0;
231 for (Tree::Iterator i = _tree.begin(); i != _tree.end(); ++i)
237 if ((i->start() + size - 1) < i->start())
240 l4_addr_t st = (i->start() + size-1) & ~(size-1);
241 //L4::cout << "test: " << (void*)st << " - " << i->end() << '\n';
243 if (st < i->end() && i->end() - st >= size - 1)
253 Region a = Region::bs((n->start() + size-1) & ~(size-1), size, owner);
263 for (Tree::Iterator i = _tree.begin(); i != _tree.end(); ++i)
264 L4::cout << *i << '\n';