L4Re/departure

Annotated libmem/lib/src/memory_preallocated.cc

300:3b8dd301c9c4
2022-03-22 Paul Boddie Raise an exception when failing to allocate memory for a pipe, catching the exception and returning the appropriate error code for the pipe-opening operation.
paul@93 1
/*
paul@93 2
 * A memory pool providing regions from a preallocated amount of memory.
paul@93 3
 *
paul@93 4
 * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>
paul@93 5
 *
paul@93 6
 * This program is free software; you can redistribute it and/or
paul@93 7
 * modify it under the terms of the GNU General Public License as
paul@93 8
 * published by the Free Software Foundation; either version 2 of
paul@93 9
 * the License, or (at your option) any later version.
paul@93 10
 *
paul@93 11
 * This program is distributed in the hope that it will be useful,
paul@93 12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
paul@93 13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
paul@93 14
 * GNU General Public License for more details.
paul@93 15
 *
paul@93 16
 * You should have received a copy of the GNU General Public License
paul@93 17
 * along with this program; if not, write to the Free Software
paul@93 18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
paul@93 19
 * Boston, MA  02110-1301, USA
paul@93 20
 */
paul@93 21
paul@72 22
#include "memory_preallocated.h"
paul@72 23
paul@300 24
#include <l4/cxx/exceptions>
paul@300 25
paul@72 26
paul@72 27
paul@72 28
/* Initialise the memory pool with the given amount in bytes. */
paul@72 29
paul@72 30
MemoryPreallocated::MemoryPreallocated(Memory *memory, offset_t amount)
paul@72 31
: _memory(memory), _amount(amount)
paul@72 32
{
paul@72 33
    offset_t remaining = amount;
paul@72 34
paul@72 35
    while (remaining)
paul@72 36
    {
paul@300 37
        Region *region = memory->region();
paul@72 38
paul@300 39
        if (region == NULL)
paul@300 40
            throw L4::Out_of_memory();
paul@300 41
paul@300 42
        _regions.push_back(region);
paul@72 43
paul@72 44
        remaining -= memory->region_size();
paul@72 45
    }
paul@72 46
}
paul@72 47
paul@73 48
/* Discard all unused regions. */
paul@73 49
paul@73 50
MemoryPreallocated::~MemoryPreallocated()
paul@73 51
{
paul@73 52
    while (!_regions.empty())
paul@73 53
    {
paul@73 54
        Region *region = _regions.front();
paul@73 55
paul@73 56
        _regions.pop_front();
paul@73 57
        _memory->release(region);
paul@73 58
    }
paul@73 59
}
paul@73 60
paul@72 61
/* Obtain an allocated region. */
paul@72 62
paul@72 63
Region *MemoryPreallocated::region()
paul@72 64
{
paul@72 65
    std::lock_guard<std::mutex> guard(_lock);
paul@72 66
paul@107 67
    if (_regions.empty())
paul@107 68
        return NULL;
paul@107 69
paul@72 70
    Region *region = _regions.front();
paul@72 71
paul@72 72
    _regions.pop_front();
paul@72 73
    return region;
paul@72 74
}
paul@72 75
paul@72 76
/* Release the allocated 'region'. */
paul@72 77
paul@72 78
void MemoryPreallocated::release(Region *region)
paul@72 79
{
paul@72 80
    std::lock_guard<std::mutex> guard(_lock);
paul@72 81
paul@72 82
    _regions.push_back(region);
paul@72 83
}
paul@72 84
paul@72 85
// vim: tabstop=4 expandtab shiftwidth=4