summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/buflib.c27
-rw-r--r--firmware/core_alloc.c5
-rw-r--r--firmware/include/buflib.h15
-rw-r--r--firmware/include/core_alloc.h1
4 files changed, 41 insertions, 7 deletions
diff --git a/firmware/buflib.c b/firmware/buflib.c
index 2ceb7fc..1aa7404 100644
--- a/firmware/buflib.c
+++ b/firmware/buflib.c
@@ -647,9 +647,9 @@ free_space_at_end(struct buflib_context* ctx)
return 0;
}
-/* Return the maximum allocatable memory in bytes */
+/* Return the maximum allocatable contiguous memory in bytes */
size_t
-buflib_available(struct buflib_context* ctx)
+buflib_allocatable(struct buflib_context* ctx)
{
union buflib_data *this;
size_t free_space = 0, max_free_space = 0;
@@ -687,6 +687,29 @@ buflib_available(struct buflib_context* ctx)
return 0;
}
+/* Return the amount of unallocated memory in bytes (even if not contiguous) */
+size_t
+buflib_available(struct buflib_context* ctx)
+{
+ union buflib_data *this;
+ size_t free_space = 0;
+
+ /* now look if there's free in holes */
+ for(this = find_first_free(ctx); this < ctx->alloc_end; this += abs(this->val))
+ {
+ if (this->val < 0)
+ {
+ free_space += -this->val;
+ continue;
+ }
+ }
+
+ free_space *= sizeof(union buflib_data); /* make it bytes */
+ free_space += free_space_at_end(ctx);
+
+ return free_space;
+}
+
/*
* Allocate all available (as returned by buflib_available()) memory and return
* a handle to it
diff --git a/firmware/core_alloc.c b/firmware/core_alloc.c
index 47faed6..aa662fb 100644
--- a/firmware/core_alloc.c
+++ b/firmware/core_alloc.c
@@ -67,6 +67,11 @@ size_t core_available(void)
return buflib_available(&core_ctx);
}
+size_t core_allocatable(void)
+{
+ return buflib_allocatable(&core_ctx);
+}
+
int core_free(int handle)
{
return buflib_free(&core_ctx, handle);
diff --git a/firmware/include/buflib.h b/firmware/include/buflib.h
index 6c9ccf7..7183951 100644
--- a/firmware/include/buflib.h
+++ b/firmware/include/buflib.h
@@ -143,15 +143,20 @@ void buflib_init(struct buflib_context *context, void *buf, size_t size);
/**
- * Returns how many bytes left the buflib has to satisfy allocations.
+ * Returns the amount of unallocated bytes. It does not mean this amount
+ * can be actually allocated because they might not be contiguous.
*
- * This function does not yet consider possible compaction so there might
- * be more space left. This may change in the future.
- *
- * Returns: The number of bytes left in the memory pool.
+ * Returns: The number of unallocated bytes in the memory pool.
*/
size_t buflib_available(struct buflib_context *ctx);
+/**
+ * Returns the biggest possible allocation that can be determined to succeed.
+ *
+ * Returns: The amount of bytes of the biggest unallocated, contiguous region.
+ */
+size_t buflib_allocatable(struct buflib_context *ctx);
+
/**
* Allocates memory from buflib's memory pool
diff --git a/firmware/include/core_alloc.h b/firmware/include/core_alloc.h
index d234947..a100b7c 100644
--- a/firmware/include/core_alloc.h
+++ b/firmware/include/core_alloc.h
@@ -16,6 +16,7 @@ int core_alloc_maximum(const char* name, size_t *size, struct buflib_callbacks *
bool core_shrink(int handle, void* new_start, size_t new_size);
int core_free(int handle);
size_t core_available(void);
+size_t core_allocatable(void);
/* DO NOT ADD wrappers for buflib_buffer_out/in. They do not call
* the move callbacks and are therefore unsafe in the core */