lv_ll_move_before bugfix

This commit is contained in:
Gabor Kiss-Vamosi
2018-09-27 15:03:20 +02:00
parent be2174b1d2
commit 789532a95f
3 changed files with 52 additions and 35 deletions

View File

@@ -51,11 +51,19 @@ void lv_ll_init(lv_ll_t * ll_p, uint32_t n_size)
{ {
ll_p->head = NULL; ll_p->head = NULL;
ll_p->tail = NULL; ll_p->tail = NULL;
#ifdef LV_MEM_ENV64
if(n_size & 0x3) { /*Round up to 4*/ /*Round the size up to 8*/
n_size &= ~0x3; if(n_size & 0x7) {
n_size += 4; n_size = n_size & (~0x7);
n_size += 8;
} }
#else
/*Round the size up to 4*/
if(n_size & 0x3) {
n_size = n_size & (~0x3);
n_size += 4;
}
#endif
ll_p->n_size = n_size; ll_p->n_size = n_size;
} }
@@ -312,20 +320,21 @@ void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after)
{ {
if(n_act == n_after) return; /*Can't move before itself*/ if(n_act == n_after) return; /*Can't move before itself*/
if(n_after == NULL) {
void * n_before = lv_ll_get_tail(ll_p); void * n_before = lv_ll_get_prev(ll_p, n_after);
node_set_next(ll_p, n_before, n_act); if(n_act == n_before) return; /*Already before `n_after`*/
node_set_prev(ll_p, n_act, n_before);
node_set_next(ll_p, n_act, NULL); /*It's much easier to remove from the list and add again*/
ll_p->tail = n_act; lv_ll_rem(ll_p, n_act);
} else {
void * n_before = lv_ll_get_prev(ll_p, n_after); /*Add again by setting the prev. and next nodes*/
/*Move the node between `n_before` and `n_after`*/ node_set_next(ll_p, n_before, n_act);
node_set_next(ll_p, n_before, n_act); node_set_prev(ll_p, n_act, n_before);
node_set_prev(ll_p, n_act, n_before); node_set_prev(ll_p, n_after, n_act);
node_set_prev(ll_p, n_after, n_act); node_set_next(ll_p, n_act, n_after);
node_set_next(ll_p, n_act, n_after);
} /*If `n_act` was moved before NULL then it become the new tail*/
if(n_after == NULL) ll_p->tail = n_act;
} }
/********************** /**********************
@@ -340,7 +349,11 @@ void lv_ll_move_before(lv_ll_t * ll_p, void * n_act, void * n_after)
*/ */
static void node_set_prev(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * prev) static void node_set_prev(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * prev)
{ {
memcpy(act + LL_PREV_P_OFFSET(ll_p), &prev, sizeof(lv_ll_node_t *)); if(act == NULL) return; /*Can't set the prev node of `NULL`*/
uint32_t node_p_size = sizeof(lv_ll_node_t *);
if(prev) memcpy(act + LL_PREV_P_OFFSET(ll_p), &prev, node_p_size);
else memset(act + LL_PREV_P_OFFSET(ll_p), 0, node_p_size);
} }
/** /**
@@ -351,6 +364,10 @@ static void node_set_prev(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * pre
*/ */
static void node_set_next(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * next) static void node_set_next(lv_ll_t * ll_p, lv_ll_node_t * act, lv_ll_node_t * next)
{ {
memcpy(act + LL_NEXT_P_OFFSET(ll_p), &next, sizeof(lv_ll_node_t *)); if(act == NULL) return; /*Can't set the next node of `NULL`*/
uint32_t node_p_size = sizeof(lv_ll_node_t *);
if(next) memcpy(act + LL_NEXT_P_OFFSET(ll_p), &next, node_p_size);
else memset(act + LL_NEXT_P_OFFSET(ll_p), 0, node_p_size);
} }

View File

@@ -20,25 +20,14 @@
*********************/ *********************/
#define LV_MEM_ADD_JUNK 0 /*Add memory junk on alloc (0xaa) and free(0xbb) (just for testing purposes)*/ #define LV_MEM_ADD_JUNK 0 /*Add memory junk on alloc (0xaa) and free(0xbb) (just for testing purposes)*/
// Check windows
#if __WIN64
# define ENVIRONMENT64
#endif
// Check GCC #ifdef LV_MEM_ENV64
#if __GNUC__
# if __x86_64__ || __ppc64__
# define ENVIRONMENT64
# endif
#endif
#ifdef ENVIRONMENT64
# define MEM_UNIT uint64_t # define MEM_UNIT uint64_t
#else #else
# define MEM_UNIT uint32_t # define MEM_UNIT uint32_t
#endif #endif
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
@@ -109,7 +98,7 @@ void * lv_mem_alloc(uint32_t size)
return &zero_mem; return &zero_mem;
} }
#ifdef ENVIRONMENT64 #ifdef LV_MEM_ENV64
/*Round the size up to 8*/ /*Round the size up to 8*/
if(size & 0x7) { if(size & 0x7) {
size = size & (~0x7); size = size & (~0x7);
@@ -393,7 +382,7 @@ static void * ent_alloc(lv_mem_ent_t * e, uint32_t size)
*/ */
static void ent_trunc(lv_mem_ent_t * e, uint32_t size) static void ent_trunc(lv_mem_ent_t * e, uint32_t size)
{ {
#ifdef ENVIRONMENT64 #ifdef LV_MEM_ENV64
/*Round the size up to 8*/ /*Round the size up to 8*/
if(size & 0x7) { if(size & 0x7) {
size = size & (~0x7); size = size & (~0x7);

View File

@@ -27,6 +27,17 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
// Check windows
#if __WIN64
# define LV_MEM_ENV64
#endif
// Check GCC
#if __GNUC__
# if __x86_64__ || __ppc64__
# define LV_MEM_ENV64
# endif
#endif
/********************** /**********************
* TYPEDEFS * TYPEDEFS