# HG changeset patch # User Paul Boddie # Date 1616972168 -7200 # Node ID 158f806252eb0ddeeac17f0d993b75aa27782043 # Parent 710f4e5ca27c07d9e04dfd9642a1c1e560a6a370 Moved more memory-related functionality into the memory subdirectory. diff -r 710f4e5ca27c -r 158f806252eb Makefile --- a/Makefile Mon Mar 29 00:04:07 2021 +0200 +++ b/Makefile Mon Mar 29 00:56:08 2021 +0200 @@ -41,7 +41,7 @@ SERVER_INTERFACES_SRC_CC = $(call interfaces_to_server_cc,$(SERVER_INTERFACES_CC) $(COMP_INTERFACES_CC)) -COMMON_SRC_CC = memory_utils.cc +COMMON_SRC_CC = memory/memory_utils.cc PLAIN_SRC_CC_dstest_block_client = dstest_block_client.cc file.cc @@ -55,10 +55,11 @@ access_map.cc accessing.cc accessor.cc \ flexpage.cc ipc.cc \ memory/memory_incremental.cc memory/memory_preallocated.cc \ + memory/region.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 + pages/page_queue.cc pages/page_queue_partitioned.cc \ + pages/page_queue_shared.cc pages/pages.cc \ + resource_server.cc simple_pager.cc PLAIN_SRC_CC_dstest_block_server = \ $(PLAIN_SRC_CC_common_server) \ diff -r 710f4e5ca27c -r 158f806252eb memory/memory_utils.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memory/memory_utils.cc Mon Mar 29 00:56:08 2021 +0200 @@ -0,0 +1,111 @@ +#include "memory_utils.h" + + + +/* Return page 'n' for the configured page size. */ + +offset_t page(unsigned int n) +{ + return PAGE_SIZE * n; +} + +/* Return the order of 'size', where 2 ** order yields the size. */ + +unsigned int page_order(offset_t size) +{ + /* Count zeros from the left, stopping at the first set bit, using the width + of the size value (in bits, starting with the width in bytes) to + calculate the position of this bit and thus the order of the value. */ + + return sizeof(unsigned long) * 8 - 1 - __builtin_clzl(size); +} + +/* Return 'value' rounded up to the nearest 'increment'. */ + +offset_t round(offset_t value, offset_t increment) +{ + return trunc(value + increment - 1, increment); +} + +/* Return 'value' rounded up to the nearest multiple of 'increment'. */ + +offset_t round_multiple(offset_t value, offset_t increment) +{ + offset_t last = increment; + + while (1) + { + if (value < increment) + return round(value, last); + + last = increment; + increment *= 2; + } +} + +/* Return 'value' rounded down (or truncated) to the nearest 'increment'. */ + +offset_t trunc(offset_t value, offset_t increment) +{ + return (value / increment) * increment; +} + +/* Return 'value' rounded down (or truncated) to the nearest multiple of + 'increment'. */ + +offset_t trunc_multiple(offset_t value, offset_t increment) +{ + offset_t last = increment; + + while (1) + { + if (value < increment) + return trunc(value, last); + + last = increment; + increment *= 2; + } +} + +/* Find the maximum size aligned region within the region from 'start' to (but + not including) 'end', with the given initial 'increment'. */ + +offset_t max_multiple(offset_t start, offset_t end, offset_t increment) +{ + /* The largest possible aligned region is derived from the region size. */ + + offset_t size = trunc_multiple(end - start, increment); + + /* Apply the alignment to the start. */ + + offset_t aligned = round(start, size); + + /* If the region is aligned, return the size. */ + + if (aligned == start) + return size; + + /* If the region is not aligned to the current size, recalculate the aligned + size. */ + + offset_t aligned_size; + + do + { + aligned_size = trunc_multiple(end - aligned, increment); + size /= 2; + + /* Determine whether a smaller alignment could yield a larger aligned + size. */ + + if (aligned_size >= size) + return aligned_size; + + aligned = round(start, size); + } + while (aligned > start); + + return aligned_size; +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 710f4e5ca27c -r 158f806252eb memory/memory_utils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memory/memory_utils.h Mon Mar 29 00:56:08 2021 +0200 @@ -0,0 +1,25 @@ +#pragma once + +#include + +#define PAGE_SIZE 4096 + + + +/* Address arithmetic. */ + +offset_t page(unsigned int n); + +unsigned int page_order(offset_t size); + +offset_t round(offset_t value, offset_t increment); + +offset_t round_multiple(offset_t value, offset_t increment); + +offset_t trunc(offset_t value, offset_t increment); + +offset_t trunc_multiple(offset_t value, offset_t increment); + +offset_t max_multiple(offset_t start, offset_t end, offset_t increment); + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 710f4e5ca27c -r 158f806252eb memory/region.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memory/region.cc Mon Mar 29 00:56:08 2021 +0200 @@ -0,0 +1,83 @@ +#include +#include + +#include "region.h" + + + +/* Initialise region state, indicating the size, file and position. */ + +RegionState::RegionState(unsigned long size, fileid_t fileid, offset_t filepos) +: size(size), fileid(fileid), filepos(filepos) +{ +} + +void RegionState::fill(fileid_t fileid, offset_t filepos) +{ + this->fileid = fileid; + this->filepos = filepos; +} + + + +/* Initialise a region having the given 'start' and 'end' addresses, with the + 'end' being one location beyond the last address in the region. */ + +Region::Region(offset_t start, offset_t end) +: start(start), end(end), state(end - start) +{ + /* Content state. */ + + memset((void *) start, 0, end - start); +} + +Region::~Region() +{ + free((void *) start); +} + +offset_t Region::size() +{ + return end - start; +} + +/* Debugging methods. */ + +int Region::compare(Region *other) +{ + if (start < other->start) + return -1; + else if (start > other->start) + return 1; + else + return 0; +} + +void Region::fill(fileid_t fileid, offset_t filepos) +{ + state.fill(fileid, filepos); +} + +void Region::flush() +{ +} + +/* Simulation methods. */ + +char *Region::read(offset_t offset) +{ + if (offset < size()) + return (char *) start + offset; + else + return NULL; +} + +void Region::write(const char *data, offset_t offset) +{ + size_t length = strlen(data); + + if (offset + length < size()) + memcpy((void *) (start + offset), data, length + 1); +} + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 710f4e5ca27c -r 158f806252eb memory/region.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/memory/region.h Mon Mar 29 00:56:08 2021 +0200 @@ -0,0 +1,59 @@ +#pragma once + +#include + +#include "types.h" + + + +/* Region-related state information. */ + +class RegionState +{ +public: + unsigned long size; + fileid_t fileid; + offset_t filepos; + + explicit RegionState(unsigned long size=0, fileid_t fileid=0, offset_t filepos=0); + + void fill(fileid_t fileid, offset_t filepos); + + bool valid() { return size != 0; } +}; + + + +/* A memory region abstraction. */ + +class Region +{ +public: + offset_t start, end; + + /* Debugging information. */ + + RegionState state; + + /* Methods. */ + + explicit Region(offset_t start, offset_t end); + + virtual ~Region(); + + offset_t size(); + + int compare(Region *other); + + void fill(fileid_t fileid, offset_t filepos); + + void flush(); + + /* Simulation methods. */ + + char *read(offset_t offset=0); + + void write(const char *data, offset_t offset=0); +}; + +// vim: tabstop=4 expandtab shiftwidth=4 diff -r 710f4e5ca27c -r 158f806252eb memory_utils.cc --- a/memory_utils.cc Mon Mar 29 00:04:07 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -#include "memory_utils.h" - - - -/* Return page 'n' for the configured page size. */ - -offset_t page(unsigned int n) -{ - return PAGE_SIZE * n; -} - -/* Return the order of 'size', where 2 ** order yields the size. */ - -unsigned int page_order(offset_t size) -{ - /* Count zeros from the left, stopping at the first set bit, using the width - of the size value (in bits, starting with the width in bytes) to - calculate the position of this bit and thus the order of the value. */ - - return sizeof(unsigned long) * 8 - 1 - __builtin_clzl(size); -} - -/* Return 'value' rounded up to the nearest 'increment'. */ - -offset_t round(offset_t value, offset_t increment) -{ - return trunc(value + increment - 1, increment); -} - -/* Return 'value' rounded up to the nearest multiple of 'increment'. */ - -offset_t round_multiple(offset_t value, offset_t increment) -{ - offset_t last = increment; - - while (1) - { - if (value < increment) - return round(value, last); - - last = increment; - increment *= 2; - } -} - -/* Return 'value' rounded down (or truncated) to the nearest 'increment'. */ - -offset_t trunc(offset_t value, offset_t increment) -{ - return (value / increment) * increment; -} - -/* Return 'value' rounded down (or truncated) to the nearest multiple of - 'increment'. */ - -offset_t trunc_multiple(offset_t value, offset_t increment) -{ - offset_t last = increment; - - while (1) - { - if (value < increment) - return trunc(value, last); - - last = increment; - increment *= 2; - } -} - -/* Find the maximum size aligned region within the region from 'start' to (but - not including) 'end', with the given initial 'increment'. */ - -offset_t max_multiple(offset_t start, offset_t end, offset_t increment) -{ - /* The largest possible aligned region is derived from the region size. */ - - offset_t size = trunc_multiple(end - start, increment); - - /* Apply the alignment to the start. */ - - offset_t aligned = round(start, size); - - /* If the region is aligned, return the size. */ - - if (aligned == start) - return size; - - /* If the region is not aligned to the current size, recalculate the aligned - size. */ - - offset_t aligned_size; - - do - { - aligned_size = trunc_multiple(end - aligned, increment); - size /= 2; - - /* Determine whether a smaller alignment could yield a larger aligned - size. */ - - if (aligned_size >= size) - return aligned_size; - - aligned = round(start, size); - } - while (aligned > start); - - return aligned_size; -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 710f4e5ca27c -r 158f806252eb memory_utils.h --- a/memory_utils.h Mon Mar 29 00:04:07 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -#pragma once - -#include - -#define PAGE_SIZE 4096 - - - -/* Address arithmetic. */ - -offset_t page(unsigned int n); - -unsigned int page_order(offset_t size); - -offset_t round(offset_t value, offset_t increment); - -offset_t round_multiple(offset_t value, offset_t increment); - -offset_t trunc(offset_t value, offset_t increment); - -offset_t trunc_multiple(offset_t value, offset_t increment); - -offset_t max_multiple(offset_t start, offset_t end, offset_t increment); - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 710f4e5ca27c -r 158f806252eb region.cc --- a/region.cc Mon Mar 29 00:04:07 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -#include -#include - -#include "region.h" - - - -/* Initialise region state, indicating the size, file and position. */ - -RegionState::RegionState(unsigned long size, fileid_t fileid, offset_t filepos) -: size(size), fileid(fileid), filepos(filepos) -{ -} - -void RegionState::fill(fileid_t fileid, offset_t filepos) -{ - this->fileid = fileid; - this->filepos = filepos; -} - - - -/* Initialise a region having the given 'start' and 'end' addresses, with the - 'end' being one location beyond the last address in the region. */ - -Region::Region(offset_t start, offset_t end) -: start(start), end(end), state(end - start) -{ - /* Content state. */ - - memset((void *) start, 0, end - start); -} - -Region::~Region() -{ - free((void *) start); -} - -offset_t Region::size() -{ - return end - start; -} - -/* Debugging methods. */ - -int Region::compare(Region *other) -{ - if (start < other->start) - return -1; - else if (start > other->start) - return 1; - else - return 0; -} - -void Region::fill(fileid_t fileid, offset_t filepos) -{ - state.fill(fileid, filepos); -} - -void Region::flush() -{ -} - -/* Simulation methods. */ - -char *Region::read(offset_t offset) -{ - if (offset < size()) - return (char *) start + offset; - else - return NULL; -} - -void Region::write(const char *data, offset_t offset) -{ - size_t length = strlen(data); - - if (offset + length < size()) - memcpy((void *) (start + offset), data, length + 1); -} - -// vim: tabstop=4 expandtab shiftwidth=4 diff -r 710f4e5ca27c -r 158f806252eb region.h --- a/region.h Mon Mar 29 00:04:07 2021 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -#pragma once - -#include - -#include "types.h" - - - -/* Region-related state information. */ - -class RegionState -{ -public: - unsigned long size; - fileid_t fileid; - offset_t filepos; - - explicit RegionState(unsigned long size=0, fileid_t fileid=0, offset_t filepos=0); - - void fill(fileid_t fileid, offset_t filepos); - - bool valid() { return size != 0; } -}; - - - -/* A memory region abstraction. */ - -class Region -{ -public: - offset_t start, end; - - /* Debugging information. */ - - RegionState state; - - /* Methods. */ - - explicit Region(offset_t start, offset_t end); - - virtual ~Region(); - - offset_t size(); - - int compare(Region *other); - - void fill(fileid_t fileid, offset_t filepos); - - void flush(); - - /* Simulation methods. */ - - char *read(offset_t offset=0); - - void write(const char *data, offset_t offset=0); -}; - -// vim: tabstop=4 expandtab shiftwidth=4