Files
TAIXIN/csky/csi_kernel/rhino/pwrmgmt/dl_list.h

190 lines
7.4 KiB
C
Raw Normal View History

/*
* Copyright (C) 2018 Alibaba Group Holding Limited
*/
/* double linked list header */
#ifndef __dl_list_h__
#define __dl_list_h__
#ifdef __cplusplus
extern "C" {
#endif
/* defines */
/* typedefs */
typedef struct _rhino_dlnode /* Node of a linked list. */
{
struct _rhino_dlnode* next; /* Points at the next node in the list */
struct _rhino_dlnode* previous; /* Points at the previous node in the list */
} _RHINO_DL_NODE;
typedef struct /* Header for a linked list. */
{
_RHINO_DL_NODE* head; /* header of list */
_RHINO_DL_NODE* tail; /* tail of list */
} _RHINO_DL_LIST;
typedef _RHINO_DL_NODE DL_NODE;
typedef _RHINO_DL_LIST DL_LIST;
/* DLL_INIT() initialize the specified list to an empty list. */
#define DLL_INIT(list) \
{ \
((DL_LIST *)(list))->head = NULL; \
((DL_LIST *)(list))->tail = NULL; \
}
/* DLL_ADD() adds the specified node to the end of the specified list. */
#define DLL_ADD(list, node) \
{ \
DL_NODE* listTail = (list)->tail; \
DLL_INSERT ((list), listTail, (node)); \
}
/*
* DLL_INSERT() inserts the specified node in the specified list.
* The new node is placed following the specified 'previous' node in the list.
* If the specified previous node is NULL, the node is inserted at the head
* of the list.
*/
#define DLL_INSERT(list, previousNode, node) \
{ \
DL_NODE *temp; \
if ((previousNode) == NULL) \
{ \
temp = ((DL_LIST *)(list))->head; \
((DL_LIST *)(list))->head = (DL_NODE *)(node); \
} \
else \
{ \
temp = ((DL_NODE *)(previousNode))->next; \
((DL_NODE *)(previousNode))->next = (DL_NODE *)(node); \
} \
if (temp == NULL) \
{ \
((DL_LIST *)(list))->tail = (DL_NODE *)(node); \
} \
else \
{ \
temp->previous = (DL_NODE *)(node); \
} \
((DL_NODE *)(node))->next = temp; \
((DL_NODE *)(node))->previous = (DL_NODE *)(previousNode); \
}
/* DLL_REMOVE() Remove the specified node in the doubly linked list.*/
#define DLL_REMOVE(list, node) \
{ \
if (((DL_NODE *)(node))->previous == NULL) \
{ \
((DL_LIST *)(list))->head = ((DL_NODE *)(node))->next; \
} \
else \
{ \
((DL_NODE *)(node))->previous->next = ((DL_NODE *)(node))->next; \
} \
if (((DL_NODE *)(node))->next == NULL) \
{ \
((DL_LIST *)(list))->tail = ((DL_NODE *)(node))->previous; \
} \
else \
{ \
((DL_NODE *)(node))->next->previous = ((DL_NODE *)(node))->previous; \
} \
}
/*
* DLL_FIRST() finds the first node in a doubly linked list.
*
* RETURNS: Pointer to the first node in a list, or NULL if the list is empty.
*/
#define DLL_FIRST(pList) \
( \
(((DL_LIST *)(pList))->head) \
)
/*
* DLL_LAST () finds the last node in a doubly linked list.
*
* RETURNS: Pointer to the last node in list, or NULL if the list is empty.
*/
#define DLL_LAST(pList) \
( \
(((DL_LIST *)(pList))->tail) \
)
/*
* DLL_NEXT() locates the node immediately after the node pointed to by the pNode.
*
* RETURNS: Pointer to the next node in list, or NULL if there is no next node.
*/
#define DLL_NEXT(pNode) \
( \
(((DL_NODE *)(pNode))->next) \
)
/*
* DLL_PREVIOUS() locates the node immediately before the node pointed
* to by the pNode.
*
* RETURNS: Pointer to the preceding node in the list, or
* NULL if there is no next node.
*/
#define DLL_PREVIOUS(pNode) \
( \
(((DL_NODE *)(pNode))->previous) \
)
/*
* DLL_EMPTY() is used to check if list is empty.
* RETURNS: TRUE if list is empty. FALSE otherwise
*/
#define DLL_EMPTY(pList) \
( \
(((DL_LIST *)pList)->head == NULL) \
)
/*
* DLL_GET() gets the first node from the specified list, deletes the node
* from the list, and returns a pointer to the node gotten.
*
* RETURNS: Pointer to the first node in list, or NULL if there is list empty.
*/
#define DLL_GET(list, node) \
{ \
(node) = (void *)((DL_LIST *)(list))->head; \
if ((node) != NULL) \
{ \
((DL_LIST *)(list))->head = ((DL_NODE *)(node))->next; \
if (((DL_NODE *)(node))->next == NULL) \
{ \
((DL_LIST *)(list))->tail = NULL; \
} \
else \
{ \
((DL_NODE *)(node))->next->previous = NULL; \
} \
} \
}
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __dl_list_h__ */