]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/bootstrap/server/src/region.cc
update
[l4.git] / l4 / pkg / bootstrap / server / src / region.cc
index 0a7cb2496532815a346bb37a1434f8aa4525a609..2ebe2c3daa4647499b9e020d8b73fc8e1a96f62d 100644 (file)
@@ -24,10 +24,9 @@ Region_list::test_fit(unsigned long long start, unsigned long long _size)
   Region r(start, start + _size);
   for (Region const *c = _reg; c < _end; ++c)
     {
-#if 0
-      printf("test [%p-%p] [%llx-%llx]\n", (char*)start, (char*)start + _size,
-             c->begin(), c->end());
-#endif
+      if (0)
+        printf("test [%p-%p] [%llx-%llx]\n",
+               (char *)start, (char *)start + _size, c->begin(), c->end());
 
       if (c->overlaps(r))
        return false;
@@ -35,13 +34,19 @@ Region_list::test_fit(unsigned long long start, unsigned long long _size)
   return true;
 }
 
-unsigned long
+unsigned long long
 Region_list::next_free(unsigned long long start)
 {
-  unsigned long long s = ~0ULL;
+  unsigned long long s = ~0ULL, e = ~0ULL;
   for (Region const *c = _reg; c < _end; ++c)
-    if (c->end() > start && c->end() < s)
-      s = c->end();
+    {
+      e = c->end();
+      if (e > start && e < s)
+        s = e;
+    }
+
+  if (s == ~0ULL)
+    return e;
 
   return s;
 }
@@ -59,14 +64,13 @@ Region_list::find_free(Region const &search, unsigned long long _size,
       if (start + _size - 1 > end)
        return 0;
 
-      //printf("try start %p\n", (void*)start);
+      if (0)
+        printf("try start %p\n", (void *)start);
+
       if (test_fit(start, _size))
        return start;
 
       start = next_free(start);
-
-      if (start == ~0UL)
-       return 0;
     }
 }
 
@@ -82,7 +86,10 @@ Region_list::add_nolimitcheck(Region const &region, bool may_overlap)
   if (_end >= _max)
     panic("Bootstrap: %s: Region overflow\n", __func__);
 
-  if (!may_overlap && (r = find(region)))
+  if (!may_overlap && (r = find(region))
+      // sometimes there are smaller regions in regions of the same type
+      && !(   r->contains(region)
+           && region.type() == r->type()))
     {
       printf("  New region for list %s:\t", _name);
       region.vprint();
@@ -95,6 +102,7 @@ Region_list::add_nolimitcheck(Region const &region, bool may_overlap)
 
   *_end = region;
   ++_end;
+  _combined_size += region.size();
 }
 
 void
@@ -108,22 +116,41 @@ Region_list::add(Region const &region, bool may_overlap)
       return;
     }
 
-  if (mem.begin() >= _upper_limit)
+  if (mem.begin() > _address_limit)
+    {
+      printf("  Dropping '%s' region ", _name);
+      mem.print();
+      printf(" due to %lld MB address limit\n", _address_limit >> 20);
+      return;
+    }
+
+  if (mem.end() >= _address_limit)
+    {
+      printf("  Limiting '%s' region ", _name);
+      mem.print();
+      mem.end(_address_limit - 1);
+      printf(" to ");
+      mem.print();
+      printf(" due to %lld MB address limit\n", _address_limit >> 20);
+
+    }
+
+  if (_combined_size >= _max_combined_size)
     {
-      printf("  Dropping %s region ", _name);
+      printf("  Dropping '%s' region ", _name);
       mem.print();
-      printf(" due to %lld MB limit\n", _upper_limit >> 20);
+      printf(" due to %lld MB size limit\n", _max_combined_size >> 20);
       return;
     }
 
-  if (mem.end() >= _upper_limit - 1)
+  if (_combined_size + mem.size() > _max_combined_size)
     {
-      printf("  Limiting %s region ", _name);
+      printf("  Limiting '%s' region ", _name);
       mem.print();
-      mem.end(_upper_limit - 1);
+      mem.end(mem.begin() + _max_combined_size - _combined_size - 1);
       printf(" to ");
       mem.print();
-      printf(" due to %lld MB limit\n", _upper_limit >> 20);
+      printf(" due to %lld MB size limit\n", _max_combined_size >> 20);
     }
 
   add_nolimitcheck(mem, may_overlap);
@@ -152,7 +179,7 @@ Region_list::contains(Region const &o)
 void
 Region::print() const
 {
-  printf("  [%9llx, %9llx]", begin(), end());
+  printf("  [%9llx, %9llx] {%9llx}", begin(), end(), size());
 }
 
 void
@@ -181,7 +208,7 @@ Region_list::dump()
   Region const *min_idx;
   unsigned long long min, mark = 0;
 
-  printf("Regions of list %s\n", _name);
+  printf("Regions of list '%s'\n", _name);
   for (i = _reg; i < _end; ++i)
     {
       min = ~0;