fix(lru): lower dependency for standard C functions (#3024)

* uses lvgl memory functions for lru

* uses lv_memset_00

* using lv_rand for seed
updated to use lvgl naming convention

* includes stddef.h
This commit is contained in:
Mariotaku
2022-01-20 20:00:13 +09:00
committed by GitHub
parent b0949109bd
commit 842296d874
3 changed files with 77 additions and 73 deletions

View File

@@ -56,13 +56,13 @@ static draw_cache_value_t * draw_cache_get_entry(lv_draw_sdl_ctx_t * ctx, const
void lv_draw_sdl_texture_cache_init(lv_draw_sdl_ctx_t * ctx) void lv_draw_sdl_texture_cache_init(lv_draw_sdl_ctx_t * ctx)
{ {
ctx->internals->texture_cache = lv_lru_new(LV_GPU_SDL_LRU_SIZE, 65536, ctx->internals->texture_cache = lv_lru_create(LV_GPU_SDL_LRU_SIZE, 65536,
(lv_lru_free_t *) draw_cache_free_value, NULL); (lv_lru_free_t *) draw_cache_free_value, NULL);
} }
void lv_draw_sdl_texture_cache_deinit(lv_draw_sdl_ctx_t * ctx) void lv_draw_sdl_texture_cache_deinit(lv_draw_sdl_ctx_t * ctx)
{ {
lv_lru_free(ctx->internals->texture_cache); lv_lru_del(ctx->internals->texture_cache);
} }
SDL_Texture * lv_draw_sdl_texture_cache_get(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length, bool * found) SDL_Texture * lv_draw_sdl_texture_cache_get(lv_draw_sdl_ctx_t * ctx, const void * key, size_t key_length, bool * found)

View File

@@ -9,11 +9,11 @@
*********************/ *********************/
#include "lv_lru.h" #include "lv_lru.h"
#include "lv_math.h"
#include "lv_mem.h"
#include "lv_assert.h"
#include "lv_log.h" #include "lv_log.h"
#include <stdlib.h>
#include <string.h>
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
@@ -22,6 +22,15 @@
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
struct _lv_lru_item_t {
void * value;
void * key;
size_t value_length;
size_t key_length;
uint64_t access_count;
struct _lv_lru_item_t * next;
};
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
@@ -34,10 +43,10 @@
static uint32_t lv_lru_hash(lv_lru_t * cache, const void * key, uint32_t key_length); static uint32_t lv_lru_hash(lv_lru_t * cache, const void * key, uint32_t key_length);
/** compare a key against an existing item's key */ /** compare a key against an existing item's key */
static int lv_lru_cmp_keys(lruc_item * item, const void * key, uint32_t key_length); static int lv_lru_cmp_keys(lv_lru_item_t * item, const void * key, uint32_t key_length);
/** remove an item and push it to the free items queue */ /** remove an item and push it to the free items queue */
static void lv_lru_remove_item(lv_lru_t * cache, lruc_item * prev, lruc_item * item, uint32_t hash_index); static void lv_lru_remove_item(lv_lru_t * cache, lv_lru_item_t * prev, lv_lru_item_t * item, uint32_t hash_index);
/** /**
* remove the least recently used item * remove the least recently used item
@@ -47,7 +56,7 @@ static void lv_lru_remove_item(lv_lru_t * cache, lruc_item * prev, lruc_item * i
static void lv_lru_remove_lru_item(lv_lru_t * cache); static void lv_lru_remove_lru_item(lv_lru_t * cache);
/** pop an existing item off the free queue, or create a new one */ /** pop an existing item off the free queue, or create a new one */
static lruc_item * lv_lru_pop_or_create_item(lv_lru_t * cache); static lv_lru_item_t * lv_lru_pop_or_create_item(lv_lru_t * cache);
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@@ -68,11 +77,12 @@ static lruc_item * lv_lru_pop_or_create_item(lv_lru_t * cache);
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
lv_lru_t * lv_lru_new(size_t cache_size, size_t average_length, lv_lru_free_t * value_free, lv_lru_t * lv_lru_create(size_t cache_size, size_t average_length, lv_lru_free_t * value_free,
lv_lru_free_t * key_free) lv_lru_free_t * key_free)
{ {
// create the cache // create the cache
lv_lru_t * cache = (lv_lru_t *) calloc(sizeof(lv_lru_t), 1); lv_lru_t * cache = (lv_lru_t *) lv_mem_alloc(sizeof(lv_lru_t));
lv_memset_00(cache, sizeof(lv_lru_t));
if(!cache) { if(!cache) {
LV_LOG_WARN("LRU Cache unable to create cache object"); LV_LOG_WARN("LRU Cache unable to create cache object");
return NULL; return NULL;
@@ -81,60 +91,59 @@ lv_lru_t * lv_lru_new(size_t cache_size, size_t average_length, lv_lru_free_t *
cache->average_item_length = average_length; cache->average_item_length = average_length;
cache->free_memory = cache_size; cache->free_memory = cache_size;
cache->total_memory = cache_size; cache->total_memory = cache_size;
cache->seed = time(NULL); cache->seed = lv_rand(1, UINT32_MAX);
cache->value_free = value_free ? value_free : free; cache->value_free = value_free ? value_free : lv_mem_free;
cache->key_free = key_free ? key_free : free; cache->key_free = key_free ? key_free : lv_mem_free;
// size the hash table to a guestimate of the number of slots required (assuming a perfect hash) // size the hash table to a guestimate of the number of slots required (assuming a perfect hash)
cache->items = (lruc_item **) calloc(sizeof(lruc_item *), cache->hash_table_size); cache->items = (lv_lru_item_t **) lv_mem_alloc(sizeof(lv_lru_item_t *) * cache->hash_table_size);
lv_memset_00(cache->items, sizeof(lv_lru_item_t *) * cache->hash_table_size);
if(!cache->items) { if(!cache->items) {
LV_LOG_WARN("LRU Cache unable to create cache hash table"); LV_LOG_WARN("LRU Cache unable to create cache hash table");
free(cache); lv_mem_free(cache);
return NULL; return NULL;
} }
return cache; return cache;
} }
lruc_error lv_lru_free(lv_lru_t * cache) void lv_lru_del(lv_lru_t * cache)
{ {
test_for_missing_cache(); LV_ASSERT_NULL(cache);
// free each of the cached items, and the hash table // free each of the cached items, and the hash table
lruc_item * item = NULL, *next = NULL; lv_lru_item_t * item = NULL, *next = NULL;
uint32_t i = 0; uint32_t i = 0;
if(cache->items) { if(cache->items) {
for(; i < cache->hash_table_size; i++) { for(; i < cache->hash_table_size; i++) {
item = cache->items[i]; item = cache->items[i];
while(item) { while(item) {
next = (lruc_item *) item->next; next = (lv_lru_item_t *) item->next;
cache->value_free(item->value); cache->value_free(item->value);
cache->key_free(item->key); cache->key_free(item->key);
cache->free_memory += item->value_length; cache->free_memory += item->value_length;
free(item); lv_mem_free(item);
item = next; item = next;
} }
} }
free(cache->items); lv_mem_free(cache->items);
} }
if(cache->free_items) { if(cache->free_items) {
item = cache->free_items; item = cache->free_items;
while(item) { while(item) {
next = (lruc_item *) item->next; next = (lv_lru_item_t *) item->next;
free(item); lv_mem_free(item);
item = next; item = next;
} }
} }
// free the cache // free the cache
free(cache); lv_mem_free(cache);
return LV_LRU_NO_ERROR;
} }
lruc_error lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, void * value, size_t value_length) lv_lru_res_t lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, void * value, size_t value_length)
{ {
test_for_missing_cache(); test_for_missing_cache();
test_for_missing_key(); test_for_missing_key();
@@ -144,12 +153,12 @@ lruc_error lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, voi
// see if the key already exists // see if the key already exists
uint32_t hash_index = lv_lru_hash(cache, key, key_length); uint32_t hash_index = lv_lru_hash(cache, key, key_length);
size_t required = 0; size_t required = 0;
lruc_item * item = NULL, *prev = NULL; lv_lru_item_t * item = NULL, *prev = NULL;
item = cache->items[hash_index]; item = cache->items[hash_index];
while(item && lv_lru_cmp_keys(item, key, key_length)) { while(item && lv_lru_cmp_keys(item, key, key_length)) {
prev = item; prev = item;
item = (lruc_item *) item->next; item = (lv_lru_item_t *) item->next;
} }
if(item) { if(item) {
@@ -164,7 +173,7 @@ lruc_error lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, voi
// insert a new item // insert a new item
item = lv_lru_pop_or_create_item(cache); item = lv_lru_pop_or_create_item(cache);
item->value = value; item->value = value;
item->key = malloc(key_length); item->key = lv_mem_alloc(key_length);
memcpy(item->key, key, key_length); memcpy(item->key, key, key_length);
item->value_length = value_length; item->value_length = value_length;
item->key_length = key_length; item->key_length = key_length;
@@ -183,21 +192,21 @@ lruc_error lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, voi
lv_lru_remove_lru_item(cache); lv_lru_remove_lru_item(cache);
} }
cache->free_memory -= required; cache->free_memory -= required;
return LV_LRU_NO_ERROR; return LV_LRU_OK;
} }
lruc_error lv_lru_get(lv_lru_t * cache, const void * key, size_t key_size, void ** value) lv_lru_res_t lv_lru_get(lv_lru_t * cache, const void * key, size_t key_size, void ** value)
{ {
test_for_missing_cache(); test_for_missing_cache();
test_for_missing_key(); test_for_missing_key();
// loop until we find the item, or hit the end of a chain // loop until we find the item, or hit the end of a chain
uint32_t hash_index = lv_lru_hash(cache, key, key_size); uint32_t hash_index = lv_lru_hash(cache, key, key_size);
lruc_item * item = cache->items[hash_index]; lv_lru_item_t * item = cache->items[hash_index];
while(item && lv_lru_cmp_keys(item, key, key_size)) while(item && lv_lru_cmp_keys(item, key, key_size))
item = (lruc_item *) item->next; item = (lv_lru_item_t *) item->next;
if(item) { if(item) {
*value = item->value; *value = item->value;
@@ -207,29 +216,29 @@ lruc_error lv_lru_get(lv_lru_t * cache, const void * key, size_t key_size, void
*value = NULL; *value = NULL;
} }
return LV_LRU_NO_ERROR; return LV_LRU_OK;
} }
lruc_error lv_lru_delete(lv_lru_t * cache, const void * key, size_t key_size) lv_lru_res_t lv_lru_remove(lv_lru_t * cache, const void * key, size_t key_size)
{ {
test_for_missing_cache(); test_for_missing_cache();
test_for_missing_key(); test_for_missing_key();
// loop until we find the item, or hit the end of a chain // loop until we find the item, or hit the end of a chain
lruc_item * item = NULL, *prev = NULL; lv_lru_item_t * item = NULL, *prev = NULL;
uint32_t hash_index = lv_lru_hash(cache, key, key_size); uint32_t hash_index = lv_lru_hash(cache, key, key_size);
item = cache->items[hash_index]; item = cache->items[hash_index];
while(item && lv_lru_cmp_keys(item, key, key_size)) { while(item && lv_lru_cmp_keys(item, key, key_size)) {
prev = item; prev = item;
item = (lruc_item *) item->next; item = (lv_lru_item_t *) item->next;
} }
if(item) { if(item) {
lv_lru_remove_item(cache, prev, item, hash_index); lv_lru_remove_item(cache, prev, item, hash_index);
} }
return LV_LRU_NO_ERROR; return LV_LRU_OK;
} }
/********************** /**********************
@@ -271,7 +280,7 @@ static uint32_t lv_lru_hash(lv_lru_t * cache, const void * key, uint32_t key_len
return h % cache->hash_table_size; return h % cache->hash_table_size;
} }
static int lv_lru_cmp_keys(lruc_item * item, const void * key, uint32_t key_length) static int lv_lru_cmp_keys(lv_lru_item_t * item, const void * key, uint32_t key_length)
{ {
if(key_length != item->key_length) if(key_length != item->key_length)
return 1; return 1;
@@ -279,12 +288,12 @@ static int lv_lru_cmp_keys(lruc_item * item, const void * key, uint32_t key_leng
return memcmp(key, item->key, key_length); return memcmp(key, item->key, key_length);
} }
static void lv_lru_remove_item(lv_lru_t * cache, lruc_item * prev, lruc_item * item, uint32_t hash_index) static void lv_lru_remove_item(lv_lru_t * cache, lv_lru_item_t * prev, lv_lru_item_t * item, uint32_t hash_index)
{ {
if(prev) if(prev)
prev->next = item->next; prev->next = item->next;
else else
cache->items[hash_index] = (lruc_item *) item->next; cache->items[hash_index] = (lv_lru_item_t *) item->next;
// free memory and update the free memory counter // free memory and update the free memory counter
cache->free_memory += item->value_length; cache->free_memory += item->value_length;
@@ -292,15 +301,15 @@ static void lv_lru_remove_item(lv_lru_t * cache, lruc_item * prev, lruc_item * i
cache->key_free(item->key); cache->key_free(item->key);
// push the item to the free items queue // push the item to the free items queue
memset(item, 0, sizeof(lruc_item)); lv_memset_00(item, sizeof(lv_lru_item_t));
item->next = cache->free_items; item->next = cache->free_items;
cache->free_items = item; cache->free_items = item;
} }
static void lv_lru_remove_lru_item(lv_lru_t * cache) static void lv_lru_remove_lru_item(lv_lru_t * cache)
{ {
lruc_item * min_item = NULL, *min_prev = NULL; lv_lru_item_t * min_item = NULL, *min_prev = NULL;
lruc_item * item = NULL, *prev = NULL; lv_lru_item_t * item = NULL, *prev = NULL;
uint32_t i = 0, min_index = -1; uint32_t i = 0, min_index = -1;
uint64_t min_access_count = -1; uint64_t min_access_count = -1;
@@ -324,17 +333,18 @@ static void lv_lru_remove_lru_item(lv_lru_t * cache)
lv_lru_remove_item(cache, min_prev, min_item, min_index); lv_lru_remove_item(cache, min_prev, min_item, min_index);
} }
static lruc_item * lv_lru_pop_or_create_item(lv_lru_t * cache) static lv_lru_item_t * lv_lru_pop_or_create_item(lv_lru_t * cache)
{ {
lruc_item * item = NULL; lv_lru_item_t * item = NULL;
if(cache->free_items) { if(cache->free_items) {
item = cache->free_items; item = cache->free_items;
cache->free_items = item->next; cache->free_items = item->next;
memset(item, 0, sizeof(lruc_item)); lv_memset_00(item, sizeof(lv_lru_item_t));
} }
else { else {
item = (lruc_item *) calloc(sizeof(lruc_item), 1); item = (lv_lru_item_t *) lv_mem_alloc(sizeof(lv_lru_item_t));
lv_memset_00(item, sizeof(lv_lru_item_t));
} }
return item; return item;

View File

@@ -16,8 +16,10 @@ extern "C" {
#include "../lv_conf_internal.h" #include "../lv_conf_internal.h"
#include "lv_types.h"
#include <stdint.h> #include <stdint.h>
#include <time.h> #include <stddef.h>
/********************* /*********************
@@ -29,36 +31,28 @@ extern "C" {
**********************/ **********************/
typedef enum { typedef enum {
LV_LRU_NO_ERROR = 0, LV_LRU_OK = 0,
LV_LRU_MISSING_CACHE, LV_LRU_MISSING_CACHE,
LV_LRU_MISSING_KEY, LV_LRU_MISSING_KEY,
LV_LRU_MISSING_VALUE, LV_LRU_MISSING_VALUE,
LV_LRU_LOCK_ERROR, LV_LRU_LOCK_ERROR,
LV_LRU_VALUE_TOO_LARGE LV_LRU_VALUE_TOO_LARGE
} lruc_error; } lv_lru_res_t;
typedef void (lv_lru_free_t)(void * v); typedef void (lv_lru_free_t)(void * v);
typedef struct _lv_lru_item_t lv_lru_item_t;
typedef struct lruc_item { typedef struct lv_lru_t {
void * value; lv_lru_item_t ** items;
void * key;
size_t value_length;
size_t key_length;
uint64_t access_count;
struct lruc_item * next;
} lruc_item;
typedef struct {
lruc_item ** items;
uint64_t access_count; uint64_t access_count;
size_t free_memory; size_t free_memory;
size_t total_memory; size_t total_memory;
size_t average_item_length; size_t average_item_length;
size_t hash_table_size; size_t hash_table_size;
time_t seed; uint32_t seed;
lv_lru_free_t * value_free; lv_lru_free_t * value_free;
lv_lru_free_t * key_free; lv_lru_free_t * key_free;
lruc_item * free_items; lv_lru_item_t * free_items;
} lv_lru_t; } lv_lru_t;
@@ -66,16 +60,16 @@ typedef struct {
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
lv_lru_t * lv_lru_new(size_t cache_size, size_t average_length, lv_lru_free_t * value_free, lv_lru_t * lv_lru_create(size_t cache_size, size_t average_length, lv_lru_free_t * value_free,
lv_lru_free_t * key_free); lv_lru_free_t * key_free);
lruc_error lv_lru_free(lv_lru_t * cache); void lv_lru_del(lv_lru_t * cache);
lruc_error lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, void * value, size_t value_length); lv_lru_res_t lv_lru_set(lv_lru_t * cache, const void * key, size_t key_length, void * value, size_t value_length);
lruc_error lv_lru_get(lv_lru_t * cache, const void * key, size_t key_size, void ** value); lv_lru_res_t lv_lru_get(lv_lru_t * cache, const void * key, size_t key_size, void ** value);
lruc_error lv_lru_delete(lv_lru_t * cache, const void * key, size_t key_size); lv_lru_res_t lv_lru_remove(lv_lru_t * cache, const void * key, size_t key_size);
/********************** /**********************
* MACROS * MACROS