1.1 --- a/Makefile Mon Mar 29 00:04:07 2021 +0200
1.2 +++ b/Makefile Mon Mar 29 00:56:08 2021 +0200
1.3 @@ -41,7 +41,7 @@
1.4
1.5 SERVER_INTERFACES_SRC_CC = $(call interfaces_to_server_cc,$(SERVER_INTERFACES_CC) $(COMP_INTERFACES_CC))
1.6
1.7 -COMMON_SRC_CC = memory_utils.cc
1.8 +COMMON_SRC_CC = memory/memory_utils.cc
1.9
1.10 PLAIN_SRC_CC_dstest_block_client = dstest_block_client.cc file.cc
1.11
1.12 @@ -55,10 +55,11 @@
1.13 access_map.cc accessing.cc accessor.cc \
1.14 flexpage.cc ipc.cc \
1.15 memory/memory_incremental.cc memory/memory_preallocated.cc \
1.16 + memory/region.cc \
1.17 page_mapper.cc pager.cc paging.cc \
1.18 - pages/page_queue.cc pages/page_queue_partitioned.cc pages/page_queue_shared.cc \
1.19 - pages/pages.cc \
1.20 - region.cc resource_server.cc simple_pager.cc
1.21 + pages/page_queue.cc pages/page_queue_partitioned.cc \
1.22 + pages/page_queue_shared.cc pages/pages.cc \
1.23 + resource_server.cc simple_pager.cc
1.24
1.25 PLAIN_SRC_CC_dstest_block_server = \
1.26 $(PLAIN_SRC_CC_common_server) \
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/memory/memory_utils.cc Mon Mar 29 00:56:08 2021 +0200
2.3 @@ -0,0 +1,111 @@
2.4 +#include "memory_utils.h"
2.5 +
2.6 +
2.7 +
2.8 +/* Return page 'n' for the configured page size. */
2.9 +
2.10 +offset_t page(unsigned int n)
2.11 +{
2.12 + return PAGE_SIZE * n;
2.13 +}
2.14 +
2.15 +/* Return the order of 'size', where 2 ** order yields the size. */
2.16 +
2.17 +unsigned int page_order(offset_t size)
2.18 +{
2.19 + /* Count zeros from the left, stopping at the first set bit, using the width
2.20 + of the size value (in bits, starting with the width in bytes) to
2.21 + calculate the position of this bit and thus the order of the value. */
2.22 +
2.23 + return sizeof(unsigned long) * 8 - 1 - __builtin_clzl(size);
2.24 +}
2.25 +
2.26 +/* Return 'value' rounded up to the nearest 'increment'. */
2.27 +
2.28 +offset_t round(offset_t value, offset_t increment)
2.29 +{
2.30 + return trunc(value + increment - 1, increment);
2.31 +}
2.32 +
2.33 +/* Return 'value' rounded up to the nearest multiple of 'increment'. */
2.34 +
2.35 +offset_t round_multiple(offset_t value, offset_t increment)
2.36 +{
2.37 + offset_t last = increment;
2.38 +
2.39 + while (1)
2.40 + {
2.41 + if (value < increment)
2.42 + return round(value, last);
2.43 +
2.44 + last = increment;
2.45 + increment *= 2;
2.46 + }
2.47 +}
2.48 +
2.49 +/* Return 'value' rounded down (or truncated) to the nearest 'increment'. */
2.50 +
2.51 +offset_t trunc(offset_t value, offset_t increment)
2.52 +{
2.53 + return (value / increment) * increment;
2.54 +}
2.55 +
2.56 +/* Return 'value' rounded down (or truncated) to the nearest multiple of
2.57 + 'increment'. */
2.58 +
2.59 +offset_t trunc_multiple(offset_t value, offset_t increment)
2.60 +{
2.61 + offset_t last = increment;
2.62 +
2.63 + while (1)
2.64 + {
2.65 + if (value < increment)
2.66 + return trunc(value, last);
2.67 +
2.68 + last = increment;
2.69 + increment *= 2;
2.70 + }
2.71 +}
2.72 +
2.73 +/* Find the maximum size aligned region within the region from 'start' to (but
2.74 + not including) 'end', with the given initial 'increment'. */
2.75 +
2.76 +offset_t max_multiple(offset_t start, offset_t end, offset_t increment)
2.77 +{
2.78 + /* The largest possible aligned region is derived from the region size. */
2.79 +
2.80 + offset_t size = trunc_multiple(end - start, increment);
2.81 +
2.82 + /* Apply the alignment to the start. */
2.83 +
2.84 + offset_t aligned = round(start, size);
2.85 +
2.86 + /* If the region is aligned, return the size. */
2.87 +
2.88 + if (aligned == start)
2.89 + return size;
2.90 +
2.91 + /* If the region is not aligned to the current size, recalculate the aligned
2.92 + size. */
2.93 +
2.94 + offset_t aligned_size;
2.95 +
2.96 + do
2.97 + {
2.98 + aligned_size = trunc_multiple(end - aligned, increment);
2.99 + size /= 2;
2.100 +
2.101 + /* Determine whether a smaller alignment could yield a larger aligned
2.102 + size. */
2.103 +
2.104 + if (aligned_size >= size)
2.105 + return aligned_size;
2.106 +
2.107 + aligned = round(start, size);
2.108 + }
2.109 + while (aligned > start);
2.110 +
2.111 + return aligned_size;
2.112 +}
2.113 +
2.114 +// vim: tabstop=4 expandtab shiftwidth=4
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/memory/memory_utils.h Mon Mar 29 00:56:08 2021 +0200
3.3 @@ -0,0 +1,25 @@
3.4 +#pragma once
3.5 +
3.6 +#include <systypes/base.h>
3.7 +
3.8 +#define PAGE_SIZE 4096
3.9 +
3.10 +
3.11 +
3.12 +/* Address arithmetic. */
3.13 +
3.14 +offset_t page(unsigned int n);
3.15 +
3.16 +unsigned int page_order(offset_t size);
3.17 +
3.18 +offset_t round(offset_t value, offset_t increment);
3.19 +
3.20 +offset_t round_multiple(offset_t value, offset_t increment);
3.21 +
3.22 +offset_t trunc(offset_t value, offset_t increment);
3.23 +
3.24 +offset_t trunc_multiple(offset_t value, offset_t increment);
3.25 +
3.26 +offset_t max_multiple(offset_t start, offset_t end, offset_t increment);
3.27 +
3.28 +// vim: tabstop=4 expandtab shiftwidth=4
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/memory/region.cc Mon Mar 29 00:56:08 2021 +0200
4.3 @@ -0,0 +1,83 @@
4.4 +#include <string.h>
4.5 +#include <stdlib.h>
4.6 +
4.7 +#include "region.h"
4.8 +
4.9 +
4.10 +
4.11 +/* Initialise region state, indicating the size, file and position. */
4.12 +
4.13 +RegionState::RegionState(unsigned long size, fileid_t fileid, offset_t filepos)
4.14 +: size(size), fileid(fileid), filepos(filepos)
4.15 +{
4.16 +}
4.17 +
4.18 +void RegionState::fill(fileid_t fileid, offset_t filepos)
4.19 +{
4.20 + this->fileid = fileid;
4.21 + this->filepos = filepos;
4.22 +}
4.23 +
4.24 +
4.25 +
4.26 +/* Initialise a region having the given 'start' and 'end' addresses, with the
4.27 + 'end' being one location beyond the last address in the region. */
4.28 +
4.29 +Region::Region(offset_t start, offset_t end)
4.30 +: start(start), end(end), state(end - start)
4.31 +{
4.32 + /* Content state. */
4.33 +
4.34 + memset((void *) start, 0, end - start);
4.35 +}
4.36 +
4.37 +Region::~Region()
4.38 +{
4.39 + free((void *) start);
4.40 +}
4.41 +
4.42 +offset_t Region::size()
4.43 +{
4.44 + return end - start;
4.45 +}
4.46 +
4.47 +/* Debugging methods. */
4.48 +
4.49 +int Region::compare(Region *other)
4.50 +{
4.51 + if (start < other->start)
4.52 + return -1;
4.53 + else if (start > other->start)
4.54 + return 1;
4.55 + else
4.56 + return 0;
4.57 +}
4.58 +
4.59 +void Region::fill(fileid_t fileid, offset_t filepos)
4.60 +{
4.61 + state.fill(fileid, filepos);
4.62 +}
4.63 +
4.64 +void Region::flush()
4.65 +{
4.66 +}
4.67 +
4.68 +/* Simulation methods. */
4.69 +
4.70 +char *Region::read(offset_t offset)
4.71 +{
4.72 + if (offset < size())
4.73 + return (char *) start + offset;
4.74 + else
4.75 + return NULL;
4.76 +}
4.77 +
4.78 +void Region::write(const char *data, offset_t offset)
4.79 +{
4.80 + size_t length = strlen(data);
4.81 +
4.82 + if (offset + length < size())
4.83 + memcpy((void *) (start + offset), data, length + 1);
4.84 +}
4.85 +
4.86 +// vim: tabstop=4 expandtab shiftwidth=4
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/memory/region.h Mon Mar 29 00:56:08 2021 +0200
5.3 @@ -0,0 +1,59 @@
5.4 +#pragma once
5.5 +
5.6 +#include <systypes/base.h>
5.7 +
5.8 +#include "types.h"
5.9 +
5.10 +
5.11 +
5.12 +/* Region-related state information. */
5.13 +
5.14 +class RegionState
5.15 +{
5.16 +public:
5.17 + unsigned long size;
5.18 + fileid_t fileid;
5.19 + offset_t filepos;
5.20 +
5.21 + explicit RegionState(unsigned long size=0, fileid_t fileid=0, offset_t filepos=0);
5.22 +
5.23 + void fill(fileid_t fileid, offset_t filepos);
5.24 +
5.25 + bool valid() { return size != 0; }
5.26 +};
5.27 +
5.28 +
5.29 +
5.30 +/* A memory region abstraction. */
5.31 +
5.32 +class Region
5.33 +{
5.34 +public:
5.35 + offset_t start, end;
5.36 +
5.37 + /* Debugging information. */
5.38 +
5.39 + RegionState state;
5.40 +
5.41 + /* Methods. */
5.42 +
5.43 + explicit Region(offset_t start, offset_t end);
5.44 +
5.45 + virtual ~Region();
5.46 +
5.47 + offset_t size();
5.48 +
5.49 + int compare(Region *other);
5.50 +
5.51 + void fill(fileid_t fileid, offset_t filepos);
5.52 +
5.53 + void flush();
5.54 +
5.55 + /* Simulation methods. */
5.56 +
5.57 + char *read(offset_t offset=0);
5.58 +
5.59 + void write(const char *data, offset_t offset=0);
5.60 +};
5.61 +
5.62 +// vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/memory_utils.cc Mon Mar 29 00:04:07 2021 +0200
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,111 +0,0 @@
6.4 -#include "memory_utils.h"
6.5 -
6.6 -
6.7 -
6.8 -/* Return page 'n' for the configured page size. */
6.9 -
6.10 -offset_t page(unsigned int n)
6.11 -{
6.12 - return PAGE_SIZE * n;
6.13 -}
6.14 -
6.15 -/* Return the order of 'size', where 2 ** order yields the size. */
6.16 -
6.17 -unsigned int page_order(offset_t size)
6.18 -{
6.19 - /* Count zeros from the left, stopping at the first set bit, using the width
6.20 - of the size value (in bits, starting with the width in bytes) to
6.21 - calculate the position of this bit and thus the order of the value. */
6.22 -
6.23 - return sizeof(unsigned long) * 8 - 1 - __builtin_clzl(size);
6.24 -}
6.25 -
6.26 -/* Return 'value' rounded up to the nearest 'increment'. */
6.27 -
6.28 -offset_t round(offset_t value, offset_t increment)
6.29 -{
6.30 - return trunc(value + increment - 1, increment);
6.31 -}
6.32 -
6.33 -/* Return 'value' rounded up to the nearest multiple of 'increment'. */
6.34 -
6.35 -offset_t round_multiple(offset_t value, offset_t increment)
6.36 -{
6.37 - offset_t last = increment;
6.38 -
6.39 - while (1)
6.40 - {
6.41 - if (value < increment)
6.42 - return round(value, last);
6.43 -
6.44 - last = increment;
6.45 - increment *= 2;
6.46 - }
6.47 -}
6.48 -
6.49 -/* Return 'value' rounded down (or truncated) to the nearest 'increment'. */
6.50 -
6.51 -offset_t trunc(offset_t value, offset_t increment)
6.52 -{
6.53 - return (value / increment) * increment;
6.54 -}
6.55 -
6.56 -/* Return 'value' rounded down (or truncated) to the nearest multiple of
6.57 - 'increment'. */
6.58 -
6.59 -offset_t trunc_multiple(offset_t value, offset_t increment)
6.60 -{
6.61 - offset_t last = increment;
6.62 -
6.63 - while (1)
6.64 - {
6.65 - if (value < increment)
6.66 - return trunc(value, last);
6.67 -
6.68 - last = increment;
6.69 - increment *= 2;
6.70 - }
6.71 -}
6.72 -
6.73 -/* Find the maximum size aligned region within the region from 'start' to (but
6.74 - not including) 'end', with the given initial 'increment'. */
6.75 -
6.76 -offset_t max_multiple(offset_t start, offset_t end, offset_t increment)
6.77 -{
6.78 - /* The largest possible aligned region is derived from the region size. */
6.79 -
6.80 - offset_t size = trunc_multiple(end - start, increment);
6.81 -
6.82 - /* Apply the alignment to the start. */
6.83 -
6.84 - offset_t aligned = round(start, size);
6.85 -
6.86 - /* If the region is aligned, return the size. */
6.87 -
6.88 - if (aligned == start)
6.89 - return size;
6.90 -
6.91 - /* If the region is not aligned to the current size, recalculate the aligned
6.92 - size. */
6.93 -
6.94 - offset_t aligned_size;
6.95 -
6.96 - do
6.97 - {
6.98 - aligned_size = trunc_multiple(end - aligned, increment);
6.99 - size /= 2;
6.100 -
6.101 - /* Determine whether a smaller alignment could yield a larger aligned
6.102 - size. */
6.103 -
6.104 - if (aligned_size >= size)
6.105 - return aligned_size;
6.106 -
6.107 - aligned = round(start, size);
6.108 - }
6.109 - while (aligned > start);
6.110 -
6.111 - return aligned_size;
6.112 -}
6.113 -
6.114 -// vim: tabstop=4 expandtab shiftwidth=4
7.1 --- a/memory_utils.h Mon Mar 29 00:04:07 2021 +0200
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,25 +0,0 @@
7.4 -#pragma once
7.5 -
7.6 -#include <systypes/base.h>
7.7 -
7.8 -#define PAGE_SIZE 4096
7.9 -
7.10 -
7.11 -
7.12 -/* Address arithmetic. */
7.13 -
7.14 -offset_t page(unsigned int n);
7.15 -
7.16 -unsigned int page_order(offset_t size);
7.17 -
7.18 -offset_t round(offset_t value, offset_t increment);
7.19 -
7.20 -offset_t round_multiple(offset_t value, offset_t increment);
7.21 -
7.22 -offset_t trunc(offset_t value, offset_t increment);
7.23 -
7.24 -offset_t trunc_multiple(offset_t value, offset_t increment);
7.25 -
7.26 -offset_t max_multiple(offset_t start, offset_t end, offset_t increment);
7.27 -
7.28 -// vim: tabstop=4 expandtab shiftwidth=4
8.1 --- a/region.cc Mon Mar 29 00:04:07 2021 +0200
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,83 +0,0 @@
8.4 -#include <string.h>
8.5 -#include <stdlib.h>
8.6 -
8.7 -#include "region.h"
8.8 -
8.9 -
8.10 -
8.11 -/* Initialise region state, indicating the size, file and position. */
8.12 -
8.13 -RegionState::RegionState(unsigned long size, fileid_t fileid, offset_t filepos)
8.14 -: size(size), fileid(fileid), filepos(filepos)
8.15 -{
8.16 -}
8.17 -
8.18 -void RegionState::fill(fileid_t fileid, offset_t filepos)
8.19 -{
8.20 - this->fileid = fileid;
8.21 - this->filepos = filepos;
8.22 -}
8.23 -
8.24 -
8.25 -
8.26 -/* Initialise a region having the given 'start' and 'end' addresses, with the
8.27 - 'end' being one location beyond the last address in the region. */
8.28 -
8.29 -Region::Region(offset_t start, offset_t end)
8.30 -: start(start), end(end), state(end - start)
8.31 -{
8.32 - /* Content state. */
8.33 -
8.34 - memset((void *) start, 0, end - start);
8.35 -}
8.36 -
8.37 -Region::~Region()
8.38 -{
8.39 - free((void *) start);
8.40 -}
8.41 -
8.42 -offset_t Region::size()
8.43 -{
8.44 - return end - start;
8.45 -}
8.46 -
8.47 -/* Debugging methods. */
8.48 -
8.49 -int Region::compare(Region *other)
8.50 -{
8.51 - if (start < other->start)
8.52 - return -1;
8.53 - else if (start > other->start)
8.54 - return 1;
8.55 - else
8.56 - return 0;
8.57 -}
8.58 -
8.59 -void Region::fill(fileid_t fileid, offset_t filepos)
8.60 -{
8.61 - state.fill(fileid, filepos);
8.62 -}
8.63 -
8.64 -void Region::flush()
8.65 -{
8.66 -}
8.67 -
8.68 -/* Simulation methods. */
8.69 -
8.70 -char *Region::read(offset_t offset)
8.71 -{
8.72 - if (offset < size())
8.73 - return (char *) start + offset;
8.74 - else
8.75 - return NULL;
8.76 -}
8.77 -
8.78 -void Region::write(const char *data, offset_t offset)
8.79 -{
8.80 - size_t length = strlen(data);
8.81 -
8.82 - if (offset + length < size())
8.83 - memcpy((void *) (start + offset), data, length + 1);
8.84 -}
8.85 -
8.86 -// vim: tabstop=4 expandtab shiftwidth=4
9.1 --- a/region.h Mon Mar 29 00:04:07 2021 +0200
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,59 +0,0 @@
9.4 -#pragma once
9.5 -
9.6 -#include <systypes/base.h>
9.7 -
9.8 -#include "types.h"
9.9 -
9.10 -
9.11 -
9.12 -/* Region-related state information. */
9.13 -
9.14 -class RegionState
9.15 -{
9.16 -public:
9.17 - unsigned long size;
9.18 - fileid_t fileid;
9.19 - offset_t filepos;
9.20 -
9.21 - explicit RegionState(unsigned long size=0, fileid_t fileid=0, offset_t filepos=0);
9.22 -
9.23 - void fill(fileid_t fileid, offset_t filepos);
9.24 -
9.25 - bool valid() { return size != 0; }
9.26 -};
9.27 -
9.28 -
9.29 -
9.30 -/* A memory region abstraction. */
9.31 -
9.32 -class Region
9.33 -{
9.34 -public:
9.35 - offset_t start, end;
9.36 -
9.37 - /* Debugging information. */
9.38 -
9.39 - RegionState state;
9.40 -
9.41 - /* Methods. */
9.42 -
9.43 - explicit Region(offset_t start, offset_t end);
9.44 -
9.45 - virtual ~Region();
9.46 -
9.47 - offset_t size();
9.48 -
9.49 - int compare(Region *other);
9.50 -
9.51 - void fill(fileid_t fileid, offset_t filepos);
9.52 -
9.53 - void flush();
9.54 -
9.55 - /* Simulation methods. */
9.56 -
9.57 - char *read(offset_t offset=0);
9.58 -
9.59 - void write(const char *data, offset_t offset=0);
9.60 -};
9.61 -
9.62 -// vim: tabstop=4 expandtab shiftwidth=4