1.1 --- a/Makefile Sat Mar 27 01:42:25 2021 +0100
1.2 +++ b/Makefile Sat Mar 27 22:12:12 2021 +0100
1.3 @@ -53,22 +53,25 @@
1.4
1.5 PLAIN_SRC_CC_common_server = \
1.6 access_map.cc accessing.cc accessor.cc \
1.7 - flexpage.cc files/file_pager.cc ipc.cc memory.cc \
1.8 + flexpage.cc ipc.cc \
1.9 + memory/memory_incremental.cc memory/memory_preallocated.cc \
1.10 opener_resource.cc opener_context_resource.cc \
1.11 - page_mapper.cc page_queue_partitioned.cc page_queue_shared.cc \
1.12 - pager.cc paging.cc \
1.13 - page_collection.cc pages.cc pages_conserving.cc \
1.14 + page_mapper.cc \
1.15 + page_queue_partitioned.cc page_queue_shared.cc \
1.16 + pager.cc paging.cc pages.cc \
1.17 region.cc resource_server.cc simple_pager.cc
1.18
1.19 PLAIN_SRC_CC_dstest_block_server = \
1.20 $(PLAIN_SRC_CC_common_server) \
1.21 dstest_block_server.cc \
1.22 + files/file_pager.cc \
1.23 files/block_file_accessor.cc files/block_file_opener.cc \
1.24 files/host_file_accessor.cc files/host_file_opener.cc
1.25
1.26 PLAIN_SRC_CC_dstest_host_server = \
1.27 $(PLAIN_SRC_CC_common_server) \
1.28 dstest_host_server.cc \
1.29 + files/file_pager.cc \
1.30 files/host_file_accessor.cc files/host_file_opener.cc
1.31
1.32 PLAIN_SRC_CC_dstest_pipe_server = \
1.33 @@ -80,6 +83,7 @@
1.34 PLAIN_SRC_CC_dstest_test_server = \
1.35 $(PLAIN_SRC_CC_common_server) \
1.36 dstest_test_server.cc \
1.37 + files/file_pager.cc \
1.38 files/test_file_accessor.cc files/test_file_opener.cc
1.39
1.40 # Normal definitions.
1.41 @@ -126,7 +130,7 @@
1.42
1.43 REQUIRES_LIBS = l4re_c-util libipc libstdc++ libsystypes
1.44
1.45 -PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(PKGDIR)/pipes \
1.46 +PRIVATE_INCDIR = $(PKGDIR) $(PKGDIR)/files $(PKGDIR)/memory $(PKGDIR)/pipes \
1.47 $(IDL_BUILD_DIR) $(IDL_EXPORT_DIR)
1.48
1.49 include $(L4DIR)/mk/prog.mk
2.1 --- a/access_map.cc Sat Mar 27 01:42:25 2021 +0100
2.2 +++ b/access_map.cc Sat Mar 27 22:12:12 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, PageCollection *pages)
2.8 +void AccessMap::purge(PageOwner *owner, Pages *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, PageCollection *pages)
2.17 +void AccessMap::flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages)
2.18 {
2.19 offset_t end = start + size;
2.20
3.1 --- a/access_map.h Sat Mar 27 01:42:25 2021 +0100
3.2 +++ b/access_map.h Sat Mar 27 22:12:12 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, PageCollection *pages);
3.8 + void purge(PageOwner *owner, Pages *pages);
3.9
3.10 - void flush_all(offset_t start, offset_t size, PageOwner *owner, PageCollection *pages);
3.11 + void flush_all(offset_t start, offset_t size, PageOwner *owner, Pages *pages);
3.12 };
3.13
3.14 // vim: tabstop=4 expandtab shiftwidth=4
4.1 --- a/dstest_block_server.cc Sat Mar 27 01:42:25 2021 +0100
4.2 +++ b/dstest_block_server.cc Sat Mar 27 22:12:12 2021 +0100
4.3 @@ -27,8 +27,9 @@
4.4 #include <stdlib.h>
4.5
4.6 #include "accessing.h"
4.7 -#include "memory.h"
4.8 +#include "memory_incremental.h"
4.9 #include "memory_utils.h"
4.10 +#include "page_queue_shared.h"
4.11 #include "pages.h"
4.12 #include "paging.h"
4.13 #include "resource_server.h"
4.14 @@ -42,10 +43,11 @@
4.15 {
4.16 /* Some memory plus infrastructure. */
4.17
4.18 - Memory mem(MEMORY_PAGES);
4.19 + MemoryIncremental mem(MEMORY_PAGES);
4.20 Accessing accessing;
4.21 Paging paging;
4.22 - Pages pages(&mem);
4.23 + PageQueueShared queue;
4.24 + Pages pages(&mem, &queue);
4.25 BlockFileOpener opener(&accessing, &paging, &pages);
4.26
4.27 /* Register a server associating it with the given object. */
4.28 @@ -63,3 +65,5 @@
4.29 server.start();
4.30 return 0;
4.31 }
4.32 +
4.33 +// vim: tabstop=2 expandtab shiftwidth=2
5.1 --- a/dstest_host_server.cc Sat Mar 27 01:42:25 2021 +0100
5.2 +++ b/dstest_host_server.cc Sat Mar 27 22:12:12 2021 +0100
5.3 @@ -27,8 +27,9 @@
5.4 #include <stdlib.h>
5.5
5.6 #include "accessing.h"
5.7 -#include "memory.h"
5.8 +#include "memory_incremental.h"
5.9 #include "memory_utils.h"
5.10 +#include "page_queue_shared.h"
5.11 #include "pages.h"
5.12 #include "paging.h"
5.13 #include "resource_server.h"
5.14 @@ -42,10 +43,11 @@
5.15 {
5.16 /* Some memory plus infrastructure. */
5.17
5.18 - Memory mem(MEMORY_PAGES);
5.19 + MemoryIncremental mem(MEMORY_PAGES);
5.20 Accessing accessing;
5.21 Paging paging;
5.22 - Pages pages(&mem);
5.23 + PageQueueShared queue;
5.24 + Pages pages(&mem, &queue);
5.25 HostFileOpener opener(&accessing, &paging, &pages);
5.26
5.27 /* Register a server associating it with the given object. */
6.1 --- a/dstest_pipe_client.cc Sat Mar 27 01:42:25 2021 +0100
6.2 +++ b/dstest_pipe_client.cc Sat Mar 27 22:12:12 2021 +0100
6.3 @@ -94,8 +94,8 @@
6.4
6.5 if (err)
6.6 {
6.7 - printf("Region traversal error: %s\n", l4sys_errtostr(err));
6.8 - return 1;
6.9 + printf("Region traversal error at region %d: %s\n", region, l4sys_errtostr(err));
6.10 + break;
6.11 }
6.12 }
6.13
7.1 --- a/dstest_pipe_server.cc Sat Mar 27 01:42:25 2021 +0100
7.2 +++ b/dstest_pipe_server.cc Sat Mar 27 22:12:12 2021 +0100
7.3 @@ -23,7 +23,7 @@
7.4
7.5 #include <stdio.h>
7.6
7.7 -#include "memory.h"
7.8 +#include "memory_incremental.h"
7.9 #include "pipe_opener_resource.h"
7.10 #include "resource_server.h"
7.11
7.12 @@ -35,7 +35,7 @@
7.13 {
7.14 /* Some memory plus infrastructure. */
7.15
7.16 - Memory mem(MEMORY_PAGES);
7.17 + MemoryIncremental mem(MEMORY_PAGES);
7.18 PipeOpenerResource opener(&mem);
7.19
7.20 /* Register a server associating it with the given object. */
8.1 --- a/dstest_test_server.cc Sat Mar 27 01:42:25 2021 +0100
8.2 +++ b/dstest_test_server.cc Sat Mar 27 22:12:12 2021 +0100
8.3 @@ -29,8 +29,9 @@
8.4 #include <stdlib.h>
8.5
8.6 #include "accessing.h"
8.7 -#include "memory.h"
8.8 +#include "memory_incremental.h"
8.9 #include "memory_utils.h"
8.10 +#include "page_queue_shared.h"
8.11 #include "pages.h"
8.12 #include "paging.h"
8.13 #include "resource_server.h"
8.14 @@ -65,10 +66,11 @@
8.15
8.16 /* Some memory plus infrastructure. */
8.17
8.18 - Memory mem(memory_pages, page(REGION_PAGES));
8.19 + MemoryIncremental mem(memory_pages, page(REGION_PAGES));
8.20 Accessing accessing;
8.21 Paging paging;
8.22 - Pages pages(&mem);
8.23 + PageQueueShared queue;
8.24 + Pages pages(&mem, &queue);
8.25 TestFileOpener opener(&accessing, &paging, &pages, page(FILE_PAGES));
8.26
8.27 /* Register a server associating it with the given object. */
9.1 --- a/memory.cc Sat Mar 27 01:42:25 2021 +0100
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,90 +0,0 @@
9.4 -#include "memory.h"
9.5 -
9.6 -#include <stdlib.h>
9.7 -
9.8 -
9.9 -/* Initialise the memory pool with an optional 'limit' in pages. */
9.10 -
9.11 -Memory::Memory(unsigned int limit, offset_t region_size)
9.12 -: _limit(limit), _region_size(region_size)
9.13 -{
9.14 - _limited = true;
9.15 -}
9.16 -
9.17 -Memory::Memory()
9.18 -: _region_size(PAGE_SIZE)
9.19 -{
9.20 - _limited = false;
9.21 -}
9.22 -
9.23 -/* Allocate a block of the given 'size'. */
9.24 -
9.25 -Region *Memory::allocate(offset_t size)
9.26 -{
9.27 - /* Attempt to allocate aligned memory. */
9.28 -
9.29 - void *current;
9.30 -
9.31 - /* Make the size appropriate for the invocation. */
9.32 -
9.33 - size = round_multiple(size, PAGE_SIZE);
9.34 -
9.35 - if (posix_memalign(¤t, size, size))
9.36 - return NULL;
9.37 -
9.38 - return new Region((offset_t) current, (offset_t) current + size);
9.39 -}
9.40 -
9.41 -/* Allocate a new region of the given 'size' rounded to the nearest page. */
9.42 -
9.43 -Region *Memory::region(offset_t size)
9.44 -{
9.45 - std::lock_guard<std::mutex> guard(_lock);
9.46 -
9.47 - offset_t rounded = round(size, PAGE_SIZE);
9.48 - offset_t pages = rounded / PAGE_SIZE;
9.49 -
9.50 - /* Check for sufficient pages. */
9.51 -
9.52 - if (!_limited || (_limit >= pages))
9.53 - {
9.54 - /* Attempt to allocate aligned memory. */
9.55 -
9.56 - Region *region = allocate(rounded);
9.57 -
9.58 - if (region == NULL)
9.59 - return NULL;
9.60 -
9.61 - if (_limited)
9.62 - _limit -= pages;
9.63 -
9.64 - return region;
9.65 - }
9.66 -
9.67 - /* Return no region without sufficient pages. */
9.68 -
9.69 - else
9.70 - return NULL;
9.71 -}
9.72 -
9.73 -Region *Memory::region()
9.74 -{
9.75 - return region(_region_size);
9.76 -}
9.77 -
9.78 -/* Release the allocated 'region'. */
9.79 -
9.80 -void Memory::release(Region *region)
9.81 -{
9.82 - std::lock_guard<std::mutex> guard(_lock);
9.83 -
9.84 - offset_t rounded = round(region->size(), PAGE_SIZE);
9.85 - offset_t pages = rounded / PAGE_SIZE;
9.86 -
9.87 - if (_limited)
9.88 - _limit += pages;
9.89 -
9.90 - delete region;
9.91 -}
9.92 -
9.93 -// vim: tabstop=4 expandtab shiftwidth=4
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/memory/memory_incremental.cc Sat Mar 27 22:12:12 2021 +0100
12.3 @@ -0,0 +1,90 @@
12.4 +#include "memory_incremental.h"
12.5 +
12.6 +#include <stdlib.h>
12.7 +
12.8 +
12.9 +/* Initialise the memory pool with an optional 'limit' in pages. */
12.10 +
12.11 +MemoryIncremental::MemoryIncremental(unsigned int limit, offset_t region_size)
12.12 +: _limit(limit), _region_size(region_size)
12.13 +{
12.14 + _limited = true;
12.15 +}
12.16 +
12.17 +MemoryIncremental::MemoryIncremental()
12.18 +: _region_size(PAGE_SIZE)
12.19 +{
12.20 + _limited = false;
12.21 +}
12.22 +
12.23 +/* Allocate a block of the given 'size'. */
12.24 +
12.25 +Region *MemoryIncremental::allocate(offset_t size)
12.26 +{
12.27 + /* Attempt to allocate aligned memory. */
12.28 +
12.29 + void *current;
12.30 +
12.31 + /* Make the size appropriate for the invocation. */
12.32 +
12.33 + size = round_multiple(size, PAGE_SIZE);
12.34 +
12.35 + if (posix_memalign(¤t, size, size))
12.36 + return NULL;
12.37 +
12.38 + return new Region((offset_t) current, (offset_t) current + size);
12.39 +}
12.40 +
12.41 +/* Allocate a new region of the given 'size' rounded to the nearest page. */
12.42 +
12.43 +Region *MemoryIncremental::region(offset_t size)
12.44 +{
12.45 + std::lock_guard<std::mutex> guard(_lock);
12.46 +
12.47 + offset_t rounded = round(size, PAGE_SIZE);
12.48 + offset_t pages = rounded / PAGE_SIZE;
12.49 +
12.50 + /* Check for sufficient pages. */
12.51 +
12.52 + if (!_limited || (_limit >= pages))
12.53 + {
12.54 + /* Attempt to allocate aligned memory. */
12.55 +
12.56 + Region *region = allocate(rounded);
12.57 +
12.58 + if (region == NULL)
12.59 + return NULL;
12.60 +
12.61 + if (_limited)
12.62 + _limit -= pages;
12.63 +
12.64 + return region;
12.65 + }
12.66 +
12.67 + /* Return no region without sufficient pages. */
12.68 +
12.69 + else
12.70 + return NULL;
12.71 +}
12.72 +
12.73 +Region *MemoryIncremental::region()
12.74 +{
12.75 + return region(_region_size);
12.76 +}
12.77 +
12.78 +/* Release the allocated 'region'. */
12.79 +
12.80 +void MemoryIncremental::release(Region *region)
12.81 +{
12.82 + std::lock_guard<std::mutex> guard(_lock);
12.83 +
12.84 + offset_t rounded = round(region->size(), PAGE_SIZE);
12.85 + offset_t pages = rounded / PAGE_SIZE;
12.86 +
12.87 + if (_limited)
12.88 + _limit += pages;
12.89 +
12.90 + delete region;
12.91 +}
12.92 +
12.93 +// vim: tabstop=4 expandtab shiftwidth=4
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/memory/memory_incremental.h Sat Mar 27 22:12:12 2021 +0100
13.3 @@ -0,0 +1,40 @@
13.4 +#pragma once
13.5 +
13.6 +#include <systypes/base.h>
13.7 +
13.8 +#include <mutex>
13.9 +
13.10 +#include "memory.h"
13.11 +#include "memory_utils.h"
13.12 +
13.13 +
13.14 +
13.15 +/* A memory pool abstraction. */
13.16 +
13.17 +class MemoryIncremental : public Memory
13.18 +{
13.19 +protected:
13.20 + std::mutex _lock;
13.21 +
13.22 + unsigned int _limit;
13.23 + offset_t _region_size;
13.24 + bool _limited;
13.25 +
13.26 + Region *allocate(offset_t size);
13.27 +
13.28 +public:
13.29 + explicit MemoryIncremental(unsigned int limit, offset_t region_size=PAGE_SIZE);
13.30 +
13.31 + explicit MemoryIncremental();
13.32 +
13.33 + virtual Region *region(offset_t size);
13.34 +
13.35 + virtual Region *region();
13.36 +
13.37 + virtual offset_t region_size()
13.38 + { return _region_size; }
13.39 +
13.40 + virtual void release(Region *region);
13.41 +};
13.42 +
13.43 +// vim: tabstop=4 expandtab shiftwidth=4
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/memory/memory_preallocated.cc Sat Mar 27 22:12:12 2021 +0100
14.3 @@ -0,0 +1,46 @@
14.4 +#include "memory_preallocated.h"
14.5 +
14.6 +
14.7 +
14.8 +/* Initialise the memory pool with the given amount in bytes. */
14.9 +
14.10 +MemoryPreallocated::MemoryPreallocated(Memory *memory, offset_t amount)
14.11 +: _memory(memory), _amount(amount)
14.12 +{
14.13 + // NOTE: Handle allocation failure.
14.14 +
14.15 + offset_t remaining = amount;
14.16 +
14.17 + while (remaining)
14.18 + {
14.19 + _regions.push_back(memory->region());
14.20 +
14.21 + if (memory->region_size() >= remaining)
14.22 + break;
14.23 +
14.24 + remaining -= memory->region_size();
14.25 + }
14.26 +}
14.27 +
14.28 +/* Obtain an allocated region. */
14.29 +
14.30 +Region *MemoryPreallocated::region()
14.31 +{
14.32 + std::lock_guard<std::mutex> guard(_lock);
14.33 +
14.34 + Region *region = _regions.front();
14.35 +
14.36 + _regions.pop_front();
14.37 + return region;
14.38 +}
14.39 +
14.40 +/* Release the allocated 'region'. */
14.41 +
14.42 +void MemoryPreallocated::release(Region *region)
14.43 +{
14.44 + std::lock_guard<std::mutex> guard(_lock);
14.45 +
14.46 + _regions.push_back(region);
14.47 +}
14.48 +
14.49 +// vim: tabstop=4 expandtab shiftwidth=4
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/memory/memory_preallocated.h Sat Mar 27 22:12:12 2021 +0100
15.3 @@ -0,0 +1,36 @@
15.4 +#pragma once
15.5 +
15.6 +#include <systypes/base.h>
15.7 +
15.8 +#include <list>
15.9 +#include <mutex>
15.10 +
15.11 +#include "memory.h"
15.12 +
15.13 +
15.14 +
15.15 +/* A memory pool abstraction. */
15.16 +
15.17 +class MemoryPreallocated : public Memory
15.18 +{
15.19 +protected:
15.20 + std::mutex _lock;
15.21 + std::list<Region *> _regions;
15.22 +
15.23 + Memory *_memory;
15.24 + offset_t _amount;
15.25 +
15.26 +public:
15.27 + explicit MemoryPreallocated(Memory *memory, offset_t amount);
15.28 +
15.29 + explicit MemoryPreallocated();
15.30 +
15.31 + virtual Region *region();
15.32 +
15.33 + virtual offset_t region_size()
15.34 + { return _memory->region_size(); }
15.35 +
15.36 + virtual void release(Region *region);
15.37 +};
15.38 +
15.39 +// vim: tabstop=4 expandtab shiftwidth=4
16.1 --- a/page_collection.cc Sat Mar 27 01:42:25 2021 +0100
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,64 +0,0 @@
16.4 -#include "pages.h"
16.5 -
16.6 -PageCollection::PageCollection(Memory *memory)
16.7 -: _memory(memory)
16.8 -{
16.9 -}
16.10 -
16.11 -PageCollection::PageCollection()
16.12 -{
16.13 - _memory = new Memory();
16.14 -}
16.15 -
16.16 -/* Remove the first flexpage in the queue. If its owner exists, remove it from
16.17 - the owner (retiring the content). Return the flexpage for reuse. */
16.18 -
16.19 -Flexpage *PageCollection::remove()
16.20 -{
16.21 - PageOwner *owner;
16.22 - Flexpage *flexpage;
16.23 -
16.24 - _queue->pop(&owner, &flexpage);
16.25 -
16.26 - if (owner != NULL)
16.27 - owner->remove(flexpage);
16.28 -
16.29 - return flexpage;
16.30 -}
16.31 -
16.32 -/* Reserve 'flexpage' by removing it from this collection. */
16.33 -
16.34 -bool PageCollection::reserve(PageOwner *owner, Flexpage *flexpage)
16.35 -{
16.36 - return _queue->remove(owner, flexpage);
16.37 -}
16.38 -
16.39 -/* Obtain a new flexpage. Return the flexpage or None if no new flexpage could
16.40 - be created. */
16.41 -
16.42 -Flexpage *PageCollection::flexpage()
16.43 -{
16.44 - Region *region = _memory->region();
16.45 -
16.46 - if (region != NULL)
16.47 - return new Flexpage(region);
16.48 - else
16.49 - return NULL;
16.50 -}
16.51 -
16.52 -/* Queue an entry associating the given 'owner' and 'flexpage'. */
16.53 -
16.54 -void PageCollection::queue(PageOwner *owner, Flexpage *flexpage)
16.55 -{
16.56 - _queue->push(owner, flexpage);
16.57 -}
16.58 -
16.59 -/* Push an entry for 'flexpage' without owner association for immediate
16.60 - reuse. */
16.61 -
16.62 -void PageCollection::release(Flexpage *flexpage)
16.63 -{
16.64 - _queue->push_front(NULL, flexpage);
16.65 -}
16.66 -
16.67 -// vim: tabstop=4 expandtab shiftwidth=4
17.1 --- a/page_collection.h Sat Mar 27 01:42:25 2021 +0100
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,38 +0,0 @@
17.4 -#pragma once
17.5 -
17.6 -#include "flexpage.h"
17.7 -#include "memory.h"
17.8 -#include "page_owner.h"
17.9 -#include "page_queue.h"
17.10 -
17.11 -
17.12 -
17.13 -/* A page collection. */
17.14 -
17.15 -class PageCollection
17.16 -{
17.17 -protected:
17.18 - PageQueue *_queue;
17.19 - Memory *_memory;
17.20 -
17.21 -public:
17.22 - explicit PageCollection(Memory *memory);
17.23 -
17.24 - explicit PageCollection();
17.25 -
17.26 - virtual ~PageCollection()
17.27 - {
17.28 - }
17.29 -
17.30 - virtual Flexpage *remove();
17.31 -
17.32 - virtual bool reserve(PageOwner *owner, Flexpage *flexpage);
17.33 -
17.34 - virtual Flexpage *flexpage();
17.35 -
17.36 - virtual void queue(PageOwner *owner, Flexpage *flexpage);
17.37 -
17.38 - virtual void release(Flexpage *flexpage);
17.39 -};
17.40 -
17.41 -// vim: tabstop=4 expandtab shiftwidth=4
18.1 --- a/page_mapper.cc Sat Mar 27 01:42:25 2021 +0100
18.2 +++ b/page_mapper.cc Sat Mar 27 22:12:12 2021 +0100
18.3 @@ -3,7 +3,7 @@
18.4
18.5
18.6
18.7 -PageMapper::PageMapper(Accessor *accessor, PageCollection *pages)
18.8 +PageMapper::PageMapper(Accessor *accessor, Pages *pages)
18.9 : _accessor(accessor), _pages(pages), _attached(0)
18.10 {
18.11 }
19.1 --- a/page_mapper.h Sat Mar 27 01:42:25 2021 +0100
19.2 +++ b/page_mapper.h Sat Mar 27 22:12:12 2021 +0100
19.3 @@ -13,7 +13,7 @@
19.4 protected:
19.5 AccessMap _map;
19.6 Accessor *_accessor;
19.7 - PageCollection *_pages;
19.8 + Pages *_pages;
19.9 unsigned int _attached;
19.10 std::mutex _lock;
19.11
19.12 @@ -24,7 +24,7 @@
19.13 Flexpage *flexpage(offset_t offset);
19.14
19.15 public:
19.16 - explicit PageMapper(Accessor *accessor, PageCollection *pages);
19.17 + explicit PageMapper(Accessor *accessor, Pages *pages);
19.18
19.19 /* Accounting methods. */
19.20
20.1 --- a/page_queue.h Sat Mar 27 01:42:25 2021 +0100
20.2 +++ b/page_queue.h Sat Mar 27 22:12:12 2021 +0100
20.3 @@ -23,6 +23,10 @@
20.4 class PageQueue
20.5 {
20.6 public:
20.7 + virtual ~PageQueue()
20.8 + {
20.9 + }
20.10 +
20.11 virtual void pop(PageOwner **owner, Flexpage **flexpage) = 0;
20.12
20.13 virtual void push(PageOwner *owner, Flexpage *flexpage) = 0;
21.1 --- a/pages.cc Sat Mar 27 01:42:25 2021 +0100
21.2 +++ b/pages.cc Sat Mar 27 22:12:12 2021 +0100
21.3 @@ -1,15 +1,68 @@
21.4 +#include "memory_incremental.h"
21.5 #include "pages.h"
21.6
21.7 -Pages::Pages(Memory *memory)
21.8 -: PageCollection(memory)
21.9 +
21.10 +
21.11 +Pages::Pages(Memory *memory, PageQueue *queue)
21.12 +: _memory(memory), _queue(queue)
21.13 +{
21.14 +}
21.15 +
21.16 +Pages::Pages(PageQueue *queue)
21.17 +: _queue(queue)
21.18 {
21.19 - _queue = &_page_queue;
21.20 + _memory = new MemoryIncremental();
21.21 +}
21.22 +
21.23 +/* Remove the first flexpage in the queue. If its owner exists, remove it from
21.24 + the owner (retiring the content). Return the flexpage for reuse. */
21.25 +
21.26 +Flexpage *Pages::remove()
21.27 +{
21.28 + PageOwner *owner;
21.29 + Flexpage *flexpage;
21.30 +
21.31 + _queue->pop(&owner, &flexpage);
21.32 +
21.33 + if (owner != NULL)
21.34 + owner->remove(flexpage);
21.35 +
21.36 + return flexpage;
21.37 }
21.38
21.39 -Pages::Pages()
21.40 -: PageCollection()
21.41 +/* Reserve 'flexpage' by removing it from this collection. */
21.42 +
21.43 +bool Pages::reserve(PageOwner *owner, Flexpage *flexpage)
21.44 +{
21.45 + return _queue->remove(owner, flexpage);
21.46 +}
21.47 +
21.48 +/* Obtain a new flexpage. Return the flexpage or None if no new flexpage could
21.49 + be created. */
21.50 +
21.51 +Flexpage *Pages::flexpage()
21.52 {
21.53 - _queue = &_page_queue;
21.54 + Region *region = _memory->region();
21.55 +
21.56 + if (region != NULL)
21.57 + return new Flexpage(region);
21.58 + else
21.59 + return NULL;
21.60 +}
21.61 +
21.62 +/* Queue an entry associating the given 'owner' and 'flexpage'. */
21.63 +
21.64 +void Pages::queue(PageOwner *owner, Flexpage *flexpage)
21.65 +{
21.66 + _queue->push(owner, flexpage);
21.67 +}
21.68 +
21.69 +/* Push an entry for 'flexpage' without owner association for immediate
21.70 + reuse. */
21.71 +
21.72 +void Pages::release(Flexpage *flexpage)
21.73 +{
21.74 + _queue->push_front(NULL, flexpage);
21.75 }
21.76
21.77 // vim: tabstop=4 expandtab shiftwidth=4
22.1 --- a/pages.h Sat Mar 27 01:42:25 2021 +0100
22.2 +++ b/pages.h Sat Mar 27 22:12:12 2021 +0100
22.3 @@ -1,21 +1,38 @@
22.4 #pragma once
22.5
22.6 -#include "page_collection.h"
22.7 -#include "page_queue_shared.h"
22.8 +#include "flexpage.h"
22.9 +#include "memory.h"
22.10 +#include "page_owner.h"
22.11 +#include "page_queue.h"
22.12
22.13
22.14
22.15 /* A page collection. */
22.16
22.17 -class Pages : public PageCollection
22.18 +class Pages
22.19 {
22.20 protected:
22.21 - PageQueueShared _page_queue;
22.22 + Memory *_memory;
22.23 + PageQueue *_queue;
22.24
22.25 public:
22.26 - explicit Pages(Memory *memory);
22.27 + explicit Pages(Memory *memory, PageQueue *queue);
22.28 +
22.29 + explicit Pages(PageQueue *queue);
22.30 +
22.31 + virtual ~Pages()
22.32 + {
22.33 + }
22.34
22.35 - explicit Pages();
22.36 + virtual Flexpage *remove();
22.37 +
22.38 + virtual bool reserve(PageOwner *owner, Flexpage *flexpage);
22.39 +
22.40 + virtual Flexpage *flexpage();
22.41 +
22.42 + virtual void queue(PageOwner *owner, Flexpage *flexpage);
22.43 +
22.44 + virtual void release(Flexpage *flexpage);
22.45 };
22.46
22.47 // vim: tabstop=4 expandtab shiftwidth=4
23.1 --- a/pages_conserving.cc Sat Mar 27 01:42:25 2021 +0100
23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
23.3 @@ -1,75 +0,0 @@
23.4 -#include "pages_conserving.h"
23.5 -
23.6 -PagesConserving::PagesConserving(Memory *memory)
23.7 -: PageCollection(memory)
23.8 -{
23.9 - _queue = &_page_queue;
23.10 -}
23.11 -
23.12 -PagesConserving::PagesConserving()
23.13 -: PageCollection()
23.14 -{
23.15 - _queue = &_page_queue;
23.16 -}
23.17 -
23.18 -
23.19 -
23.20 -/* Refuse to obtain a new flexpage directly. All flexpages must be obtained from
23.21 - the page queue. */
23.22 -
23.23 -Flexpage *PagesConserving::flexpage()
23.24 -{
23.25 - return NULL;
23.26 -}
23.27 -
23.28 -
23.29 -
23.30 -/* Decrease the provision of flexpages to pipes. */
23.31 -
23.32 -bool PagesConserving::decrease(offset_t size)
23.33 -{
23.34 - // NOTE: Need to remove flexpages from the queue.
23.35 - // NOTE: This might need to happen incrementally in case some pages are not
23.36 - // NOTE: back in the queue for whatever reason.
23.37 -
23.38 - return true;
23.39 -}
23.40 -
23.41 -/* Increase the provision of flexpages to pipes, returning whether allocation
23.42 - succeeded. */
23.43 -
23.44 -bool PagesConserving::increase(offset_t size)
23.45 -{
23.46 - offset_t allocated_size = 0;
23.47 - std::list<Region *> allocated;
23.48 - std::list<Region *>::iterator it;
23.49 -
23.50 - /* Allocate regions for the defined increment value. */
23.51 -
23.52 - while (allocated_size < size)
23.53 - {
23.54 - Region *r = _memory->region();
23.55 -
23.56 - /* Free all allocated regions if not all regions can be allocated. */
23.57 -
23.58 - if (r == NULL)
23.59 - {
23.60 - for (it = allocated.begin(); it != allocated.end(); it++)
23.61 - _memory->release(r);
23.62 -
23.63 - return false;
23.64 - }
23.65 -
23.66 - allocated.push_back(r);
23.67 - allocated_size += r->size();
23.68 - }
23.69 -
23.70 - /* Queue flexpages for the regions. */
23.71 -
23.72 - for (it = allocated.begin(); it != allocated.end(); it++)
23.73 - _queue->push(NULL, new Flexpage(*it));
23.74 -
23.75 - return true;
23.76 -}
23.77 -
23.78 -// vim: tabstop=4 expandtab shiftwidth=4
24.1 --- a/pages_conserving.h Sat Mar 27 01:42:25 2021 +0100
24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
24.3 @@ -1,32 +0,0 @@
24.4 -#pragma once
24.5 -
24.6 -#include "page_collection.h"
24.7 -#include "page_queue_partitioned.h"
24.8 -
24.9 -
24.10 -
24.11 -/* A page collection where the pages are "conserved", meaning that they are not
24.12 - queued for reuse unless they are completely unused. */
24.13 -
24.14 -class PagesConserving : public PageCollection
24.15 -{
24.16 -protected:
24.17 - PageQueuePartitioned _page_queue;
24.18 -
24.19 -public:
24.20 - explicit PagesConserving(Memory *memory);
24.21 -
24.22 - explicit PagesConserving();
24.23 -
24.24 - /* Specialised methods. */
24.25 -
24.26 - virtual Flexpage *flexpage();
24.27 -
24.28 - /* Memory control methods. */
24.29 -
24.30 - virtual bool decrease(offset_t size);
24.31 -
24.32 - virtual bool increase(offset_t size);
24.33 -};
24.34 -
24.35 -// vim: tabstop=4 expandtab shiftwidth=4
25.1 --- a/pipes/pipe_opener_resource.cc Sat Mar 27 01:42:25 2021 +0100
25.2 +++ b/pipes/pipe_opener_resource.cc Sat Mar 27 22:12:12 2021 +0100
25.3 @@ -1,3 +1,4 @@
25.4 +#include "memory_incremental.h"
25.5 #include "pipe_opener_resource.h"
25.6 #include "pipe_opener_server.h"
25.7 #include "pipe_pager.h"
25.8 @@ -14,7 +15,7 @@
25.9
25.10 PipeOpenerResource::PipeOpenerResource()
25.11 {
25.12 - _memory = new Memory();
25.13 + _memory = new MemoryIncremental();
25.14 }
25.15
25.16 int PipeOpenerResource::expected_items()
26.1 --- a/pipes/pipe_pager.cc Sat Mar 27 01:42:25 2021 +0100
26.2 +++ b/pipes/pipe_pager.cc Sat Mar 27 22:12:12 2021 +0100
26.3 @@ -1,6 +1,8 @@
26.4 #include "pipe_pager.h"
26.5 #include "pipe_object_server.h"
26.6
26.7 +
26.8 +
26.9 /* Initialise a pager for a pipe with a shared page mapper for moderating
26.10 access to loaded pages. At first, no mapper will be configured: this must be
26.11 done by requesting a region. */
26.12 @@ -71,26 +73,12 @@
26.13
26.14 long PipePager::next_region_for_reader(offset_t *populated_size, offset_t *size)
26.15 {
26.16 - /* Obtain the next region if a current region is defined. */
26.17 -
26.18 - if (_mapper != NULL)
26.19 - {
26.20 - PageMapper *mapper = _paging->next_region();
26.21 -
26.22 - /* Return an error if no next region currently exists. */
26.23 + PageMapper *mapper = _paging->next_region();
26.24
26.25 - if (mapper == NULL)
26.26 - return -L4_EIO;
26.27 -
26.28 - _mapper = mapper;
26.29 - }
26.30 + if (mapper == NULL)
26.31 + return -L4_EIO;
26.32
26.33 - /* Obtain the first region if no mapper is defined. */
26.34 -
26.35 - else
26.36 - _mapper = _paging->first_region();
26.37 -
26.38 - /* Return the details of the now-current region. */
26.39 + _mapper = mapper;
26.40
26.41 return current_region(populated_size, size);
26.42 }
26.43 @@ -102,28 +90,16 @@
26.44 if (_mapper != NULL)
26.45 _mapper->set_data_size(*populated_size);
26.46
26.47 - /* A guaranteed amount of memory is reserved for the pipe. */
26.48 -
26.49 - PagesConserving *pages = _paging->pages();
26.50 + /* Obtain the page mapper for the region. */
26.51
26.52 - if (!pages->increase(_size))
26.53 - return -L4_ENOMEM;
26.54 -
26.55 - /* Set the page mapper for the region. */
26.56 + PageMapper *mapper = _paging->add_region();
26.57
26.58 - _mapper = new PageMapper(_paging->accessor(), pages);
26.59 - _mapper->attach();
26.60 -
26.61 - /* Record the mapper as the latest region in the accessor. */
26.62 -
26.63 - _paging->add_region(_mapper);
26.64 + if (mapper == NULL)
26.65 + return -L4_EIO;
26.66
26.67 - /* Set the region size to the allocated amount. */
26.68 + _mapper = mapper;
26.69
26.70 - *size = _size;
26.71 - *populated_size = 0;
26.72 -
26.73 - return L4_EOK;
26.74 + return current_region(populated_size, size);
26.75 }
26.76
26.77 // vim: tabstop=4 expandtab shiftwidth=4
27.1 --- a/pipes/pipe_paging.cc Sat Mar 27 01:42:25 2021 +0100
27.2 +++ b/pipes/pipe_paging.cc Sat Mar 27 22:12:12 2021 +0100
27.3 @@ -1,16 +1,35 @@
27.4 +#include "memory_incremental.h"
27.5 +#include "memory_preallocated.h"
27.6 +#include "page_queue_partitioned.h"
27.7 #include "pipe_paging.h"
27.8
27.9 +
27.10 +
27.11 PipePaging::PipePaging(Memory *memory, offset_t size)
27.12 : _memory(NULL), _size(size)
27.13 {
27.14 - _pages = new PagesConserving(memory);
27.15 + /* Reserve space for two pipe regions. */
27.16 +
27.17 + _memory = new MemoryPreallocated(memory, size * 2);
27.18 + _queue = new PageQueuePartitioned();
27.19 + _pages = new Pages(_memory, _queue);
27.20 +
27.21 + for (unsigned int i = 0; i < 2; i++)
27.22 + _regions[i] = NULL;
27.23 }
27.24
27.25 PipePaging::PipePaging(offset_t size)
27.26 : _size(size)
27.27 {
27.28 - _memory = new Memory();
27.29 - _pages = new PagesConserving(_memory);
27.30 + /* Reserve space for two pipe regions. */
27.31 +
27.32 + _memory_base = new MemoryIncremental();
27.33 + _memory = new MemoryPreallocated(_memory_base, size * 2);
27.34 + _queue = new PageQueuePartitioned();
27.35 + _pages = new Pages(_memory, _queue);
27.36 +
27.37 + for (unsigned int i = 0; i < 2; i++)
27.38 + _regions[i] = NULL;
27.39 }
27.40
27.41 /* Detach one endpoint. */
27.42 @@ -29,73 +48,90 @@
27.43
27.44 /* Discard all regions from the pipe. */
27.45
27.46 - while (!_regions.empty())
27.47 + for (unsigned int i = 0; i < 2; i++)
27.48 {
27.49 - PageMapper *mapper = _regions.front();
27.50 + PageMapper *mapper = _regions[i];
27.51
27.52 - _regions.pop_front();
27.53 - mapper->detach();
27.54 - delete mapper;
27.55 + if (mapper != NULL)
27.56 + {
27.57 + mapper->detach();
27.58 + _regions[i] = NULL;
27.59 + delete mapper;
27.60 + }
27.61 }
27.62
27.63 - /* Delete the page collection and memory object. */
27.64 + /* Delete the page collection and related objects. */
27.65
27.66 delete _pages;
27.67 + delete _queue;
27.68 + delete _memory;
27.69
27.70 - if (_memory != NULL)
27.71 - delete _memory;
27.72 + /* Delete any underlying memory object. */
27.73 +
27.74 + if (_memory_base != NULL)
27.75 + delete _memory_base;
27.76 }
27.77
27.78 /* Add a region to the sequence. */
27.79
27.80 -void PipePaging::add_region(PageMapper *mapper)
27.81 +PageMapper *PipePaging::add_region()
27.82 {
27.83 - _regions.push_back(mapper);
27.84 + /* If the writer already accesses a different region to the reader, no new
27.85 + region is added. */
27.86 +
27.87 + if (_writing != _reading)
27.88 + return NULL;
27.89 +
27.90 + /* Select the other region of the pair being maintained. */
27.91 +
27.92 + _writing = 1 - _writing;
27.93 +
27.94 + /* Make a new mapper for the region. */
27.95 +
27.96 + PageMapper *mapper = new PageMapper(&_accessors[_writing], _pages);
27.97 +
27.98 + /* Initialise and record the mapper. */
27.99 +
27.100 + mapper->attach();
27.101 + mapper->set_data_size(0);
27.102 +
27.103 + _regions[_writing] = mapper;
27.104 + return mapper;
27.105 }
27.106
27.107 -/* Return the first region in the sequence. */
27.108 +/* Return the current region for reading. */
27.109
27.110 -PageMapper *PipePaging::first_region()
27.111 +PageMapper *PipePaging::current_region()
27.112 {
27.113 - return _regions.front();
27.114 + return _regions[_reading];
27.115 }
27.116
27.117 -/* Return the next region for the reader. If only a single region remains, with
27.118 - the reader wishing to move to the next, return NULL. */
27.119 +/* Return the next region for the reader if the writer is using a different one.
27.120 + Otherwise, return NULL. */
27.121
27.122 PageMapper *PipePaging::next_region()
27.123 {
27.124 - if (_regions.size() > 1)
27.125 - {
27.126 - /* Discard the accessor from the current region. */
27.127 -
27.128 - if (_accessors.size() > _regions.size())
27.129 - _accessors.pop_front();
27.130 + /* If the reader already accesses the same region to the writer, no next
27.131 + region can be obtained. */
27.132
27.133 - /* Detach and discard the current page mapper. */
27.134 -
27.135 - PageMapper *mapper = _regions.front();
27.136 + if (_reading == _writing)
27.137 + return NULL;
27.138
27.139 - _regions.pop_front();
27.140 - mapper->detach();
27.141 - delete mapper;
27.142 + /* Detach and discard the current page mapper. */
27.143 +
27.144 + PageMapper *mapper = _regions[_reading];
27.145
27.146 - /* Return the next region. */
27.147 -
27.148 - return _regions.front();
27.149 + if (mapper != NULL)
27.150 + {
27.151 + mapper->detach();
27.152 + _regions[_reading] = NULL;
27.153 + delete mapper;
27.154 }
27.155 - else
27.156 - return NULL;
27.157 -}
27.158
27.159 -/* Initialise an accessor for a region. */
27.160 + /* Return the next region. */
27.161
27.162 -PipeAccessor *PipePaging::accessor()
27.163 -{
27.164 - PipeAccessor accessor;
27.165 -
27.166 - _accessors.push_back(accessor);
27.167 - return &_accessors.back();
27.168 + _reading = 1 - _reading;
27.169 + return _regions[_reading];
27.170 }
27.171
27.172 // vim: tabstop=4 expandtab shiftwidth=4
28.1 --- a/pipes/pipe_paging.h Sat Mar 27 01:42:25 2021 +0100
28.2 +++ b/pipes/pipe_paging.h Sat Mar 27 22:12:12 2021 +0100
28.3 @@ -1,9 +1,7 @@
28.4 #pragma once
28.5
28.6 -#include <list>
28.7 -
28.8 #include "page_mapper.h"
28.9 -#include "pages_conserving.h"
28.10 +#include "pages.h"
28.11 #include "pipe_accessor.h"
28.12
28.13 /* Pipe paging support, maintaining the sequence of active regions or sections
28.14 @@ -12,13 +10,18 @@
28.15 class PipePaging
28.16 {
28.17 protected:
28.18 - Memory *_memory;
28.19 - PagesConserving *_pages;
28.20 + Memory *_memory, *_memory_base;
28.21 + Pages *_pages;
28.22 + PageQueue *_queue;
28.23
28.24 /* Regions acting as files with their own accessors. */
28.25
28.26 - std::list<PageMapper *> _regions;
28.27 - std::list<PipeAccessor> _accessors;
28.28 + PageMapper *_regions[2];
28.29 + PipeAccessor _accessors[2];
28.30 +
28.31 + /* The first region is initially exposed to both reader and writer. */
28.32 +
28.33 + int _reading = 0, _writing = 0;
28.34
28.35 /* Pipe section/region size. */
28.36
28.37 @@ -35,21 +38,16 @@
28.38
28.39 virtual void detach();
28.40
28.41 - virtual PagesConserving *pages()
28.42 - { return _pages; }
28.43 -
28.44 virtual offset_t region_size()
28.45 { return _size; }
28.46
28.47 /* Region management. */
28.48
28.49 - virtual void add_region(PageMapper *mapper);
28.50 + virtual PageMapper *add_region();
28.51
28.52 - virtual PageMapper *first_region();
28.53 + virtual PageMapper *current_region();
28.54
28.55 virtual PageMapper *next_region();
28.56 -
28.57 - virtual PipeAccessor *accessor();
28.58 };
28.59
28.60 // vim: tabstop=4 expandtab shiftwidth=4
29.1 --- a/simple_pager.cc Sat Mar 27 01:42:25 2021 +0100
29.2 +++ b/simple_pager.cc Sat Mar 27 22:12:12 2021 +0100
29.3 @@ -1,6 +1,7 @@
29.4 #include <l4/re/c/dataspace.h>
29.5
29.6 #include "dataspace_server.h"
29.7 +#include "memory_incremental.h"
29.8 #include "ipc.h"
29.9 #include "simple_pager.h"
29.10
29.11 @@ -9,7 +10,7 @@
29.12 SimplePager::SimplePager(Memory *memory)
29.13 {
29.14 if (memory == NULL)
29.15 - _memory = new Memory();
29.16 + _memory = new MemoryIncremental();
29.17 else
29.18 _memory = memory;
29.19