summaryrefslogtreecommitdiff
path: root/src/cache/backings
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-04-30 17:42:08 -0400
committerAndrew Opalach <andrew@akon.city> 2025-04-30 17:42:08 -0400
commit2ce402fa41508d45e2d30b56502c00ef92efff7b (patch)
tree63f4701b292dfcbe08af1aeb3a5942c1973c45ba /src/cache/backings
parentaf54e6510f2f701db3b3a533514076c04cea4c66 (diff)
downloadcamu-2ce402fa41508d45e2d30b56502c00ef92efff7b.tar.gz
camu-2ce402fa41508d45e2d30b56502c00ef92efff7b.tar.bz2
camu-2ce402fa41508d45e2d30b56502c00ef92efff7b.zip
Refactor the way cache backing sizes are tracked
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'src/cache/backings')
-rw-r--r--src/cache/backings/file.c60
-rw-r--r--src/cache/backings/file.h1
-rw-r--r--src/cache/backings/file_common.h28
-rw-r--r--src/cache/backings/file_mapped.c41
-rw-r--r--src/cache/backings/memory.c65
-rw-r--r--src/cache/backings/memory.h4
6 files changed, 121 insertions, 78 deletions
diff --git a/src/cache/backings/file.c b/src/cache/backings/file.c
index 500e16f..06cc600 100644
--- a/src/cache/backings/file.c
+++ b/src/cache/backings/file.c
@@ -7,40 +7,48 @@ static void file_backing_lock(struct cch_backing *backing)
nn_mutex_lock(&file->mutex);
}
-static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *size)
+static void maybe_seek_to_index(struct cch_backing_file *file, off_t index)
{
- struct cch_backing_file *file = (struct cch_backing_file *)backing;
- nn_mutex_lock(&file->mutex);
if (file->u.pointer != index) {
file->u.pointer = nn_file_seek(&file->file, index, SEEK_SET);
al_assert(file->u.pointer == index);
}
- off_t n = (off_t)*size;
- if (file->size >= 0 && index + n >= file->size) {
- n = MAX(file->size - index, (off_t)0);
+}
+
+static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *count)
+{
+ struct cch_backing_file *file = (struct cch_backing_file *)backing;
+ off_t n = (off_t)*count;
+ nn_mutex_lock(&file->mutex);
+ maybe_seek_to_index(file, index);
+ off_t size = file->backing.size;
+ if (size > 0 && index + n >= size) {
+ n = MAX(size - index, (off_t)0);
+ }
+ if (n > 0) {
+ nn_file_write(&file->file, buf, n);
+ file->u.pointer += n;
+ cch_backing_fill_range(&file->backing, index, n);
}
- nn_file_write(&file->file, buf, n);
- file->u.pointer += n;
- cch_backing_fill_range(&file->backing, index, n);
- *size = (size_t)n;
+ *count = (size_t)n;
nn_mutex_unlock(&file->mutex);
}
-static void file_backing_read(struct cch_backing *backing, u8 *buf, off_t index, size_t *size)
+static void file_backing_read(struct cch_backing *backing, u8 *buf, off_t index, size_t *count)
{
struct cch_backing_file *file = (struct cch_backing_file *)backing;
+ off_t n = (off_t)*count;
nn_mutex_lock(&file->mutex);
- if (file->u.pointer != index) {
- file->u.pointer = nn_file_seek(&file->file, index, SEEK_SET);
- al_assert(file->u.pointer == index);
+ maybe_seek_to_index(file, index);
+ off_t size = file->backing.size;
+ if (size > 0 && index + n >= size) {
+ n = MAX(size - index, (off_t)0);
}
- off_t n = (off_t)*size;
- if (file->size >= 0 && index + n >= file->size) {
- n = MAX(file->size - index, (off_t)0);
+ if (n > 0) {
+ nn_file_read(&file->file, buf, n);
+ file->u.pointer += n;
}
- nn_file_read(&file->file, buf, n);
- file->u.pointer += n;
- *size = (size_t)n;
+ *count = (size_t)n;
nn_mutex_unlock(&file->mutex);
}
@@ -50,12 +58,12 @@ static void file_backing_unlock(struct cch_backing *backing)
nn_mutex_unlock(&file->mutex);
}
-static void file_backing_resize(struct cch_backing *backing, size_t size)
+static void file_backing_set_size(struct cch_backing *backing, off_t size, bool expand_to_size)
{
struct cch_backing_file *file = (struct cch_backing_file *)backing;
nn_mutex_lock(&file->mutex);
- file->size = size;
- if (size > file->file.size) {
+ file->backing.size = size;
+ if (expand_to_size && (size_t)size > file->file.size) {
nn_file_truncate(&file->file, size);
}
nn_mutex_unlock(&file->mutex);
@@ -74,13 +82,15 @@ struct cch_backing *cch_backing_file_create(str *path, size_t size)
{
struct cch_backing_file *file = al_alloc_object(struct cch_backing_file);
file->backing.mode = CACHE_BACKING_READ;
+ file->backing.size = -1;
file->backing.lock = file_backing_lock;
file->backing.write = file_backing_write;
file->backing.read = file_backing_read;
file->backing.get_ptr = NULL;
file->backing.unlock = file_backing_unlock;
- file->backing.get_size_estimate = file_backing_get_size_estimate;
- file->backing.resize = file_backing_resize;
+ file->backing.set_size = file_backing_set_size;
+ file->backing.get_size_if_known = file_backing_get_size_if_known;
+ file->backing.finalize = file_backing_finalize;
file->backing.free = file_backing_free;
al_array_init(file->backing.available);
if (!file_open_internal(file, path, size)) {
diff --git a/src/cache/backings/file.h b/src/cache/backings/file.h
index 06daac9..361aad6 100644
--- a/src/cache/backings/file.h
+++ b/src/cache/backings/file.h
@@ -10,7 +10,6 @@
struct cch_backing_file {
struct cch_backing backing;
struct nn_file file;
- off_t size;
union {
off_t pointer; // CACHE_BACKING_READ
void *map; // CACHE_BACKING_MAPPED
diff --git a/src/cache/backings/file_common.h b/src/cache/backings/file_common.h
index 3f4ed3b..936babe 100644
--- a/src/cache/backings/file_common.h
+++ b/src/cache/backings/file_common.h
@@ -7,29 +7,33 @@
AL_IGNORE_WARNING("-Wunused-function")
-static off_t file_backing_get_size_estimate(struct cch_backing *backing)
+static off_t file_backing_get_size_if_known(struct cch_backing *backing)
{
struct cch_backing_file *file = (struct cch_backing_file *)backing;
nn_mutex_lock(&file->mutex);
- off_t size = file->size;
+ off_t size = file->backing.size;
nn_mutex_unlock(&file->mutex);
return size;
}
+static void file_backing_finalize(struct cch_backing *backing)
+{
+ struct cch_backing_file *file = (struct cch_backing_file *)backing;
+ nn_mutex_lock(&file->mutex);
+ file->backing.size = file->file.size;
+ nn_mutex_unlock(&file->mutex);
+}
+
static bool file_open_internal(struct cch_backing_file *file, str *path, size_t size)
{
s32 flags = size != 0 ? NNWT_FILE_CREATE : NNWT_FILE_READONLY;
- if (!nn_file_open(&file->file, path, flags)) {
- return false;
- }
+ if (!nn_file_open(&file->file, path, flags)) return false;
+ size_t filesize = file->file.size;
if (!size) {
- file->size = file->file.size;
- cch_backing_fill_range(&file->backing, 0, file->size);
- } else {
- file->size = -1;
- if (file->file.size < size) {
- nn_file_truncate(&file->file, size);
- }
+ file->backing.size = filesize;
+ cch_backing_fill_range(&file->backing, 0, filesize);
+ } else if (filesize < size) {
+ nn_file_truncate(&file->file, size);
}
return true;
}
diff --git a/src/cache/backings/file_mapped.c b/src/cache/backings/file_mapped.c
index adb840c..7657a21 100644
--- a/src/cache/backings/file_mapped.c
+++ b/src/cache/backings/file_mapped.c
@@ -7,29 +7,33 @@ static void file_backing_lock(struct cch_backing *backing)
nn_mutex_lock(&file->mutex);
}
-static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *size)
+static void file_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *count)
{
struct cch_backing_file *file = (struct cch_backing_file *)backing;
+ off_t n = (off_t)*count;
nn_mutex_lock(&file->mutex);
- off_t n = (off_t)*size;
- if (file->size >= 0 && index + n >= file->size) {
- n = MAX(file->size - index, (off_t)0);
+ off_t size = file->backing.size;
+ if (size > 0 && index + n >= size) {
+ n = MAX(size - index, (off_t)0);
}
- al_memcpy(file->u.map + index, buf, n);
- cch_backing_fill_range(&file->backing, index, n);
- *size = (size_t)n;
+ if (n > 0) {
+ al_memcpy(file->u.map + index, buf, n);
+ cch_backing_fill_range(&file->backing, index, n);
+ }
+ *count = (size_t)n;
nn_mutex_unlock(&file->mutex);
}
-static u8 *file_backing_get_ptr(struct cch_backing *backing, off_t index, size_t *size)
+static u8 *file_backing_get_ptr(struct cch_backing *backing, off_t index, size_t *count)
{
struct cch_backing_file *file = (struct cch_backing_file *)backing;
+ off_t n = (off_t)*count;
nn_mutex_lock(&file->mutex);
- off_t n = (off_t)*size;
- if (file->size >= 0 && index + n >= file->size) {
- n = MAX(file->size - index, (off_t)0);
+ off_t size = file->backing.size;
+ if (size > 0 && index + n >= size) {
+ n = MAX(size - index, (off_t)0);
}
- *size = (size_t)n;
+ *count = (size_t)n;
return (u8 *)(file->u.map + index);
}
@@ -39,12 +43,13 @@ static void file_backing_unlock(struct cch_backing *backing)
nn_mutex_unlock(&file->mutex);
}
-static void file_backing_resize(struct cch_backing *backing, size_t size)
+static void file_backing_set_size(struct cch_backing *backing, off_t size, bool expand_to_size)
{
struct cch_backing_file *file = (struct cch_backing_file *)backing;
+ al_assert(expand_to_size || size == 0);
nn_mutex_lock(&file->mutex);
- file->size = size;
- if (size > file->file.size) {
+ file->backing.size = size;
+ if ((size_t)size > file->file.size) {
nn_file_munmap(&file->file, file->u.map);
nn_file_truncate(&file->file, size);
file->u.map = nn_file_mmap(&file->file);
@@ -67,13 +72,15 @@ struct cch_backing *cch_backing_file_create(str *path, size_t size)
{
struct cch_backing_file *file = al_alloc_object(struct cch_backing_file);
file->backing.mode = CACHE_BACKING_MAPPED;
+ file->backing.size = -1;
file->backing.lock = file_backing_lock;
file->backing.write = file_backing_write;
file->backing.read = NULL;
file->backing.get_ptr = file_backing_get_ptr;
file->backing.unlock = file_backing_unlock;
- file->backing.get_size_estimate = file_backing_get_size_estimate;
- file->backing.resize = file_backing_resize;
+ file->backing.set_size = file_backing_set_size;
+ file->backing.get_size_if_known = file_backing_get_size_if_known;
+ file->backing.finalize = file_backing_finalize;
file->backing.free = file_backing_free;
al_array_init(file->backing.available);
if (!file_open_internal(file, path, size)) {
diff --git a/src/cache/backings/memory.c b/src/cache/backings/memory.c
index 8e0306a..6b3da62 100644
--- a/src/cache/backings/memory.c
+++ b/src/cache/backings/memory.c
@@ -2,10 +2,11 @@
#include "memory.h"
-static void ensure_alloced(struct cch_backing_memory *mem, size_t size)
+static void ensure_allocated(struct cch_backing_memory *mem, off_t amount)
{
- if (size > mem->alloc) {
- mem->alloc = al_next_power_of_two(size);
+ if (amount > mem->expanse) mem->expanse = amount;
+ if (amount > mem->alloc) {
+ mem->alloc = al_next_power_of_two(amount);
mem->data = al_realloc(mem->data, mem->alloc);
}
}
@@ -16,26 +17,35 @@ static void memory_backing_lock(struct cch_backing *backing)
nn_mutex_lock(&mem->mutex);
}
-static void memory_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *size)
+static void memory_backing_write(struct cch_backing *backing, u8 *buf, off_t index, size_t *count)
{
struct cch_backing_memory *mem = (struct cch_backing_memory *)backing;
+ off_t n = (off_t)*count;
nn_mutex_lock(&mem->mutex);
- if (mem->size >= 0 && index + (off_t)*size >= mem->size) {
- *size = MAX(mem->size - index, (off_t)0);
+ off_t size = mem->backing.size;
+ if (size > 0 && index + n >= size) {
+ n = MAX(size - index, (off_t)0);
}
- ensure_alloced(mem, index + *size);
- al_memcpy(mem->data + index, buf, *size);
- cch_backing_fill_range(&mem->backing, index, *size);
+ if (n > 0) {
+ ensure_allocated(mem, index + n);
+ al_memcpy(mem->data + index, buf, n);
+ cch_backing_fill_range(&mem->backing, index, n);
+ }
+ *count = (size_t)n;
nn_mutex_unlock(&mem->mutex);
}
-static u8 *memory_backing_get_ptr(struct cch_backing *backing, off_t index, size_t *size)
+static u8 *memory_backing_get_ptr(struct cch_backing *backing, off_t index, size_t *count)
{
struct cch_backing_memory *mem = (struct cch_backing_memory *)backing;
+ off_t n = (off_t)*count;
nn_mutex_lock(&mem->mutex);
- if (mem->size >= 0 && index + (off_t)*size >= mem->size) {
- *size = MAX(mem->size - index, (off_t)0);
+ off_t size = mem->backing.size;
+ if (size > 0 && index + n >= size) {
+ n = MAX(size - index, (off_t)0);
}
+ *count = (size_t)n;
+ al_assert(mem->alloc >= index + n);
return (u8 *)(mem->data + index);
}
@@ -45,21 +55,32 @@ static void memory_backing_unlock(struct cch_backing *backing)
nn_mutex_unlock(&mem->mutex);
}
-static off_t memory_backing_get_size_estimate(struct cch_backing *backing)
+static void memory_backing_set_size(struct cch_backing *backing, off_t size, bool expand_to_size)
+{
+ struct cch_backing_memory *mem = (struct cch_backing_memory *)backing;
+ nn_mutex_lock(&mem->mutex);
+ mem->backing.size = size;
+ if (expand_to_size) {
+ al_assert(size > 0);
+ ensure_allocated(mem, size);
+ }
+ nn_mutex_unlock(&mem->mutex);
+}
+
+static off_t memory_backing_get_size_if_known(struct cch_backing *backing)
{
struct cch_backing_memory *mem = (struct cch_backing_memory *)backing;
nn_mutex_lock(&mem->mutex);
- off_t size = mem->size;
+ off_t size = mem->backing.size;
nn_mutex_unlock(&mem->mutex);
return size;
}
-static void memory_backing_resize(struct cch_backing *backing, size_t size)
+static void memory_backing_finalize(struct cch_backing *backing)
{
struct cch_backing_memory *mem = (struct cch_backing_memory *)backing;
nn_mutex_lock(&mem->mutex);
- ensure_alloced(mem, size);
- mem->size = size;
+ mem->backing.size = mem->expanse;
nn_mutex_unlock(&mem->mutex);
}
@@ -77,16 +98,18 @@ struct cch_backing *cch_backing_memory_create(size_t size)
{
struct cch_backing_memory *mem = al_alloc_object(struct cch_backing_memory);
mem->backing.mode = CACHE_BACKING_MAPPED;
+ mem->backing.size = -1;
mem->backing.lock = memory_backing_lock;
mem->backing.write = memory_backing_write;
mem->backing.get_ptr = memory_backing_get_ptr;
mem->backing.unlock = memory_backing_unlock;
- mem->backing.get_size_estimate = memory_backing_get_size_estimate;
- mem->backing.resize = memory_backing_resize;
+ mem->backing.set_size = memory_backing_set_size;
+ mem->backing.get_size_if_known = memory_backing_get_size_if_known;
+ mem->backing.finalize = memory_backing_finalize;
mem->backing.free = memory_backing_free;
- mem->data = al_malloc(size);
+ if (size > 0) mem->data = al_malloc(size);
+ else mem->data = NULL;
mem->alloc = size;
- mem->size = -1;
nn_mutex_init(&mem->mutex);
al_array_init(mem->backing.available);
return (struct cch_backing *)mem;
diff --git a/src/cache/backings/memory.h b/src/cache/backings/memory.h
index e290b48..4737eba 100644
--- a/src/cache/backings/memory.h
+++ b/src/cache/backings/memory.h
@@ -8,8 +8,8 @@
struct cch_backing_memory {
struct cch_backing backing;
u8 *data;
- size_t alloc;
- off_t size;
+ off_t alloc;
+ off_t expanse;
struct nn_mutex mutex;
};