Skip to content
Snippets Groups Projects
Commit 1ec87d27 authored by Jan Hák's avatar Jan Hák Committed by Daniel Salzman
Browse files

ucw lists: fix overlapping structures causing a problems at arm architectures

parent d2ee3c0d
No related branches found
No related tags found
No related merge requests found
......@@ -2,7 +2,7 @@
* BIRD Library -- Linked Lists
*
* (c) 1998 Martin Mares <mj@ucw.cz>
* (c) 2015, 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
* (c) 2015, 2020-2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
......@@ -25,8 +25,10 @@
* similar to that used in the &fib structure.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "contrib/ucw/lists.h"
#include "contrib/mempattern.h"
......@@ -40,12 +42,13 @@
void
add_tail(list_t *l, node_t *n)
{
node_t *z = l->tail;
node_t *z = &l->tail;
n->next = (node_t *) &l->null;
n->prev = z;
z->next = n;
l->tail = n;
n->next = z;
n->prev = z->prev;
z->prev->next = n;
z->prev = n;
assert(z->next == NULL);
}
/**
......@@ -58,12 +61,13 @@ add_tail(list_t *l, node_t *n)
void
add_head(list_t *l, node_t *n)
{
node_t *z = l->head;
node_t *z = &l->head;
n->next = z;
n->prev = (node_t *) &l->head;
z->prev = n;
l->head = n;
n->next = z->next;
n->prev = z;
z->next->prev = n;
z->next = n;
assert(z->prev == NULL);
}
/**
......@@ -113,9 +117,10 @@ rem_node(node_t *n)
void
init_list(list_t *l)
{
l->head = (node_t *) &l->null;
l->null = NULL;
l->tail = (node_t *) &l->head;
l->head.next = &l->tail;
l->head.prev = NULL;
l->tail.next = NULL;
l->tail.prev = &l->head;
}
/**
......@@ -129,14 +134,12 @@ init_list(list_t *l)
void
add_tail_list(list_t *to, list_t *l)
{
node_t *p = to->tail;
node_t *q = l->head;
node_t *p = to->tail.prev;
node_t *q = l->head.next;
p->next = q;
q->prev = p;
q = l->tail;
q->next = (node_t *) &to->null;
to->tail = q;
to->tail.prev = l->tail.prev;
}
/**
......
......@@ -2,26 +2,13 @@
* BIRD Library -- Linked Lists
*
* (c) 1998 Martin Mares <mj@ucw.cz>
* (c) 2015, 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
* (c) 2015, 2020-2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#pragma once
/*
* I admit the list structure is very tricky and also somewhat awkward,
* but it's both efficient and easy to manipulate once one understands the
* basic trick: The list head always contains two synthetic nodes which are
* always present in the list: the head and the tail. But as the `next'
* entry of the tail and the `prev' entry of the head are both NULL, the
* nodes can overlap each other:
*
* head head_node.next
* null head_node.prev tail_node.next
* tail tail_node.prev
*/
#include <string.h>
#include "libknot/mm_ctx.h"
......@@ -29,13 +16,13 @@ typedef struct node {
struct node *next, *prev;
} node_t;
typedef struct list { /* In fact two overlayed nodes */
struct node *head, *null, *tail;
typedef struct list {
node_t head, tail;
} list_t;
#define NODE (node_t *)
#define HEAD(list) ((void *)((list).head))
#define TAIL(list) ((void *)((list).tail))
#define HEAD(list) ((void *)((list).head.next))
#define TAIL(list) ((void *)((list).tail.prev))
#define WALK_LIST(n,list) for(n=HEAD(list);(NODE (n))->next; \
n=(void *)((NODE (n))->next))
#define WALK_LIST_DELSAFE(n,nxt,list) \
......@@ -48,7 +35,7 @@ typedef struct list { /* In fact two overlayed nodes */
#define WALK_LIST_BACKWARDS_DELSAFE(n,prv,list) \
for(n=TAIL(list); prv=(void *)((NODE (n))->prev); n=(void *) prv)
#define EMPTY_LIST(list) (!(list).head->next)
#define EMPTY_LIST(list) (!(NODE HEAD(list))->next)
/*! \brief Free every node in the list. */
#define WALK_LIST_FREE(list) \
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment