# HG changeset patch # User Paul Boddie # Date 1616964072 -7200 # Node ID e8c7a27d0810eabac20264c9379ff2f0dc3cdfb4 # Parent e7a9e8c6995f4a51c7b18d88100ed18cada009af Fixed the remove operation in the partitioned queue: flexpages will be added again when queued and their removal is necessary to prevent duplication. Added support for closing page queues and releasing their pages. diff -r e7a9e8c6995f -r e8c7a27d0810 Makefile --- a/Makefile Sun Mar 28 22:38:45 2021 +0200 +++ b/Makefile Sun Mar 28 22:41:12 2021 +0200 @@ -57,7 +57,7 @@ memory/memory_incremental.cc memory/memory_preallocated.cc \ opener_resource.cc opener_context_resource.cc \ page_mapper.cc \ - page_queue_partitioned.cc page_queue_shared.cc \ + page_queue.cc page_queue_partitioned.cc page_queue_shared.cc \ pager.cc paging.cc pages.cc \ region.cc resource_server.cc simple_pager.cc diff -r e7a9e8c6995f -r e8c7a27d0810 page_queue.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/page_queue.cc Sun Mar 28 22:41: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 e7a9e8c6995f -r e8c7a27d0810 page_queue.h --- a/page_queue.h Sun Mar 28 22:38:45 2021 +0200 +++ b/page_queue.h Sun Mar 28 22:41:12 2021 +0200 @@ -4,6 +4,7 @@ #include #include "flexpage.h" +#include "memory.h" #include "page_owner.h" @@ -22,11 +23,21 @@ 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; diff -r e7a9e8c6995f -r e8c7a27d0810 page_queue_partitioned.cc --- a/page_queue_partitioned.cc Sun Mar 28 22:38:45 2021 +0200 +++ b/page_queue_partitioned.cc Sun Mar 28 22:41:12 2021 +0200 @@ -1,5 +1,15 @@ #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. */ @@ -96,8 +106,7 @@ bool PageQueuePartitioned::remove(PageOwner *owner, Flexpage *flexpage) { - (void) owner; (void) flexpage; - return true; + return PageQueue::remove(_issued, _positions, owner, flexpage); } // vim: tabstop=4 expandtab shiftwidth=4 diff -r e7a9e8c6995f -r e8c7a27d0810 page_queue_partitioned.h --- a/page_queue_partitioned.h Sun Mar 28 22:38:45 2021 +0200 +++ b/page_queue_partitioned.h Sun Mar 28 22:41:12 2021 +0200 @@ -21,6 +21,8 @@ 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); diff -r e7a9e8c6995f -r e8c7a27d0810 page_queue_shared.cc --- a/page_queue_shared.cc Sun Mar 28 22:38:45 2021 +0200 +++ b/page_queue_shared.cc Sun Mar 28 22:41:12 2021 +0200 @@ -1,5 +1,14 @@ #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. */ @@ -76,26 +85,7 @@ bool PageQueueShared::remove(PageOwner *owner, Flexpage *flexpage) { - std::lock_guard guard(_lock); - - 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; + return PageQueue::remove(_queue, _positions, owner, flexpage); } // vim: tabstop=4 expandtab shiftwidth=4 diff -r e7a9e8c6995f -r e8c7a27d0810 page_queue_shared.h --- a/page_queue_shared.h Sun Mar 28 22:38:45 2021 +0200 +++ b/page_queue_shared.h Sun Mar 28 22:41:12 2021 +0200 @@ -21,6 +21,8 @@ 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); diff -r e7a9e8c6995f -r e8c7a27d0810 pages.cc --- a/pages.cc Sun Mar 28 22:38:45 2021 +0200 +++ b/pages.cc Sun Mar 28 22:41:12 2021 +0200 @@ -14,6 +14,11 @@ _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. */ diff -r e7a9e8c6995f -r e8c7a27d0810 pages.h --- a/pages.h Sun Mar 28 22:38:45 2021 +0200 +++ b/pages.h Sun Mar 28 22:41:12 2021 +0200 @@ -20,9 +20,7 @@ explicit Pages(PageQueue *queue); - virtual ~Pages() - { - } + virtual ~Pages(); virtual Flexpage *remove();