1.1 --- a/Makefile Sat Mar 27 00:37:54 2021 +0100
1.2 +++ b/Makefile Sat Mar 27 00:55:05 2021 +0100
1.3 @@ -55,8 +55,9 @@
1.4 access_map.cc accessing.cc accessor.cc \
1.5 flexpage.cc file_pager.cc ipc.cc memory.cc \
1.6 opener_resource.cc opener_context_resource.cc \
1.7 - page_mapper.cc page_queue.cc pager.cc \
1.8 - pages.cc pages_conserving.cc paging.cc \
1.9 + page_mapper.cc page_queue_partitioned.cc page_queue_shared.cc \
1.10 + pager.cc paging.cc \
1.11 + page_collection.cc pages.cc pages_conserving.cc \
1.12 region.cc resource_server.cc simple_pager.cc
1.13
1.14 PLAIN_SRC_CC_dstest_block_server = \
2.1 --- a/access_map.cc Sat Mar 27 00:37:54 2021 +0100
2.2 +++ b/access_map.cc Sat Mar 27 00:55:05 2021 +0100
2.3 @@ -55,7 +55,7 @@
2.4 /* Purge all flexpages, using the 'owner' to flush their contents and
2.5 'pages' to make the flexpages available to other accessors. */
2.6
2.7 -void AccessMap::purge(PageOwner *owner, Pages *pages)
2.8 +void AccessMap::purge(PageOwner *owner, PageCollection *pages)
2.9 {
2.10 std::lock_guard<std::mutex> guard(_lock);
2.11
2.12 @@ -84,7 +84,7 @@
2.13 /* Flush flexpages in the given range from 'start' with 'size', using 'owner'
2.14 and 'pages'. */
2.15
2.16 -void AccessMap::flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages)
2.17 +void AccessMap::flush_all(offset_t start, offset_t size, PageOwner *owner, PageCollection *pages)
2.18 {
2.19 offset_t end = start + size;
2.20
3.1 --- a/access_map.h Sat Mar 27 00:37:54 2021 +0100
3.2 +++ b/access_map.h Sat Mar 27 00:55:05 2021 +0100
3.3 @@ -27,9 +27,9 @@
3.4
3.5 bool remove(PageOwner *owner, Flexpage *flexpage);
3.6
3.7 - void purge(PageOwner *owner, Pages *pages);
3.8 + void purge(PageOwner *owner, PageCollection *pages);
3.9
3.10 - void flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages);
3.11 + void flush_all(offset_t start, offset_t size, PageOwner *owner, PageCollection *pages);
3.12 };
3.13
3.14 // vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/dstest_pipe_server.cc Sat Mar 27 00:37:54 2021 +0100
4.2 +++ b/dstest_pipe_server.cc Sat Mar 27 00:55:05 2021 +0100
4.3 @@ -36,7 +36,7 @@
4.4 /* Some memory plus infrastructure. */
4.5
4.6 Memory mem(MEMORY_PAGES);
4.7 - PipeOpenerResource opener;
4.8 + PipeOpenerResource opener(&mem);
4.9
4.10 /* Register a server associating it with the given object. */
4.11
4.12 @@ -53,3 +53,5 @@
4.13 server.start();
4.14 return 0;
4.15 }
4.16 +
4.17 +// vim: tabstop=2 expandtab shiftwidth=2
5.1 --- a/files/pipe_paging.cc Sat Mar 27 00:37:54 2021 +0100
5.2 +++ b/files/pipe_paging.cc Sat Mar 27 00:55:05 2021 +0100
5.3 @@ -1,8 +1,16 @@
5.4 #include "pipe_paging.h"
5.5
5.6 +PipePaging::PipePaging(Memory *memory, offset_t size)
5.7 +: _memory(NULL), _size(size)
5.8 +{
5.9 + _pages = new PagesConserving(memory);
5.10 +}
5.11 +
5.12 PipePaging::PipePaging(offset_t size)
5.13 : _size(size)
5.14 {
5.15 + _memory = new Memory();
5.16 + _pages = new PagesConserving(_memory);
5.17 }
5.18
5.19 /* Detach one endpoint. */
5.20 @@ -29,6 +37,13 @@
5.21 mapper->detach();
5.22 delete mapper;
5.23 }
5.24 +
5.25 + /* Delete the page collection and memory object. */
5.26 +
5.27 + delete _pages;
5.28 +
5.29 + if (_memory != NULL)
5.30 + delete _memory;
5.31 }
5.32
5.33 /* Add a region to the sequence. */
6.1 --- a/files/pipe_paging.h Sat Mar 27 00:37:54 2021 +0100
6.2 +++ b/files/pipe_paging.h Sat Mar 27 00:55:05 2021 +0100
6.3 @@ -12,7 +12,8 @@
6.4 class PipePaging
6.5 {
6.6 protected:
6.7 - PagesConserving _pages;
6.8 + Memory *_memory;
6.9 + PagesConserving *_pages;
6.10
6.11 /* Regions acting as files with their own accessors. */
6.12
6.13 @@ -28,12 +29,14 @@
6.14 unsigned int _endpoints = 2;
6.15
6.16 public:
6.17 + explicit PipePaging(Memory *memory, offset_t size);
6.18 +
6.19 explicit PipePaging(offset_t size);
6.20
6.21 virtual void detach();
6.22
6.23 virtual PagesConserving *pages()
6.24 - { return &_pages; }
6.25 + { return _pages; }
6.26
6.27 virtual offset_t region_size()
6.28 { return _size; }
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/page_collection.cc Sat Mar 27 00:55:05 2021 +0100
7.3 @@ -0,0 +1,64 @@
7.4 +#include "pages.h"
7.5 +
7.6 +PageCollection::PageCollection(Memory *memory)
7.7 +: _memory(memory)
7.8 +{
7.9 +}
7.10 +
7.11 +PageCollection::PageCollection()
7.12 +{
7.13 + _memory = new Memory();
7.14 +}
7.15 +
7.16 +/* Remove the first flexpage in the queue. If its owner exists, remove it from
7.17 + the owner (retiring the content). Return the flexpage for reuse. */
7.18 +
7.19 +Flexpage *PageCollection::remove()
7.20 +{
7.21 + PageOwner *owner;
7.22 + Flexpage *flexpage;
7.23 +
7.24 + _queue->pop(&owner, &flexpage);
7.25 +
7.26 + if (owner != NULL)
7.27 + owner->remove(flexpage);
7.28 +
7.29 + return flexpage;
7.30 +}
7.31 +
7.32 +/* Reserve 'flexpage' by removing it from this collection. */
7.33 +
7.34 +bool PageCollection::reserve(PageOwner *owner, Flexpage *flexpage)
7.35 +{
7.36 + return _queue->remove(owner, flexpage);
7.37 +}
7.38 +
7.39 +/* Obtain a new flexpage. Return the flexpage or None if no new flexpage could
7.40 + be created. */
7.41 +
7.42 +Flexpage *PageCollection::flexpage()
7.43 +{
7.44 + Region *region = _memory->region();
7.45 +
7.46 + if (region != NULL)
7.47 + return new Flexpage(region);
7.48 + else
7.49 + return NULL;
7.50 +}
7.51 +
7.52 +/* Queue an entry associating the given 'owner' and 'flexpage'. */
7.53 +
7.54 +void PageCollection::queue(PageOwner *owner, Flexpage *flexpage)
7.55 +{
7.56 + _queue->push(owner, flexpage);
7.57 +}
7.58 +
7.59 +/* Push an entry for 'flexpage' without owner association for immediate
7.60 + reuse. */
7.61 +
7.62 +void PageCollection::release(Flexpage *flexpage)
7.63 +{
7.64 + _queue->push_front(NULL, flexpage);
7.65 +}
7.66 +
7.67 +// vim: tabstop=4 expandtab shiftwidth=4
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/page_collection.h Sat Mar 27 00:55:05 2021 +0100
8.3 @@ -0,0 +1,38 @@
8.4 +#pragma once
8.5 +
8.6 +#include "flexpage.h"
8.7 +#include "memory.h"
8.8 +#include "page_owner.h"
8.9 +#include "page_queue.h"
8.10 +
8.11 +
8.12 +
8.13 +/* A page collection. */
8.14 +
8.15 +class PageCollection
8.16 +{
8.17 +protected:
8.18 + PageQueue *_queue;
8.19 + Memory *_memory;
8.20 +
8.21 +public:
8.22 + explicit PageCollection(Memory *memory);
8.23 +
8.24 + explicit PageCollection();
8.25 +
8.26 + virtual ~PageCollection()
8.27 + {
8.28 + }
8.29 +
8.30 + virtual Flexpage *remove();
8.31 +
8.32 + virtual bool reserve(PageOwner *owner, Flexpage *flexpage);
8.33 +
8.34 + virtual Flexpage *flexpage();
8.35 +
8.36 + virtual void queue(PageOwner *owner, Flexpage *flexpage);
8.37 +
8.38 + virtual void release(Flexpage *flexpage);
8.39 +};
8.40 +
8.41 +// vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/page_mapper.cc Sat Mar 27 00:37:54 2021 +0100
9.2 +++ b/page_mapper.cc Sat Mar 27 00:55:05 2021 +0100
9.3 @@ -3,7 +3,7 @@
9.4
9.5
9.6
9.7 -PageMapper::PageMapper(Accessor *accessor, Pages *pages)
9.8 +PageMapper::PageMapper(Accessor *accessor, PageCollection *pages)
9.9 : _accessor(accessor), _pages(pages), _attached(0)
9.10 {
9.11 }
10.1 --- a/page_mapper.h Sat Mar 27 00:37:54 2021 +0100
10.2 +++ b/page_mapper.h Sat Mar 27 00:55:05 2021 +0100
10.3 @@ -13,7 +13,7 @@
10.4 protected:
10.5 AccessMap _map;
10.6 Accessor *_accessor;
10.7 - Pages *_pages;
10.8 + PageCollection *_pages;
10.9 unsigned int _attached;
10.10 std::mutex _lock;
10.11
10.12 @@ -24,7 +24,7 @@
10.13 Flexpage *flexpage(offset_t offset);
10.14
10.15 public:
10.16 - explicit PageMapper(Accessor *accessor, Pages *pages);
10.17 + explicit PageMapper(Accessor *accessor, PageCollection *pages);
10.18
10.19 /* Accounting methods. */
10.20
11.1 --- a/page_queue.cc Sat Mar 27 00:37:54 2021 +0100
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,101 +0,0 @@
11.4 -#include "page_queue.h"
11.5 -
11.6 -/* Keep waiting for a potential queue non-empty condition.
11.7 - Then, attempt to pop an entry from the queue. */
11.8 -
11.9 -void PageQueue::pop(PageOwner **owner, Flexpage **flexpage)
11.10 -{
11.11 - std::unique_lock<std::mutex> guard(_lock);
11.12 - QueueEntry entry;
11.13 -
11.14 - while (1)
11.15 - {
11.16 - if (_pop(&entry))
11.17 - {
11.18 - *owner = entry.owner;
11.19 - *flexpage = entry.flexpage;
11.20 - return;
11.21 - }
11.22 - else
11.23 - _counter.wait(guard);
11.24 - }
11.25 -}
11.26 -
11.27 -/* Check the queue for entries, returning false if no entries are available,
11.28 - returning true and providing the details if an entry can be removed from the
11.29 - front of the queue. */
11.30 -
11.31 -bool PageQueue::_pop(QueueEntry *entry)
11.32 -{
11.33 - if (_queue.empty())
11.34 - return false;
11.35 -
11.36 - *entry = _queue.front();
11.37 - _queue.pop_front();
11.38 -
11.39 - /* Remove any position reference for the flexpage. */
11.40 -
11.41 - Positions::iterator position = _positions.find(entry->flexpage);
11.42 -
11.43 - if (position != _positions.end())
11.44 - _positions.erase(position);
11.45 -
11.46 - return true;
11.47 -}
11.48 -
11.49 -/* Push an entry for the given owner and flexpage to the queue. */
11.50 -
11.51 -void PageQueue::push(PageOwner *owner, Flexpage *flexpage)
11.52 -{
11.53 - std::lock_guard<std::mutex> guard(_lock);
11.54 -
11.55 - /* Record the entry and a position reference for the flexpage. */
11.56 -
11.57 - _queue.push_back((QueueEntry) {flexpage, owner});
11.58 -
11.59 - Queue::iterator last = _queue.end();
11.60 - last--;
11.61 - _positions.insert(Position(flexpage, last));
11.62 -
11.63 - _counter.notify_one();
11.64 -}
11.65 -
11.66 -/* Push an entry to the front of the queue. */
11.67 -
11.68 -void PageQueue::push_front(PageOwner *owner, Flexpage *flexpage)
11.69 -{
11.70 - std::lock_guard<std::mutex> guard(_lock);
11.71 -
11.72 - _queue.push_back((QueueEntry) {flexpage, owner});
11.73 - _positions.insert(Position(flexpage, _queue.begin()));
11.74 -
11.75 - _counter.notify_one();
11.76 -}
11.77 -
11.78 -/* Remove an entry for the given owner and flexpage from the queue. */
11.79 -
11.80 -bool PageQueue::remove(PageOwner *owner, Flexpage *flexpage)
11.81 -{
11.82 - std::lock_guard<std::mutex> guard(_lock);
11.83 -
11.84 - Positions::iterator position = _positions.find(flexpage);
11.85 -
11.86 - if (position == _positions.end())
11.87 - return false;
11.88 -
11.89 - /* The found owner may be different from the requesting owner or even NULL
11.90 - if another owner has acquired and then purged its pages. Such a purged
11.91 - flexpage is not immediately usable, however. */
11.92 -
11.93 - Queue::iterator entry = position->second;
11.94 -
11.95 - if ((entry->owner == NULL) || (entry->owner != owner))
11.96 - return false;
11.97 -
11.98 - _queue.erase(entry);
11.99 - _positions.erase(position);
11.100 -
11.101 - return true;
11.102 -}
11.103 -
11.104 -// vim: tabstop=4 expandtab shiftwidth=4
12.1 --- a/page_queue.h Sat Mar 27 00:37:54 2021 +0100
12.2 +++ b/page_queue.h Sat Mar 27 00:55:05 2021 +0100
12.3 @@ -1,9 +1,7 @@
12.4 #pragma once
12.5
12.6 -#include <condition_variable>
12.7 #include <list>
12.8 #include <map>
12.9 -#include <mutex>
12.10
12.11 #include "flexpage.h"
12.12 #include "page_owner.h"
12.13 @@ -20,27 +18,18 @@
12.14
12.15
12.16
12.17 -/* A queue of issued pages. */
12.18 +/* A queue of managed pages. */
12.19
12.20 class PageQueue
12.21 {
12.22 -protected:
12.23 - Queue _queue;
12.24 - Positions _positions;
12.25 -
12.26 - std::mutex _lock;
12.27 - std::condition_variable _counter;
12.28 -
12.29 - bool _pop(QueueEntry *entry);
12.30 +public:
12.31 + virtual void pop(PageOwner **owner, Flexpage **flexpage) = 0;
12.32
12.33 -public:
12.34 - void pop(PageOwner **owner, Flexpage **flexpage);
12.35 + virtual void push(PageOwner *owner, Flexpage *flexpage) = 0;
12.36
12.37 - void push(PageOwner *owner, Flexpage *flexpage);
12.38 + virtual void push_front(PageOwner *owner, Flexpage *flexpage) = 0;
12.39
12.40 - void push_front(PageOwner *owner, Flexpage *flexpage);
12.41 -
12.42 - bool remove(PageOwner *owner, Flexpage *flexpage);
12.43 + virtual bool remove(PageOwner *owner, Flexpage *flexpage) = 0;
12.44 };
12.45
12.46 // vim: tabstop=4 expandtab shiftwidth=4
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/page_queue_partitioned.cc Sat Mar 27 00:55:05 2021 +0100
13.3 @@ -0,0 +1,103 @@
13.4 +#include "page_queue_partitioned.h"
13.5 +
13.6 +/* Keep waiting for a potential queue non-empty condition.
13.7 + Then, attempt to pop an entry from the queue. */
13.8 +
13.9 +void PageQueuePartitioned::pop(PageOwner **owner, Flexpage **flexpage)
13.10 +{
13.11 + std::unique_lock<std::mutex> guard(_lock);
13.12 + QueueEntry entry;
13.13 +
13.14 + while (1)
13.15 + {
13.16 + if (_pop(&entry))
13.17 + {
13.18 + *owner = entry.owner;
13.19 + *flexpage = entry.flexpage;
13.20 + return;
13.21 + }
13.22 + else
13.23 + _counter.wait(guard);
13.24 + }
13.25 +}
13.26 +
13.27 +/* Check the available pages queue for entries, returning false if no entries
13.28 + are available, returning true and providing the details if an entry can be
13.29 + removed from the front of the queue. */
13.30 +
13.31 +bool PageQueuePartitioned::_pop(QueueEntry *entry)
13.32 +{
13.33 + if (_available.empty())
13.34 + return false;
13.35 +
13.36 + *entry = _available.front();
13.37 + _available.pop_front();
13.38 +
13.39 + return true;
13.40 +}
13.41 +
13.42 +/* Push an entry for the given owner and flexpage to the appropriate queue. */
13.43 +
13.44 +void PageQueuePartitioned::push(PageOwner *owner, Flexpage *flexpage)
13.45 +{
13.46 + std::lock_guard<std::mutex> guard(_lock);
13.47 +
13.48 + /* Record the entry and a position reference for the flexpage. */
13.49 +
13.50 + Queue *queue;
13.51 + Positions *positions = NULL;
13.52 +
13.53 + if (owner == NULL)
13.54 + queue = &_available;
13.55 + else
13.56 + {
13.57 + queue = &_issued;
13.58 + positions = &_positions;
13.59 + }
13.60 +
13.61 + queue->push_back((QueueEntry) {flexpage, owner});
13.62 +
13.63 + if (positions != NULL)
13.64 + {
13.65 + Queue::iterator last = queue->end();
13.66 + last--;
13.67 + positions->insert(Position(flexpage, last));
13.68 + }
13.69 +
13.70 + _counter.notify_one();
13.71 +}
13.72 +
13.73 +/* Push an entry to the front of the appropriate queue. */
13.74 +
13.75 +void PageQueuePartitioned::push_front(PageOwner *owner, Flexpage *flexpage)
13.76 +{
13.77 + std::lock_guard<std::mutex> guard(_lock);
13.78 +
13.79 + Queue *queue;
13.80 + Positions *positions = NULL;
13.81 +
13.82 + if (owner == NULL)
13.83 + queue = &_available;
13.84 + else
13.85 + {
13.86 + queue = &_issued;
13.87 + positions = &_positions;
13.88 + }
13.89 +
13.90 + queue->push_back((QueueEntry) {flexpage, owner});
13.91 +
13.92 + if (positions != NULL)
13.93 + positions->insert(Position(flexpage, queue->begin()));
13.94 +
13.95 + _counter.notify_one();
13.96 +}
13.97 +
13.98 +/* Remove an entry for the given owner and flexpage from the queue. */
13.99 +
13.100 +bool PageQueuePartitioned::remove(PageOwner *owner, Flexpage *flexpage)
13.101 +{
13.102 + (void) owner; (void) flexpage;
13.103 + return true;
13.104 +}
13.105 +
13.106 +// vim: tabstop=4 expandtab shiftwidth=4
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/page_queue_partitioned.h Sat Mar 27 00:55:05 2021 +0100
14.3 @@ -0,0 +1,33 @@
14.4 +#pragma once
14.5 +
14.6 +#include <condition_variable>
14.7 +#include <mutex>
14.8 +
14.9 +#include "page_queue.h"
14.10 +
14.11 +
14.12 +
14.13 +/* Queues of issued and available pages. */
14.14 +
14.15 +class PageQueuePartitioned : public PageQueue
14.16 +{
14.17 +protected:
14.18 + Queue _issued, _available;
14.19 + Positions _positions;
14.20 +
14.21 + std::mutex _lock;
14.22 + std::condition_variable _counter;
14.23 +
14.24 + virtual bool _pop(QueueEntry *entry);
14.25 +
14.26 +public:
14.27 + virtual void pop(PageOwner **owner, Flexpage **flexpage);
14.28 +
14.29 + virtual void push(PageOwner *owner, Flexpage *flexpage);
14.30 +
14.31 + virtual void push_front(PageOwner *owner, Flexpage *flexpage);
14.32 +
14.33 + virtual bool remove(PageOwner *owner, Flexpage *flexpage);
14.34 +};
14.35 +
14.36 +// vim: tabstop=4 expandtab shiftwidth=4
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/page_queue_shared.cc Sat Mar 27 00:55:05 2021 +0100
15.3 @@ -0,0 +1,101 @@
15.4 +#include "page_queue_shared.h"
15.5 +
15.6 +/* Keep waiting for a potential queue non-empty condition.
15.7 + Then, attempt to pop an entry from the queue. */
15.8 +
15.9 +void PageQueueShared::pop(PageOwner **owner, Flexpage **flexpage)
15.10 +{
15.11 + std::unique_lock<std::mutex> guard(_lock);
15.12 + QueueEntry entry;
15.13 +
15.14 + while (1)
15.15 + {
15.16 + if (_pop(&entry))
15.17 + {
15.18 + *owner = entry.owner;
15.19 + *flexpage = entry.flexpage;
15.20 + return;
15.21 + }
15.22 + else
15.23 + _counter.wait(guard);
15.24 + }
15.25 +}
15.26 +
15.27 +/* Check the queue for entries, returning false if no entries are available,
15.28 + returning true and providing the details if an entry can be removed from the
15.29 + front of the queue. */
15.30 +
15.31 +bool PageQueueShared::_pop(QueueEntry *entry)
15.32 +{
15.33 + if (_queue.empty())
15.34 + return false;
15.35 +
15.36 + *entry = _queue.front();
15.37 + _queue.pop_front();
15.38 +
15.39 + /* Remove any position reference for the flexpage. */
15.40 +
15.41 + Positions::iterator position = _positions.find(entry->flexpage);
15.42 +
15.43 + if (position != _positions.end())
15.44 + _positions.erase(position);
15.45 +
15.46 + return true;
15.47 +}
15.48 +
15.49 +/* Push an entry for the given owner and flexpage to the queue. */
15.50 +
15.51 +void PageQueueShared::push(PageOwner *owner, Flexpage *flexpage)
15.52 +{
15.53 + std::lock_guard<std::mutex> guard(_lock);
15.54 +
15.55 + /* Record the entry and a position reference for the flexpage. */
15.56 +
15.57 + _queue.push_back((QueueEntry) {flexpage, owner});
15.58 +
15.59 + Queue::iterator last = _queue.end();
15.60 + last--;
15.61 + _positions.insert(Position(flexpage, last));
15.62 +
15.63 + _counter.notify_one();
15.64 +}
15.65 +
15.66 +/* Push an entry to the front of the queue. */
15.67 +
15.68 +void PageQueueShared::push_front(PageOwner *owner, Flexpage *flexpage)
15.69 +{
15.70 + std::lock_guard<std::mutex> guard(_lock);
15.71 +
15.72 + _queue.push_back((QueueEntry) {flexpage, owner});
15.73 + _positions.insert(Position(flexpage, _queue.begin()));
15.74 +
15.75 + _counter.notify_one();
15.76 +}
15.77 +
15.78 +/* Remove an entry for the given owner and flexpage from the queue. */
15.79 +
15.80 +bool PageQueueShared::remove(PageOwner *owner, Flexpage *flexpage)
15.81 +{
15.82 + std::lock_guard<std::mutex> guard(_lock);
15.83 +
15.84 + Positions::iterator position = _positions.find(flexpage);
15.85 +
15.86 + if (position == _positions.end())
15.87 + return false;
15.88 +
15.89 + /* The found owner may be different from the requesting owner or even NULL
15.90 + if another owner has acquired and then purged its pages. Such a purged
15.91 + flexpage is not immediately usable, however. */
15.92 +
15.93 + Queue::iterator entry = position->second;
15.94 +
15.95 + if ((entry->owner == NULL) || (entry->owner != owner))
15.96 + return false;
15.97 +
15.98 + _queue.erase(entry);
15.99 + _positions.erase(position);
15.100 +
15.101 + return true;
15.102 +}
15.103 +
15.104 +// vim: tabstop=4 expandtab shiftwidth=4
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/page_queue_shared.h Sat Mar 27 00:55:05 2021 +0100
16.3 @@ -0,0 +1,33 @@
16.4 +#pragma once
16.5 +
16.6 +#include <condition_variable>
16.7 +#include <mutex>
16.8 +
16.9 +#include "page_queue.h"
16.10 +
16.11 +
16.12 +
16.13 +/* A queue of issued pages. */
16.14 +
16.15 +class PageQueueShared : public PageQueue
16.16 +{
16.17 +protected:
16.18 + Queue _queue;
16.19 + Positions _positions;
16.20 +
16.21 + std::mutex _lock;
16.22 + std::condition_variable _counter;
16.23 +
16.24 + virtual bool _pop(QueueEntry *entry);
16.25 +
16.26 +public:
16.27 + virtual void pop(PageOwner **owner, Flexpage **flexpage);
16.28 +
16.29 + virtual void push(PageOwner *owner, Flexpage *flexpage);
16.30 +
16.31 + virtual void push_front(PageOwner *owner, Flexpage *flexpage);
16.32 +
16.33 + virtual bool remove(PageOwner *owner, Flexpage *flexpage);
16.34 +};
16.35 +
16.36 +// vim: tabstop=4 expandtab shiftwidth=4
17.1 --- a/pages.cc Sat Mar 27 00:37:54 2021 +0100
17.2 +++ b/pages.cc Sat Mar 27 00:55:05 2021 +0100
17.3 @@ -1,64 +1,15 @@
17.4 #include "pages.h"
17.5
17.6 Pages::Pages(Memory *memory)
17.7 -: _memory(memory)
17.8 +: PageCollection(memory)
17.9 {
17.10 + _queue = &_page_queue;
17.11 }
17.12
17.13 Pages::Pages()
17.14 -{
17.15 - _memory = new Memory();
17.16 -}
17.17 -
17.18 -/* Remove the first flexpage in the queue. If its owner exists, remove it from
17.19 - the owner (retiring the content). Return the flexpage for reuse. */
17.20 -
17.21 -Flexpage *Pages::remove()
17.22 -{
17.23 - PageOwner *owner;
17.24 - Flexpage *flexpage;
17.25 -
17.26 - _queue.pop(&owner, &flexpage);
17.27 -
17.28 - if (owner != NULL)
17.29 - owner->remove(flexpage);
17.30 -
17.31 - return flexpage;
17.32 -}
17.33 -
17.34 -/* Reserve 'flexpage' by removing it from this collection. */
17.35 -
17.36 -bool Pages::reserve(PageOwner *owner, Flexpage *flexpage)
17.37 +: PageCollection()
17.38 {
17.39 - return _queue.remove(owner, flexpage);
17.40 -}
17.41 -
17.42 -/* Obtain a new flexpage. Return the flexpage or None if no new flexpage could
17.43 - be created. */
17.44 -
17.45 -Flexpage *Pages::flexpage()
17.46 -{
17.47 - Region *region = _memory->region();
17.48 -
17.49 - if (region != NULL)
17.50 - return new Flexpage(region);
17.51 - else
17.52 - return NULL;
17.53 -}
17.54 -
17.55 -/* Queue an entry associating the given 'owner' and 'flexpage'. */
17.56 -
17.57 -void Pages::queue(PageOwner *owner, Flexpage *flexpage)
17.58 -{
17.59 - _queue.push(owner, flexpage);
17.60 -}
17.61 -
17.62 -/* Push an entry for 'flexpage' without owner association for immediate
17.63 - reuse. */
17.64 -
17.65 -void Pages::release(Flexpage *flexpage)
17.66 -{
17.67 - _queue.push_front(NULL, flexpage);
17.68 + _queue = &_page_queue;
17.69 }
17.70
17.71 // vim: tabstop=4 expandtab shiftwidth=4
18.1 --- a/pages.h Sat Mar 27 00:37:54 2021 +0100
18.2 +++ b/pages.h Sat Mar 27 00:55:05 2021 +0100
18.3 @@ -1,34 +1,21 @@
18.4 #pragma once
18.5
18.6 -#include "flexpage.h"
18.7 -#include "memory.h"
18.8 -#include "page_owner.h"
18.9 -#include "page_queue.h"
18.10 +#include "page_collection.h"
18.11 +#include "page_queue_shared.h"
18.12
18.13
18.14
18.15 /* A page collection. */
18.16
18.17 -class Pages
18.18 +class Pages : public PageCollection
18.19 {
18.20 protected:
18.21 - PageQueue _queue;
18.22 - Memory *_memory;
18.23 + PageQueueShared _page_queue;
18.24
18.25 public:
18.26 explicit Pages(Memory *memory);
18.27
18.28 explicit Pages();
18.29 -
18.30 - virtual Flexpage *remove();
18.31 -
18.32 - virtual bool reserve(PageOwner *owner, Flexpage *flexpage);
18.33 -
18.34 - virtual Flexpage *flexpage();
18.35 -
18.36 - virtual void queue(PageOwner *owner, Flexpage *flexpage);
18.37 -
18.38 - virtual void release(Flexpage *flexpage);
18.39 };
18.40
18.41 // vim: tabstop=4 expandtab shiftwidth=4
19.1 --- a/pages_conserving.cc Sat Mar 27 00:37:54 2021 +0100
19.2 +++ b/pages_conserving.cc Sat Mar 27 00:55:05 2021 +0100
19.3 @@ -1,13 +1,15 @@
19.4 #include "pages_conserving.h"
19.5
19.6 PagesConserving::PagesConserving(Memory *memory)
19.7 -: Pages(memory)
19.8 +: PageCollection(memory)
19.9 {
19.10 + _queue = &_page_queue;
19.11 }
19.12
19.13 PagesConserving::PagesConserving()
19.14 -: Pages()
19.15 +: PageCollection()
19.16 {
19.17 + _queue = &_page_queue;
19.18 }
19.19
19.20
19.21 @@ -20,24 +22,6 @@
19.22 return NULL;
19.23 }
19.24
19.25 -/* Pretend to queue an entry associating the given 'owner' and 'flexpage'.
19.26 - Since this collection "conserves" flexpages, they will not be queued unless
19.27 - completely unused. */
19.28 -
19.29 -void PagesConserving::queue(PageOwner *owner, Flexpage *flexpage)
19.30 -{
19.31 - (void) owner; (void) flexpage;
19.32 -}
19.33 -
19.34 -/* Pretend to reserve a flexpage already being used by 'owner' and 'flexpage'.
19.35 - Since flexpages are not queued when in use, there is nothing to reserve. */
19.36 -
19.37 -bool PagesConserving::reserve(PageOwner *owner, Flexpage *flexpage)
19.38 -{
19.39 - (void) owner; (void) flexpage;
19.40 - return true;
19.41 -}
19.42 -
19.43
19.44
19.45 /* Decrease the provision of flexpages to pipes. */
19.46 @@ -83,7 +67,7 @@
19.47 /* Queue flexpages for the regions. */
19.48
19.49 for (it = allocated.begin(); it != allocated.end(); it++)
19.50 - _queue.push(NULL, new Flexpage(*it));
19.51 + _queue->push(NULL, new Flexpage(*it));
19.52
19.53 return true;
19.54 }
20.1 --- a/pages_conserving.h Sat Mar 27 00:37:54 2021 +0100
20.2 +++ b/pages_conserving.h Sat Mar 27 00:55:05 2021 +0100
20.3 @@ -1,14 +1,18 @@
20.4 #pragma once
20.5
20.6 -#include "pages.h"
20.7 +#include "page_collection.h"
20.8 +#include "page_queue_partitioned.h"
20.9
20.10
20.11
20.12 /* A page collection where the pages are "conserved", meaning that they are not
20.13 queued for reuse unless they are completely unused. */
20.14
20.15 -class PagesConserving : public Pages
20.16 +class PagesConserving : public PageCollection
20.17 {
20.18 +protected:
20.19 + PageQueuePartitioned _page_queue;
20.20 +
20.21 public:
20.22 explicit PagesConserving(Memory *memory);
20.23
20.24 @@ -18,10 +22,6 @@
20.25
20.26 virtual Flexpage *flexpage();
20.27
20.28 - virtual void queue(PageOwner *owner, Flexpage *flexpage);
20.29 -
20.30 - virtual bool reserve(PageOwner *owner, Flexpage *flexpage);
20.31 -
20.32 /* Memory control methods. */
20.33
20.34 virtual bool decrease(offset_t size);
21.1 --- a/pipe_opener_resource.cc Sat Mar 27 00:37:54 2021 +0100
21.2 +++ b/pipe_opener_resource.cc Sat Mar 27 00:55:05 2021 +0100
21.3 @@ -7,8 +7,14 @@
21.4
21.5 /* Support for providing access to pipes. */
21.6
21.7 +PipeOpenerResource::PipeOpenerResource(Memory *memory)
21.8 +: _memory(memory)
21.9 +{
21.10 +}
21.11 +
21.12 PipeOpenerResource::PipeOpenerResource()
21.13 {
21.14 + _memory = new Memory();
21.15 }
21.16
21.17 int PipeOpenerResource::expected_items()
21.18 @@ -29,7 +35,7 @@
21.19 {
21.20 /* Both endpoints will employ a common paging coordinator. */
21.21
21.22 - PipePaging *paging = new PipePaging(size);
21.23 + PipePaging *paging = new PipePaging(_memory, size);
21.24
21.25 /* Each endpoint will have its own pager. */
21.26
22.1 --- a/pipe_opener_resource.h Sat Mar 27 00:37:54 2021 +0100
22.2 +++ b/pipe_opener_resource.h Sat Mar 27 00:55:05 2021 +0100
22.3 @@ -1,5 +1,6 @@
22.4 #pragma once
22.5
22.6 +#include "memory.h"
22.7 #include "pipe_opener_interface.h"
22.8 #include "pipe_paging.h"
22.9 #include "resource.h"
22.10 @@ -9,9 +10,13 @@
22.11 class PipeOpenerResource : public Resource, public PipeOpener
22.12 {
22.13 protected:
22.14 + Memory *_memory;
22.15 +
22.16 long open_endpoint(PipePaging *paging, bool writing, l4_cap_idx_t *endpoint);
22.17
22.18 public:
22.19 + explicit PipeOpenerResource(Memory *memory);
22.20 +
22.21 explicit PipeOpenerResource();
22.22
22.23 /* Server details. */