1 /**
2 * @file lv_cache_entry.c
3 *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_cache_entry.h"
10 #include "../../stdlib/lv_sprintf.h"
11 #include "../lv_assert.h"
12 #include "lv_cache.h"
13 #include "lv_cache_entry_private.h"
14 #include "lv_cache_private.h"
15 
16 /*********************
17  *      DEFINES
18  *********************/
19 
20 /**********************
21  *      TYPEDEFS
22  **********************/
23 struct _lv_cache_entry_t {
24     const lv_cache_t * cache;
25     int32_t ref_cnt;
26     uint32_t node_size;
27 
28     bool is_invalid;
29 };
30 /**********************
31  *  STATIC PROTOTYPES
32  **********************/
33 
34 /**********************
35  *  GLOBAL VARIABLES
36  **********************/
37 
38 /**********************
39  *  STATIC VARIABLES
40  **********************/
41 
42 /**********************
43  *      MACROS
44  **********************/
45 
46 /**********************
47  *   GLOBAL FUNCTIONS
48  **********************/
49 
lv_cache_entry_reset_ref(lv_cache_entry_t * entry)50 void lv_cache_entry_reset_ref(lv_cache_entry_t * entry)
51 {
52     LV_ASSERT_NULL(entry);
53     entry->ref_cnt = 0;
54 }
55 
lv_cache_entry_inc_ref(lv_cache_entry_t * entry)56 void lv_cache_entry_inc_ref(lv_cache_entry_t * entry)
57 {
58     LV_ASSERT_NULL(entry);
59     entry->ref_cnt++;
60 }
61 
lv_cache_entry_dec_ref(lv_cache_entry_t * entry)62 void lv_cache_entry_dec_ref(lv_cache_entry_t * entry)
63 {
64     LV_ASSERT_NULL(entry);
65     entry->ref_cnt--;
66     if(entry->ref_cnt < 0) {
67         LV_LOG_WARN("ref_cnt(%" LV_PRIu32 ") < 0", entry->ref_cnt);
68         entry->ref_cnt = 0;
69     }
70 }
71 
lv_cache_entry_get_ref(lv_cache_entry_t * entry)72 int32_t lv_cache_entry_get_ref(lv_cache_entry_t * entry)
73 {
74     LV_ASSERT_NULL(entry);
75     return entry->ref_cnt;
76 }
77 
lv_cache_entry_get_node_size(lv_cache_entry_t * entry)78 uint32_t lv_cache_entry_get_node_size(lv_cache_entry_t * entry)
79 {
80     return entry->node_size;
81 }
82 
lv_cache_entry_set_node_size(lv_cache_entry_t * entry,uint32_t node_size)83 void lv_cache_entry_set_node_size(lv_cache_entry_t * entry, uint32_t node_size)
84 {
85     LV_ASSERT_NULL(entry);
86     entry->node_size = node_size;
87 }
88 
lv_cache_entry_set_invalid(lv_cache_entry_t * entry,bool is_invalid)89 void lv_cache_entry_set_invalid(lv_cache_entry_t * entry, bool is_invalid)
90 {
91     LV_ASSERT_NULL(entry);
92     entry->is_invalid = is_invalid;
93 }
94 
lv_cache_entry_is_invalid(lv_cache_entry_t * entry)95 bool lv_cache_entry_is_invalid(lv_cache_entry_t * entry)
96 {
97     LV_ASSERT_NULL(entry);
98     return entry->is_invalid;
99 }
100 
lv_cache_entry_get_data(lv_cache_entry_t * entry)101 void * lv_cache_entry_get_data(lv_cache_entry_t * entry)
102 {
103     LV_ASSERT_NULL(entry);
104     return (uint8_t *)entry - entry->node_size;
105 }
106 
lv_cache_entry_acquire_data(lv_cache_entry_t * entry)107 void * lv_cache_entry_acquire_data(lv_cache_entry_t * entry)
108 {
109     LV_ASSERT_NULL(entry);
110 
111     lv_cache_entry_inc_ref(entry);
112     return lv_cache_entry_get_data(entry);
113 }
114 
lv_cache_entry_release_data(lv_cache_entry_t * entry,void * user_data)115 void lv_cache_entry_release_data(lv_cache_entry_t * entry, void * user_data)
116 {
117     LV_UNUSED(user_data);
118 
119     LV_ASSERT_NULL(entry);
120     if(lv_cache_entry_get_ref(entry) == 0) {
121         LV_LOG_ERROR("ref_cnt(%" LV_PRIu32 ") == 0", entry->ref_cnt);
122         return;
123     }
124 
125     lv_cache_entry_dec_ref(entry);
126 }
127 
lv_cache_entry_get_entry(void * data,const uint32_t node_size)128 lv_cache_entry_t * lv_cache_entry_get_entry(void * data, const uint32_t node_size)
129 {
130     LV_ASSERT_NULL(data);
131     return (lv_cache_entry_t *)((uint8_t *)data + node_size);
132 }
133 
lv_cache_entry_set_cache(lv_cache_entry_t * entry,const lv_cache_t * cache)134 void lv_cache_entry_set_cache(lv_cache_entry_t * entry, const lv_cache_t * cache)
135 {
136     LV_ASSERT_NULL(entry);
137     entry->cache = cache;
138 }
139 
lv_cache_entry_get_cache(const lv_cache_entry_t * entry)140 const lv_cache_t * lv_cache_entry_get_cache(const lv_cache_entry_t * entry)
141 {
142     LV_ASSERT_NULL(entry);
143     return entry->cache;
144 }
145 
lv_cache_entry_get_size(const uint32_t node_size)146 uint32_t lv_cache_entry_get_size(const uint32_t node_size)
147 {
148     return node_size + sizeof(lv_cache_entry_t);
149 }
150 
lv_cache_entry_alloc(const uint32_t node_size,const lv_cache_t * cache)151 lv_cache_entry_t * lv_cache_entry_alloc(const uint32_t node_size, const lv_cache_t * cache)
152 {
153     void * res = lv_malloc_zeroed(lv_cache_entry_get_size(node_size));
154     LV_ASSERT_MALLOC(res)
155     if(res == NULL) {
156         LV_LOG_ERROR("malloc failed");
157         return NULL;
158     }
159     lv_cache_entry_t * entry = (lv_cache_entry_t *)res;
160     lv_cache_entry_init(entry, cache, node_size);
161     return (lv_cache_entry_t *)((uint8_t *)entry + node_size);
162 }
163 
lv_cache_entry_init(lv_cache_entry_t * entry,const lv_cache_t * cache,const uint32_t node_size)164 void lv_cache_entry_init(lv_cache_entry_t * entry, const lv_cache_t * cache, const uint32_t node_size)
165 {
166     LV_ASSERT_NULL(entry);
167     LV_ASSERT_NULL(cache);
168 
169     entry->cache = cache;
170     entry->node_size = node_size;
171     entry->ref_cnt = 0;
172     entry->is_invalid = false;
173 }
174 
lv_cache_entry_delete(lv_cache_entry_t * entry)175 void lv_cache_entry_delete(lv_cache_entry_t * entry)
176 {
177     LV_ASSERT_NULL(entry);
178 
179     void * data = lv_cache_entry_get_data(entry);
180     lv_free(data);
181 }
182 
183 /**********************
184  *   STATIC FUNCTIONS
185  **********************/
186