paul@65 | 1 | #include "pipe_paging.h" |
paul@65 | 2 | |
paul@70 | 3 | PipePaging::PipePaging(Memory *memory, offset_t size) |
paul@70 | 4 | : _memory(NULL), _size(size) |
paul@70 | 5 | { |
paul@70 | 6 | _pages = new PagesConserving(memory); |
paul@70 | 7 | } |
paul@70 | 8 | |
paul@66 | 9 | PipePaging::PipePaging(offset_t size) |
paul@66 | 10 | : _size(size) |
paul@65 | 11 | { |
paul@70 | 12 | _memory = new Memory(); |
paul@70 | 13 | _pages = new PagesConserving(_memory); |
paul@65 | 14 | } |
paul@65 | 15 | |
paul@67 | 16 | /* Detach one endpoint. */ |
paul@67 | 17 | |
paul@67 | 18 | void PipePaging::detach() |
paul@67 | 19 | { |
paul@67 | 20 | if (!_endpoints) |
paul@67 | 21 | return; |
paul@67 | 22 | else |
paul@67 | 23 | _endpoints--; |
paul@67 | 24 | |
paul@69 | 25 | /* Return if the other endpoint is attached. */ |
paul@69 | 26 | |
paul@67 | 27 | if (_endpoints) |
paul@67 | 28 | return; |
paul@67 | 29 | |
paul@67 | 30 | /* Discard all regions from the pipe. */ |
paul@67 | 31 | |
paul@67 | 32 | while (!_regions.empty()) |
paul@67 | 33 | { |
paul@67 | 34 | PageMapper *mapper = _regions.front(); |
paul@67 | 35 | |
paul@67 | 36 | _regions.pop_front(); |
paul@67 | 37 | mapper->detach(); |
paul@67 | 38 | delete mapper; |
paul@67 | 39 | } |
paul@70 | 40 | |
paul@70 | 41 | /* Delete the page collection and memory object. */ |
paul@70 | 42 | |
paul@70 | 43 | delete _pages; |
paul@70 | 44 | |
paul@70 | 45 | if (_memory != NULL) |
paul@70 | 46 | delete _memory; |
paul@67 | 47 | } |
paul@67 | 48 | |
paul@65 | 49 | /* Add a region to the sequence. */ |
paul@65 | 50 | |
paul@65 | 51 | void PipePaging::add_region(PageMapper *mapper) |
paul@65 | 52 | { |
paul@65 | 53 | _regions.push_back(mapper); |
paul@65 | 54 | } |
paul@65 | 55 | |
paul@65 | 56 | /* Return the first region in the sequence. */ |
paul@65 | 57 | |
paul@65 | 58 | PageMapper *PipePaging::first_region() |
paul@65 | 59 | { |
paul@65 | 60 | return _regions.front(); |
paul@65 | 61 | } |
paul@65 | 62 | |
paul@65 | 63 | /* Return the next region for the reader. If only a single region remains, with |
paul@65 | 64 | the reader wishing to move to the next, return NULL. */ |
paul@65 | 65 | |
paul@65 | 66 | PageMapper *PipePaging::next_region() |
paul@65 | 67 | { |
paul@65 | 68 | if (_regions.size() > 1) |
paul@65 | 69 | { |
paul@66 | 70 | /* Discard the accessor from the current region. */ |
paul@66 | 71 | |
paul@66 | 72 | if (_accessors.size() > _regions.size()) |
paul@66 | 73 | _accessors.pop_front(); |
paul@66 | 74 | |
paul@67 | 75 | /* Detach and discard the current page mapper. */ |
paul@67 | 76 | |
paul@67 | 77 | PageMapper *mapper = _regions.front(); |
paul@67 | 78 | |
paul@65 | 79 | _regions.pop_front(); |
paul@67 | 80 | mapper->detach(); |
paul@67 | 81 | delete mapper; |
paul@67 | 82 | |
paul@67 | 83 | /* Return the next region. */ |
paul@67 | 84 | |
paul@65 | 85 | return _regions.front(); |
paul@65 | 86 | } |
paul@65 | 87 | else |
paul@65 | 88 | return NULL; |
paul@65 | 89 | } |
paul@65 | 90 | |
paul@66 | 91 | /* Initialise an accessor for a region. */ |
paul@66 | 92 | |
paul@66 | 93 | PipeAccessor *PipePaging::accessor() |
paul@66 | 94 | { |
paul@66 | 95 | PipeAccessor accessor; |
paul@66 | 96 | |
paul@66 | 97 | _accessors.push_back(accessor); |
paul@66 | 98 | return &_accessors.back(); |
paul@66 | 99 | } |
paul@66 | 100 | |
paul@65 | 101 | // vim: tabstop=4 expandtab shiftwidth=4 |