* This file is part of the oGRAC project.
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
*
* oGRAC is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* cm_bilist.h
*
*
* IDENTIFICATION
* src/common/cm_bilist.h
*
* -------------------------------------------------------------------------
*/
#ifndef __CM_BILIST_H__
#define __CM_BILIST_H__
#include "cm_debug.h"
#define BINODE_NEXT(node) (node)->next
#define BINODE_PREV(node) (node)->prev
#define BILIST_NODE_OF(type, node, field) ((type *)((char *)(node) - OFFSET_OF(type, field)))
#define BILIST_FOREACH(p_node, t_list) \
for ((p_node) = (t_list).head; (p_node) != NULL; (p_node) = BINODE_NEXT((p_node)))
#define BILIST_SEARCH(list, type, node, field, cond) \
do { \
bilist_node_t *_tmp_ = (list)->head; \
while (_tmp_ != NULL) { \
(node) = BILIST_NODE_OF(type, _tmp_, field); \
if (cond) { \
break; \
} \
(node) = NULL; \
_tmp_ = BINODE_NEXT(_tmp_); \
} \
} while (0)
typedef struct st_bilist_node {
struct st_bilist_node *prev;
struct st_bilist_node *next;
} bilist_node_t;
#pragma pack(4)
typedef struct st_bilist {
bilist_node_t *head;
bilist_node_t *tail;
uint32 count;
} bilist_t;
#pragma pack()
static inline void cm_bilist_init(bilist_t *bilist)
{
bilist->count = 0;
bilist->head = bilist->tail = NULL;
}
static inline void cm_bilist_node_init(bilist_node_t *node)
{
node->prev = node->next = NULL;
}
static inline bilist_node_t *cm_bilist_tail(bilist_t *bilist)
{
return bilist->tail;
}
static inline bilist_node_t *cm_bilist_head(bilist_t *bilist)
{
return bilist->head;
}
static inline bool32 cm_bilist_empty(bilist_t *bilist)
{
return bilist->count == 0;
}
static inline void cm_bilist_concat(bilist_t *bilist1, bilist_t *bilist2)
{
if (bilist1->count == 0) {
*bilist1 = *bilist2;
return;
}
bilist1->tail->next = bilist2->head;
if (bilist2->head != NULL) {
bilist2->head->prev = bilist1->tail;
}
bilist1->tail = bilist2->tail;
bilist1->count += bilist2->count;
}
void cm_bilist_del_tail(bilist_t *bilist);
void cm_bilist_del_head(bilist_t *bilist);
void cm_bilist_del(bilist_node_t *node, bilist_t *bilist);
void cm_bilist_add_tail(bilist_node_t *node, bilist_t *bilist);
void cm_bilist_add_head(bilist_node_t *node, bilist_t *bilist);
void cm_bilist_add_prev(bilist_node_t *node, bilist_node_t *where, bilist_t *bilist);
void cm_bilist_add_next(bilist_node_t *node, bilist_node_t *where, bilist_t *bilist);
bilist_node_t *cm_bilist_get(bilist_t *bilist, uint32 index);
bilist_node_t* cm_bilist_remove_head(bilist_t *bilist);
bilist_node_t* cm_bilist_remove_tail(bilist_t *bilist);
#endif