00001
00020
00021
00022
00023
00024 #include "co_int.h"
00025 #include "co_bool.h"
00026 #include "arch.h"
00027 #include "dbg_assert.h"
00028
00029 #include "co_math.h"
00030 #include "ke_config.h"
00031 #include "ke_env.h"
00032 #include "ke_mem.h"
00033
00034
00035
00036
00037
00038
00040 #ifdef CFG_RWTL
00041 #define KE_HEAP_SIZE NX_HEAP_SIZE/2
00042 #else
00043 #define KE_HEAP_SIZE NX_HEAP_SIZE
00044 #endif
00045
00047 struct mblock_free
00048 {
00049 struct mblock_free *next;
00050 #if CPU_WORD_SIZE == 4
00051 uint32_t size;
00052 #elif CPU_WORD_SIZE == 2
00053 uint16_t size;
00054 #endif
00055 };
00056
00058 struct mblock_used
00059 {
00060 uint32_t size;
00061 };
00062
00063
00064
00065
00066
00068 #ifdef CFG_RWTL
00069 uint16_t ke_mem_heap[KE_HEAP_SIZE];
00070 #else
00071 uint8_t ke_mem_heap[KE_HEAP_SIZE];
00072 #endif
00073
00074
00075
00076
00077
00078 struct mblock_free *ke_mem_init(void)
00079 {
00080 struct mblock_free *first;
00081
00082
00083 #if CPU_WORD_SIZE == 4
00084 first = (struct mblock_free*)CO_ALIGN4_HI((uint32_t)ke_mem_heap);
00085 #elif CPU_WORD_SIZE == 2
00086 first = (struct mblock_free*)CO_ALIGN2_HI((uint16_t)ke_mem_heap);
00087 #else
00088 #error No word size defined
00089 #endif
00090
00091
00092 GLOBAL_INT_DISABLE();
00093
00094
00095
00096 first->size = ((uint32_t)&ke_mem_heap[KE_HEAP_SIZE] & (~3)) - (uint32_t)first;
00097 first->next = NULL;
00098
00099
00100 GLOBAL_INT_RESTORE();
00101
00102
00103 return first;
00104 }
00105
00106 void *ke_malloc(uint32_t size)
00107 {
00108 struct mblock_free *node, *found;
00109 struct mblock_used *alloc;
00110 uint32_t totalsize;
00111
00112 #if KE_PROFILING
00113 uint32_t totalfreesize = 0;
00114 #endif //KE_PROFILING
00115
00116
00117 found = NULL;
00118
00119
00120 totalsize = CO_ALIGN4_HI(size) + sizeof(struct mblock_used);
00121
00122
00123 ASSERT_ERR(totalsize >= sizeof(struct mblock_free));
00124
00125 node = ke_env.mblock_first;
00126
00127
00128 GLOBAL_INT_DISABLE();
00129
00130
00131 while (node != NULL)
00132 {
00133 #if KE_PROFILING
00134 totalfreesize += node->size;
00135 #endif //KE_PROFILING
00136
00137
00138 if (node->size >= (totalsize + sizeof(struct mblock_free)))
00139 {
00140
00141 if ((found == NULL) || (found->size > node->size))
00142 {
00143 found = node;
00144 }
00145 }
00146
00147 node = node->next;
00148 }
00149
00150
00151 ASSERT_ERR(found != NULL);
00152
00153 #if KE_PROFILING
00154 if(ke_env.max_heap_used <= KE_HEAP_SIZE - totalfreesize)
00155 ke_env.max_heap_used = KE_HEAP_SIZE - totalfreesize;
00156 #endif //KE_PROFILING
00157
00158
00159
00160
00161 found->size -= totalsize;
00162
00163
00164 #if CPU_WORD_SIZE == 4
00165 alloc = (struct mblock_used*) ((uint32_t)found + found->size);
00166 #elif CPU_WORD_SIZE == 2
00167 alloc = (struct mblock_used*) ((uint16_t)found + found->size);
00168 #endif
00169
00170
00171 alloc->size = totalsize;
00172
00173
00174 alloc++;
00175
00176
00177 GLOBAL_INT_RESTORE();
00178
00179 return (void*)alloc;
00180 }
00181
00182
00183 void ke_free(void* mem_ptr)
00184 {
00185 struct mblock_used *freed;
00186 struct mblock_free *node, *prev_node, *next_node;
00187 uint32_t size;
00188
00189
00190 freed = ((struct mblock_used *)mem_ptr) - 1;
00191
00192
00193 size = freed->size;
00194 node = ke_env.mblock_first;
00195 prev_node = NULL;
00196
00197
00198 ASSERT_ERR(mem_ptr != NULL);
00199 ASSERT_ERR((uint32_t)mem_ptr > (uint32_t)node);
00200
00201
00202 GLOBAL_INT_DISABLE();
00203
00204 while (node != NULL)
00205 {
00206
00207 if ((uint32_t)freed == ((uint32_t)node + node->size))
00208 {
00209
00210 node->size += size;
00211
00212
00213 if ((uint32_t)node->next == ((uint32_t)node + node->size))
00214 {
00215 next_node = node->next;
00216
00217 node->size += next_node->size;
00218
00219 node->next = next_node->next;
00220 }
00221 goto free_end;
00222 }
00223 else if ((uint32_t)freed < (uint32_t)node)
00224 {
00225
00226 ASSERT_ERR(prev_node != NULL);
00227
00228
00229 prev_node->next = (struct mblock_free*)freed;
00230
00231
00232 if (((uint32_t)freed + size) == (uint32_t)node)
00233 {
00234
00235 ((struct mblock_free*)freed)->next = node->next;
00236 ((struct mblock_free*)freed)->size = node->size + (uint32_t)node - (uint32_t)freed;
00237 }
00238 else
00239 {
00240
00241 ((struct mblock_free*)freed)->next = node;
00242 ((struct mblock_free*)freed)->size = size;
00243 }
00244 goto free_end;
00245 }
00246
00247
00248 prev_node = node;
00249 node = node->next;
00250 }
00251
00252 prev_node->next = (struct mblock_free*)freed;
00253 ((struct mblock_free*)freed)->next = NULL;
00254 ((struct mblock_free*)freed)->size = size;
00255
00256 free_end:
00257
00258 GLOBAL_INT_RESTORE();
00259 }
00260