1// -*- Mode: C++ -*- 2// vim:ft=cpp 3/** 4 * \file bitmap_cap_alloc 5 * \brief Bitmap capability allocator 6 */ 7/* 8 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>, 9 * Alexander Warg <warg@os.inf.tu-dresden.de> 10 * economic rights: Technische Universität Dresden (Germany) 11 * 12 * This file is part of TUD:OS and distributed under the terms of the 13 * GNU General Public License 2. 14 * Please see the COPYING-GPL-2 file for details. 15 * 16 * As a special exception, you may use this file as part of a free software 17 * library without restriction. Specifically, if other files instantiate 18 * templates or use macros or inline functions from this file, or you compile 19 * this file and link it with other files to produce an executable, this 20 * file does not by itself cause the resulting executable to be covered by 21 * the GNU General Public License. This exception does not however 22 * invalidate any other reasons why the executable file might be covered by 23 * the GNU General Public License. 24 */ 25 26#pragma once 27 28#include <l4/re/util/item_alloc> 29#include <l4/sys/capability> 30#include <l4/sys/task.h> 31 32namespace L4Re { namespace Util { 33 34/** 35 * \brief Capability allocator. 36 * \ingroup api_l4re_util 37 */ 38class Cap_alloc_base 39{ 40private: 41 long _bias; 42 Item_alloc_base _items; 43 44public: 45 enum State { Free = 0, Allocated, Unknown }; 46 Cap_alloc_base(long max, void *mem, long bias = 0) 47 noexcept : _bias(bias), _items(max, mem) {} 48 49 L4::Cap<void> alloc() noexcept 50 { 51 long cap = _items.alloc(); 52 if (cap < 0) 53 return L4::Cap<void>::Invalid; 54 55 return L4::Cap<void>((cap + _bias) << L4_CAP_SHIFT); 56 } 57 58 long hint() const { return _items.hint(); } 59 60 /** 61 * \brief Allocate a capability slot. 62 */ 63 template< typename T > 64 L4::Cap<T> alloc() noexcept 65 { return L4::Cap<T>(alloc().cap()); } 66 67 State is_allocated(L4::Cap<void> c) const noexcept 68 { 69 long idx = (c.cap() >> L4_CAP_SHIFT); 70 71 if (idx < _bias) 72 return Unknown; 73 74 idx -= _bias; 75 return _items.is_allocated(idx) ? Allocated : Free; 76 } 77 78 /** 79 * \brief Free a capability slot. 80 */ 81 template< typename T> 82 void free(L4::Cap<T> const &cap, l4_cap_idx_t task = L4_INVALID_CAP, 83 l4_umword_t unmap_flags = L4_FP_ALL_SPACES) noexcept 84 { 85 long idx = (cap.cap() >> L4_CAP_SHIFT); 86 if (idx < _bias) 87 return; 88 89 idx -= _bias; 90 91 _items.free(idx); 92 93 if (l4_is_valid_cap(task)) 94 l4_task_unmap(task, cap.fpage(), unmap_flags | 2); 95 } 96 97 // since we have no counters assume counter always > 0 98 void take(L4::Cap<void>) noexcept {} 99 bool release(L4::Cap<void>, l4_cap_idx_t task = L4_INVALID_CAP, 100 unsigned unmap_flags = L4_FP_ALL_SPACES) noexcept 101 { (void)task; (void)unmap_flags; return false; } 102 103 long last() noexcept 104 { 105 return _items.size() + _bias - 1; 106 } 107}; 108 109template< long Size > 110class Cap_alloc : public Cap_alloc_base 111{ 112private: 113 typename Bitmap_base::Word<Size>::Type _bits[Bitmap_base::Word<Size>::Size]; 114 115public: 116 explicit Cap_alloc(long bias = 0) noexcept 117 : Cap_alloc_base(Size, _bits, bias) {} 118 119}; 120 121} 122} 123