Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test/cmocka/src/lib/fast-get/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

cmocka_test(fast-get-tests
fast-get-tests.c
${PROJECT_SOURCE_DIR}/src/lib/objpool.c
${PROJECT_SOURCE_DIR}/zephyr/lib/fast-get.c
${PROJECT_SOURCE_DIR}/src/lib/alloc.c
${PROJECT_SOURCE_DIR}/src/platform/library/lib/memory.c
Expand Down
1 change: 1 addition & 0 deletions test/ztest/unit/fast-get/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ target_compile_definitions(app PRIVATE

target_sources(app PRIVATE
test_fast_get_ztest.c
${SOF_ROOT}/src/lib/objpool.c
${SOF_ROOT}/zephyr/lib/fast-get.c
${SOF_ROOT}/test/ztest/unit/common/alloc.c
)
Expand Down
8 changes: 8 additions & 0 deletions zephyr/include/rtos/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,15 @@ void l3_heap_save(void);
void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes,
size_t alignment);
void sof_heap_free(struct k_heap *heap, void *addr);
#if CONFIG_SOF_FULL_ZEPHYR_APPLICATION
struct k_heap *sof_sys_heap_get(void);
#else
/* for unit-testing */
static inline struct k_heap *sof_sys_heap_get(void)
{
return NULL;
}
#endif

/* TODO: remove - debug only - only needed for linking */
static inline void heap_trace_all(int force) {}
Expand Down
97 changes: 38 additions & 59 deletions zephyr/lib/fast-get.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <sof/audio/component.h>
#include <sof/lib/fast-get.h>
#include <sof/lib/vregion.h>
#include <sof/objpool.h>
#include <rtos/alloc.h>
#include <rtos/cache.h>
#include <rtos/kernel.h>
Expand All @@ -36,60 +37,30 @@ struct sof_fast_get_entry {

struct sof_fast_get_data {
struct k_spinlock lock;
size_t num_entries;
struct sof_fast_get_entry *entries;
struct objpool_head pool;
};

static struct sof_fast_get_data fast_get_data = {
.num_entries = 0,
.entries = NULL,
.pool.list = LIST_INIT(fast_get_data.pool.list),
};

LOG_MODULE_REGISTER(fast_get, CONFIG_SOF_LOG_LEVEL);

static int fast_get_realloc(struct sof_fast_get_data *data)
{
struct sof_fast_get_entry *entries;
/*
* Allocate 8 entries for the beginning. Currently we only use 2 entries
* at most, so this should provide a reasonable first allocation.
*/
const unsigned int init_n_entries = 8;
unsigned int n_entries = data->num_entries ? data->num_entries * 2 : init_n_entries;

entries = rzalloc(SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT,
n_entries * sizeof(*entries));
if (!entries)
return -ENOMEM;

if (data->num_entries) {
memcpy_s(entries, n_entries * sizeof(*entries), data->entries,
data->num_entries * sizeof(*entries));
rfree(data->entries);
}

data->entries = entries;
data->num_entries = n_entries;

return 0;
}
struct fast_get_find {
const void *ptr;
struct sof_fast_get_entry *entry;
};

static struct sof_fast_get_entry *fast_get_find_entry(struct sof_fast_get_data *data,
const void *dram_ptr)
static bool fast_get_find_entry(void *data, void *arg)
{
int i;
struct sof_fast_get_entry *entry = data;
struct fast_get_find *find = arg;

for (i = 0; i < data->num_entries; i++) {
if (data->entries[i].dram_ptr == dram_ptr)
return &data->entries[i];
}
if (find->ptr != entry->dram_ptr)
return false;

for (i = 0; i < data->num_entries; i++) {
if (data->entries[i].dram_ptr == NULL)
return &data->entries[i];
}

return NULL;
find->entry = entry;
return true;
}

#if CONFIG_MM_DRV
Expand Down Expand Up @@ -157,15 +128,19 @@ const void *fast_get(struct mod_alloc_ctx *alloc, const void *dram_ptr, size_t s
/* When userspace is enabled only share large buffers */
alloc_ptr = NULL;

do {
entry = fast_get_find_entry(data, alloc_ptr);
struct fast_get_find find = {
.ptr = alloc_ptr,
};
objpool_iterate(&fast_get_data.pool, fast_get_find_entry, &find);
entry = find.entry;
if (!entry) {
Comment thread
lyakh marked this conversation as resolved.
entry = objpool_alloc(&fast_get_data.pool, sizeof(*entry),
SOF_MEM_FLAG_USER | SOF_MEM_FLAG_COHERENT);
if (!entry) {
if (fast_get_realloc(data)) {
ret = NULL;
goto out;
}
ret = NULL;
goto out;
}
} while (!entry);
}
Comment thread
lyakh marked this conversation as resolved.

#if CONFIG_USERSPACE
LOG_DBG("%s: %#zx bytes alloc %p entry %p DRAM %p",
Expand Down Expand Up @@ -257,17 +232,16 @@ const void *fast_get(struct mod_alloc_ctx *alloc, const void *dram_ptr, size_t s
}
EXPORT_SYMBOL(fast_get);

static struct sof_fast_get_entry *fast_put_find_entry(struct sof_fast_get_data *data,
const void *sram_ptr)
static bool fast_put_find_entry(void *data, void *arg)
{
int i;
struct sof_fast_get_entry *entry = data;
struct fast_get_find *find = arg;

for (i = 0; i < data->num_entries; i++) {
if (data->entries[i].sram_ptr == sram_ptr)
return &data->entries[i];
}
if (find->ptr != entry->sram_ptr)
return false;

return NULL;
find->entry = entry;
return true;
}

void fast_put(struct mod_alloc_ctx *alloc, struct k_mem_domain *mdom, const void *sram_ptr)
Expand All @@ -278,7 +252,12 @@ void fast_put(struct mod_alloc_ctx *alloc, struct k_mem_domain *mdom, const void
k_spinlock_key_t key;

key = k_spin_lock(&fast_get_data.lock);
entry = fast_put_find_entry(data, sram_ptr);

struct fast_get_find find = {
.ptr = sram_ptr,
Comment thread
lyakh marked this conversation as resolved.
};
objpool_iterate(&fast_get_data.pool, fast_put_find_entry, &find);
entry = find.entry;
if (!entry) {
LOG_ERR("Put called to unknown address %p", sram_ptr);
goto out;
Expand Down
Loading