From ff29f85cc9ec02ee25d21afb440a122343063c0a Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Tue, 27 Aug 2013 11:14:49 +0200 Subject: [PATCH] nova: speed up cap selector allocation Issue #485 --- base-nova/include/base/bit_allocator.h | 39 +++++++++++++++---------- base-nova/src/base/env/cap_sel_alloc.cc | 2 +- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/base-nova/include/base/bit_allocator.h b/base-nova/include/base/bit_allocator.h index fc787c190..71e62b1ff 100644 --- a/base-nova/include/base/bit_allocator.h +++ b/base-nova/include/base/bit_allocator.h @@ -23,6 +23,7 @@ namespace Genode { { protected: + addr_t _next; Bit_array _array; void _reserve(addr_t bit_start, size_t const num_cap) @@ -34,32 +35,40 @@ namespace Genode { public: + Bit_allocator() : _next(0) { } + addr_t alloc(size_t const num_log2) { addr_t const step = 1UL << num_log2; - addr_t i = 0; + addr_t max = ~0UL; - try { - /* - * Throws exception if array is * accessed outside bounds - */ - while (true) { - if (_array.get(i, step)) { - i += step; - continue; + do + { + try + { + /* throws exception if array is accessed outside bounds */ + for (addr_t i = _next & ~(step - 1); i < max; i += step) { + if (_array.get(i, step)) + continue; + + _array.set(i, step); + _next = i + step; + return i; } - _array.set(i, step); - return i; - } - } catch (Bit_array_invalid_index_access) {} + } catch (Bit_array_invalid_index_access) { } + + max = _next; + _next = 0; + + } while (max != 0); throw Bit_array_out_of_indexes(); } - void free(addr_t const bit_start, - size_t const num_log2) + void free(addr_t const bit_start, size_t const num_log2) { _array.clear(bit_start, 1UL << num_log2); + _next = bit_start; } }; diff --git a/base-nova/src/base/env/cap_sel_alloc.cc b/base-nova/src/base/env/cap_sel_alloc.cc index 31905774b..bf496d8cf 100644 --- a/base-nova/src/base/env/cap_sel_alloc.cc +++ b/base-nova/src/base/env/cap_sel_alloc.cc @@ -48,7 +48,7 @@ void Cap_selector_allocator::free(addr_t cap, size_t num_caps_log2) } -Cap_selector_allocator::Cap_selector_allocator() +Cap_selector_allocator::Cap_selector_allocator() : Bit_allocator() { /* initialize lock */ alloc_lock();