# HG changeset patch # User Paul Boddie # Date 1616966172 -7200 # Node ID bbf49114dd8a167f163e35a747bbfcdd4585df33 # Parent e8c7a27d0810eabac20264c9379ff2f0dc3cdfb4 Moved page collections and queues into their own subdirectory. diff -r e8c7a27d0810 -r bbf49114dd8a Makefile --- a/Makefile Sun Mar 28 22:41:12 2021 +0200 +++ b/Makefile Sun Mar 28 23:16:12 2021 +0200 @@ -56,9 +56,9 @@ flexpage.cc ipc.cc \ memory/memory_incremental.cc memory/memory_preallocated.cc \ opener_resource.cc opener_context_resource.cc \ - page_mapper.cc \ - page_queue.cc page_queue_partitioned.cc page_queue_shared.cc \ - pager.cc paging.cc pages.cc \ + page_mapper.cc pager.cc paging.cc \ + pages/page_queue.cc pages/page_queue_partitioned.cc pages/page_queue_shared.cc \ + pages/pages.cc \ region.cc resource_server.cc simple_pager.cc PLAIN_SRC_CC_dstest_block_server = \ @@ -130,7 +130,8 @@ REQUIRES_LIBS = l4re_c-util libipc libstdc++ libsystypes -PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(PKGDIR)/memory $(PKGDIR)/pipes \ +PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(PKGDIR)/memory \ + $(PKGDIR)/pages $(PKGDIR)/pipes \ $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR) include $(L4DIR)/mk/prog.mk diff -r e8c7a27d0810 -r bbf49114dd8a page_queue.cc --- a/page_queue.cc Sun Mar 28 22:41:12 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -#include "page_queue.h" - - - -void PageQueue::discard(Queue &queue, Memory *memory) -{ - while (!queue.empty()) - { - Flexpage *flexpage = queue.front().flexpage; - - queue.pop_front(); - memory->release(flexpage->region); - delete flexpage; - } -} - -bool PageQueue::remove(Queue &queue, Positions &positions, PageOwner *owner, Flexpage *flexpage) -{ - Positions::iterator position = positions.find(flexpage); - - if (position == positions.end()) - return false; - - /* The found owner may be different from the requesting owner or even NULL - if another owner has acquired and then purged its pages. Such a purged - flexpage is not immediately usable, however. */ - - Queue::iterator entry = position->second; - - if ((entry->owner == NULL) || (entry->owner != owner)) - return false; - - queue.erase(entry); - positions.erase(position); - - return true; -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a page_queue.h --- a/page_queue.h Sun Mar 28 22:41:12 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -#pragma once - -#include -#include - -#include "flexpage.h" -#include "memory.h" -#include "page_owner.h" - - - -/* Collection types. */ - -typedef struct { Flexpage *flexpage; PageOwner *owner; } QueueEntry; -typedef std::list Queue; - -typedef std::pair Position; -typedef std::map Positions; - - - -/* A queue of managed pages. */ - -class PageQueue -{ -protected: - - /* Helper methods. */ - - virtual void discard(Queue &queue, Memory *memory); - - virtual bool remove(Queue &queue, Positions &positions, PageOwner *owner, Flexpage *flexpage); - -public: - virtual ~PageQueue() - { - } - - virtual void close(Memory *memory) = 0; - - virtual void pop(PageOwner **owner, Flexpage **flexpage) = 0; - - virtual void push(PageOwner *owner, Flexpage *flexpage) = 0; - - virtual void push_front(PageOwner *owner, Flexpage *flexpage) = 0; - - virtual bool remove(PageOwner *owner, Flexpage *flexpage) = 0; -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a page_queue_partitioned.cc --- a/page_queue_partitioned.cc Sun Mar 28 22:41:12 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -#include "page_queue_partitioned.h" - - - -/* Discard all queued flexpages. */ - -void PageQueuePartitioned::close(Memory *memory) -{ - discard(_available, memory); - discard(_issued, memory); -} - -/* Keep waiting for a potential queue non-empty condition. - Then, attempt to pop an entry from the queue. */ - -void PageQueuePartitioned::pop(PageOwner **owner, Flexpage **flexpage) -{ - std::unique_lock guard(_lock); - QueueEntry entry; - - while (1) - { - if (_pop(&entry)) - { - *owner = entry.owner; - *flexpage = entry.flexpage; - return; - } - else - _counter.wait(guard); - } -} - -/* Check the available pages queue for entries, returning false if no entries - are available, returning true and providing the details if an entry can be - removed from the front of the queue. */ - -bool PageQueuePartitioned::_pop(QueueEntry *entry) -{ - if (_available.empty()) - return false; - - *entry = _available.front(); - _available.pop_front(); - - return true; -} - -/* Push an entry for the given owner and flexpage to the appropriate queue. */ - -void PageQueuePartitioned::push(PageOwner *owner, Flexpage *flexpage) -{ - std::lock_guard guard(_lock); - - /* Record the entry and a position reference for the flexpage. */ - - Queue *queue; - Positions *positions = NULL; - - if (owner == NULL) - queue = &_available; - else - { - queue = &_issued; - positions = &_positions; - } - - queue->push_back((QueueEntry) {flexpage, owner}); - - if (positions != NULL) - { - Queue::iterator last = queue->end(); - last--; - positions->insert(Position(flexpage, last)); - } - - _counter.notify_one(); -} - -/* Push an entry to the front of the appropriate queue. */ - -void PageQueuePartitioned::push_front(PageOwner *owner, Flexpage *flexpage) -{ - std::lock_guard guard(_lock); - - Queue *queue; - Positions *positions = NULL; - - if (owner == NULL) - queue = &_available; - else - { - queue = &_issued; - positions = &_positions; - } - - queue->push_back((QueueEntry) {flexpage, owner}); - - if (positions != NULL) - positions->insert(Position(flexpage, queue->begin())); - - _counter.notify_one(); -} - -/* Remove an entry for the given owner and flexpage from the queue. */ - -bool PageQueuePartitioned::remove(PageOwner *owner, Flexpage *flexpage) -{ - return PageQueue::remove(_issued, _positions, owner, flexpage); -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a page_queue_partitioned.h --- a/page_queue_partitioned.h Sun Mar 28 22:41:12 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -#pragma once - -#include -#include - -#include "page_queue.h" - - - -/* Queues of issued and available pages. */ - -class PageQueuePartitioned : public PageQueue -{ -protected: - Queue _issued, _available; - Positions _positions; - - std::mutex _lock; - std::condition_variable _counter; - - virtual bool _pop(QueueEntry *entry); - -public: - virtual void close(Memory *memory); - - virtual void pop(PageOwner **owner, Flexpage **flexpage); - - virtual void push(PageOwner *owner, Flexpage *flexpage); - - virtual void push_front(PageOwner *owner, Flexpage *flexpage); - - virtual bool remove(PageOwner *owner, Flexpage *flexpage); -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a page_queue_shared.cc --- a/page_queue_shared.cc Sun Mar 28 22:41:12 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -#include "page_queue_shared.h" - - - -/* Discard all queued flexpages. */ - -void PageQueueShared::close(Memory *memory) -{ - discard(_queue, memory); -} - -/* Keep waiting for a potential queue non-empty condition. - Then, attempt to pop an entry from the queue. */ - -void PageQueueShared::pop(PageOwner **owner, Flexpage **flexpage) -{ - std::unique_lock guard(_lock); - QueueEntry entry; - - while (1) - { - if (_pop(&entry)) - { - *owner = entry.owner; - *flexpage = entry.flexpage; - return; - } - else - _counter.wait(guard); - } -} - -/* Check the queue for entries, returning false if no entries are available, - returning true and providing the details if an entry can be removed from the - front of the queue. */ - -bool PageQueueShared::_pop(QueueEntry *entry) -{ - if (_queue.empty()) - return false; - - *entry = _queue.front(); - _queue.pop_front(); - - /* Remove any position reference for the flexpage. */ - - Positions::iterator position = _positions.find(entry->flexpage); - - if (position != _positions.end()) - _positions.erase(position); - - return true; -} - -/* Push an entry for the given owner and flexpage to the queue. */ - -void PageQueueShared::push(PageOwner *owner, Flexpage *flexpage) -{ - std::lock_guard guard(_lock); - - /* Record the entry and a position reference for the flexpage. */ - - _queue.push_back((QueueEntry) {flexpage, owner}); - - Queue::iterator last = _queue.end(); - last--; - _positions.insert(Position(flexpage, last)); - - _counter.notify_one(); -} - -/* Push an entry to the front of the queue. */ - -void PageQueueShared::push_front(PageOwner *owner, Flexpage *flexpage) -{ - std::lock_guard guard(_lock); - - _queue.push_back((QueueEntry) {flexpage, owner}); - _positions.insert(Position(flexpage, _queue.begin())); - - _counter.notify_one(); -} - -/* Remove an entry for the given owner and flexpage from the queue. */ - -bool PageQueueShared::remove(PageOwner *owner, Flexpage *flexpage) -{ - return PageQueue::remove(_queue, _positions, owner, flexpage); -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a page_queue_shared.h --- a/page_queue_shared.h Sun Mar 28 22:41:12 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -#pragma once - -#include -#include - -#include "page_queue.h" - - - -/* A queue of issued pages. */ - -class PageQueueShared : public PageQueue -{ -protected: - Queue _queue; - Positions _positions; - - std::mutex _lock; - std::condition_variable _counter; - - virtual bool _pop(QueueEntry *entry); - -public: - virtual void close(Memory *memory); - - virtual void pop(PageOwner **owner, Flexpage **flexpage); - - virtual void push(PageOwner *owner, Flexpage *flexpage); - - virtual void push_front(PageOwner *owner, Flexpage *flexpage); - - virtual bool remove(PageOwner *owner, Flexpage *flexpage); -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages.cc --- a/pages.cc Sun Mar 28 22:41:12 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -#include "memory_incremental.h" -#include "pages.h" - - - -Pages::Pages(Memory *memory, PageQueue *queue) -: _memory(memory), _queue(queue) -{ -} - -Pages::Pages(PageQueue *queue) -: _queue(queue) -{ - _memory = new MemoryIncremental(); -} - -Pages::~Pages() -{ - _queue->close(_memory); -} - -/* Remove the first flexpage in the queue. If its owner exists, remove it from - the owner (retiring the content). Return the flexpage for reuse. */ - -Flexpage *Pages::remove() -{ - PageOwner *owner; - Flexpage *flexpage; - - _queue->pop(&owner, &flexpage); - - if (owner != NULL) - owner->remove(flexpage); - - return flexpage; -} - -/* Reserve 'flexpage' by removing it from this collection. */ - -bool Pages::reserve(PageOwner *owner, Flexpage *flexpage) -{ - return _queue->remove(owner, flexpage); -} - -/* Obtain a new flexpage. Return the flexpage or None if no new flexpage could - be created. */ - -Flexpage *Pages::flexpage() -{ - Region *region = _memory->region(); - - if (region != NULL) - return new Flexpage(region); - else - return NULL; -} - -/* Queue an entry associating the given 'owner' and 'flexpage'. */ - -void Pages::queue(PageOwner *owner, Flexpage *flexpage) -{ - _queue->push(owner, flexpage); -} - -/* Push an entry for 'flexpage' without owner association for immediate - reuse. */ - -void Pages::release(Flexpage *flexpage) -{ - _queue->push_front(NULL, flexpage); -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages.h --- a/pages.h Sun Mar 28 22:41:12 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -#pragma once - -#include "flexpage.h" -#include "memory.h" -#include "page_owner.h" -#include "page_queue.h" - - - -/* A page collection. */ - -class Pages -{ -protected: - Memory *_memory; - PageQueue *_queue; - -public: - explicit Pages(Memory *memory, PageQueue *queue); - - explicit Pages(PageQueue *queue); - - virtual ~Pages(); - - virtual Flexpage *remove(); - - virtual bool reserve(PageOwner *owner, Flexpage *flexpage); - - virtual Flexpage *flexpage(); - - virtual void queue(PageOwner *owner, Flexpage *flexpage); - - virtual void release(Flexpage *flexpage); -}; - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages/page_queue.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/page_queue.cc Sun Mar 28 23:16:12 2021 +0200 @@ -0,0 +1,39 @@ +#include "page_queue.h" + + + +void PageQueue::discard(Queue &queue, Memory *memory) +{ + while (!queue.empty()) + { + Flexpage *flexpage = queue.front().flexpage; + + queue.pop_front(); + memory->release(flexpage->region); + delete flexpage; + } +} + +bool PageQueue::remove(Queue &queue, Positions &positions, PageOwner *owner, Flexpage *flexpage) +{ + Positions::iterator position = positions.find(flexpage); + + if (position == positions.end()) + return false; + + /* The found owner may be different from the requesting owner or even NULL + if another owner has acquired and then purged its pages. Such a purged + flexpage is not immediately usable, however. */ + + Queue::iterator entry = position->second; + + if ((entry->owner == NULL) || (entry->owner != owner)) + return false; + + queue.erase(entry); + positions.erase(position); + + return true; +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages/page_queue.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/page_queue.h Sun Mar 28 23:16:12 2021 +0200 @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +#include "flexpage.h" +#include "memory.h" +#include "page_owner.h" + + + +/* Collection types. */ + +typedef struct { Flexpage *flexpage; PageOwner *owner; } QueueEntry; +typedef std::list Queue; + +typedef std::pair Position; +typedef std::map Positions; + + + +/* A queue of managed pages. */ + +class PageQueue +{ +protected: + + /* Helper methods. */ + + virtual void discard(Queue &queue, Memory *memory); + + virtual bool remove(Queue &queue, Positions &positions, PageOwner *owner, Flexpage *flexpage); + +public: + virtual ~PageQueue() + { + } + + virtual void close(Memory *memory) = 0; + + virtual void pop(PageOwner **owner, Flexpage **flexpage) = 0; + + virtual void push(PageOwner *owner, Flexpage *flexpage) = 0; + + virtual void push_front(PageOwner *owner, Flexpage *flexpage) = 0; + + virtual bool remove(PageOwner *owner, Flexpage *flexpage) = 0; +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages/page_queue_partitioned.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/page_queue_partitioned.cc Sun Mar 28 23:16:12 2021 +0200 @@ -0,0 +1,112 @@ +#include "page_queue_partitioned.h" + + + +/* Discard all queued flexpages. */ + +void PageQueuePartitioned::close(Memory *memory) +{ + discard(_available, memory); + discard(_issued, memory); +} + +/* Keep waiting for a potential queue non-empty condition. + Then, attempt to pop an entry from the queue. */ + +void PageQueuePartitioned::pop(PageOwner **owner, Flexpage **flexpage) +{ + std::unique_lock guard(_lock); + QueueEntry entry; + + while (1) + { + if (_pop(&entry)) + { + *owner = entry.owner; + *flexpage = entry.flexpage; + return; + } + else + _counter.wait(guard); + } +} + +/* Check the available pages queue for entries, returning false if no entries + are available, returning true and providing the details if an entry can be + removed from the front of the queue. */ + +bool PageQueuePartitioned::_pop(QueueEntry *entry) +{ + if (_available.empty()) + return false; + + *entry = _available.front(); + _available.pop_front(); + + return true; +} + +/* Push an entry for the given owner and flexpage to the appropriate queue. */ + +void PageQueuePartitioned::push(PageOwner *owner, Flexpage *flexpage) +{ + std::lock_guard guard(_lock); + + /* Record the entry and a position reference for the flexpage. */ + + Queue *queue; + Positions *positions = NULL; + + if (owner == NULL) + queue = &_available; + else + { + queue = &_issued; + positions = &_positions; + } + + queue->push_back((QueueEntry) {flexpage, owner}); + + if (positions != NULL) + { + Queue::iterator last = queue->end(); + last--; + positions->insert(Position(flexpage, last)); + } + + _counter.notify_one(); +} + +/* Push an entry to the front of the appropriate queue. */ + +void PageQueuePartitioned::push_front(PageOwner *owner, Flexpage *flexpage) +{ + std::lock_guard guard(_lock); + + Queue *queue; + Positions *positions = NULL; + + if (owner == NULL) + queue = &_available; + else + { + queue = &_issued; + positions = &_positions; + } + + queue->push_back((QueueEntry) {flexpage, owner}); + + if (positions != NULL) + positions->insert(Position(flexpage, queue->begin())); + + _counter.notify_one(); +} + +/* Remove an entry for the given owner and flexpage from the queue. */ + +bool PageQueuePartitioned::remove(PageOwner *owner, Flexpage *flexpage) +{ + return PageQueue::remove(_issued, _positions, owner, flexpage); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages/page_queue_partitioned.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/page_queue_partitioned.h Sun Mar 28 23:16:12 2021 +0200 @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include "page_queue.h" + + + +/* Queues of issued and available pages. */ + +class PageQueuePartitioned : public PageQueue +{ +protected: + Queue _issued, _available; + Positions _positions; + + std::mutex _lock; + std::condition_variable _counter; + + virtual bool _pop(QueueEntry *entry); + +public: + virtual void close(Memory *memory); + + virtual void pop(PageOwner **owner, Flexpage **flexpage); + + virtual void push(PageOwner *owner, Flexpage *flexpage); + + virtual void push_front(PageOwner *owner, Flexpage *flexpage); + + virtual bool remove(PageOwner *owner, Flexpage *flexpage); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages/page_queue_shared.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/page_queue_shared.cc Sun Mar 28 23:16:12 2021 +0200 @@ -0,0 +1,91 @@ +#include "page_queue_shared.h" + + + +/* Discard all queued flexpages. */ + +void PageQueueShared::close(Memory *memory) +{ + discard(_queue, memory); +} + +/* Keep waiting for a potential queue non-empty condition. + Then, attempt to pop an entry from the queue. */ + +void PageQueueShared::pop(PageOwner **owner, Flexpage **flexpage) +{ + std::unique_lock guard(_lock); + QueueEntry entry; + + while (1) + { + if (_pop(&entry)) + { + *owner = entry.owner; + *flexpage = entry.flexpage; + return; + } + else + _counter.wait(guard); + } +} + +/* Check the queue for entries, returning false if no entries are available, + returning true and providing the details if an entry can be removed from the + front of the queue. */ + +bool PageQueueShared::_pop(QueueEntry *entry) +{ + if (_queue.empty()) + return false; + + *entry = _queue.front(); + _queue.pop_front(); + + /* Remove any position reference for the flexpage. */ + + Positions::iterator position = _positions.find(entry->flexpage); + + if (position != _positions.end()) + _positions.erase(position); + + return true; +} + +/* Push an entry for the given owner and flexpage to the queue. */ + +void PageQueueShared::push(PageOwner *owner, Flexpage *flexpage) +{ + std::lock_guard guard(_lock); + + /* Record the entry and a position reference for the flexpage. */ + + _queue.push_back((QueueEntry) {flexpage, owner}); + + Queue::iterator last = _queue.end(); + last--; + _positions.insert(Position(flexpage, last)); + + _counter.notify_one(); +} + +/* Push an entry to the front of the queue. */ + +void PageQueueShared::push_front(PageOwner *owner, Flexpage *flexpage) +{ + std::lock_guard guard(_lock); + + _queue.push_back((QueueEntry) {flexpage, owner}); + _positions.insert(Position(flexpage, _queue.begin())); + + _counter.notify_one(); +} + +/* Remove an entry for the given owner and flexpage from the queue. */ + +bool PageQueueShared::remove(PageOwner *owner, Flexpage *flexpage) +{ + return PageQueue::remove(_queue, _positions, owner, flexpage); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages/page_queue_shared.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/page_queue_shared.h Sun Mar 28 23:16:12 2021 +0200 @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include "page_queue.h" + + + +/* A queue of issued pages. */ + +class PageQueueShared : public PageQueue +{ +protected: + Queue _queue; + Positions _positions; + + std::mutex _lock; + std::condition_variable _counter; + + virtual bool _pop(QueueEntry *entry); + +public: + virtual void close(Memory *memory); + + virtual void pop(PageOwner **owner, Flexpage **flexpage); + + virtual void push(PageOwner *owner, Flexpage *flexpage); + + virtual void push_front(PageOwner *owner, Flexpage *flexpage); + + virtual bool remove(PageOwner *owner, Flexpage *flexpage); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages/pages.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/pages.cc Sun Mar 28 23:16:12 2021 +0200 @@ -0,0 +1,73 @@ +#include "memory_incremental.h" +#include "pages.h" + + + +Pages::Pages(Memory *memory, PageQueue *queue) +: _memory(memory), _queue(queue) +{ +} + +Pages::Pages(PageQueue *queue) +: _queue(queue) +{ + _memory = new MemoryIncremental(); +} + +Pages::~Pages() +{ + _queue->close(_memory); +} + +/* Remove the first flexpage in the queue. If its owner exists, remove it from + the owner (retiring the content). Return the flexpage for reuse. */ + +Flexpage *Pages::remove() +{ + PageOwner *owner; + Flexpage *flexpage; + + _queue->pop(&owner, &flexpage); + + if (owner != NULL) + owner->remove(flexpage); + + return flexpage; +} + +/* Reserve 'flexpage' by removing it from this collection. */ + +bool Pages::reserve(PageOwner *owner, Flexpage *flexpage) +{ + return _queue->remove(owner, flexpage); +} + +/* Obtain a new flexpage. Return the flexpage or None if no new flexpage could + be created. */ + +Flexpage *Pages::flexpage() +{ + Region *region = _memory->region(); + + if (region != NULL) + return new Flexpage(region); + else + return NULL; +} + +/* Queue an entry associating the given 'owner' and 'flexpage'. */ + +void Pages::queue(PageOwner *owner, Flexpage *flexpage) +{ + _queue->push(owner, flexpage); +} + +/* Push an entry for 'flexpage' without owner association for immediate + reuse. */ + +void Pages::release(Flexpage *flexpage) +{ + _queue->push_front(NULL, flexpage); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r e8c7a27d0810 -r bbf49114dd8a pages/pages.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pages/pages.h Sun Mar 28 23:16:12 2021 +0200 @@ -0,0 +1,36 @@ +#pragma once + +#include "flexpage.h" +#include "memory.h" +#include "page_owner.h" +#include "page_queue.h" + + + +/* A page collection. */ + +class Pages +{ +protected: + Memory *_memory; + PageQueue *_queue; + +public: + explicit Pages(Memory *memory, PageQueue *queue); + + explicit Pages(PageQueue *queue); + + virtual ~Pages(); + + virtual Flexpage *remove(); + + virtual bool reserve(PageOwner *owner, Flexpage *flexpage); + + virtual Flexpage *flexpage(); + + virtual void queue(PageOwner *owner, Flexpage *flexpage); + + virtual void release(Flexpage *flexpage); +}; + +// vim: tabstop=4 expandtab shiftwidth=4