1// -*- Mode: C++ -*-
2// vim:ft=cpp
3/*!
4 * \file   item_alloc
5 * \brief  Item 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/cxx/bitmap>
29
30namespace L4Re { namespace Util {
31
32using cxx::Bitmap_base;
33using cxx::Bitmap;
34
35/**
36 * \brief Item allocator.
37 */
38class Item_alloc_base
39{
40private:
41  long _capacity;
42  long _free_hint;
43  Bitmap_base _bits;
44
45public:
46  bool is_allocated(long item) const noexcept
47  { return _bits[item]; }
48
49  long hint() const { return _free_hint; }
50
51  bool alloc(long item) noexcept
52  {
53    if (!_bits[item])
54      {
55	_bits.set_bit(item);
56	return true;
57      }
58    return false;
59  }
60
61  void free(long item) noexcept
62  {
63    if (item < _free_hint)
64      _free_hint = item;
65
66    _bits.clear_bit(item);
67  }
68
69  Item_alloc_base(long size, void *mem) noexcept
70    : _capacity(size), _free_hint(0), _bits(mem)
71  {}
72
73  long alloc() noexcept
74  {
75    if (_free_hint >= _capacity)
76      return -1;
77
78    long free = _bits.scan_zero(_capacity, _free_hint);
79    if (free >= 0)
80      {
81	_bits.set_bit(free);
82	_free_hint += 1;
83      }
84    return free;
85  }
86
87  long size() const noexcept
88  {
89    return _capacity;
90  }
91};
92
93template< long Bits >
94class Item_alloc : public Item_alloc_base
95{
96private:
97  typename Bitmap_base::Word<Bits>::Type _bits[Bitmap_base::Word<Bits>::Size];
98
99public:
100  Item_alloc() noexcept : Item_alloc_base(Bits, _bits) {}
101};
102
103}}
104