Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2018-2021, Arm Limited. All rights reserved. |
| 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | * |
| 6 | */ |
| 7 | #ifndef __LISTS_H__ |
| 8 | #define __LISTS_H__ |
| 9 | |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 10 | /********* Bi-directional list operations ********/ |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 11 | /* Bi-directional list structure */ |
| 12 | struct bi_list_node_t { |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 13 | struct bi_list_node_t *bprev; |
| 14 | struct bi_list_node_t *bnext; |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 15 | }; |
| 16 | |
| 17 | /* Init an empty node. */ |
| 18 | #define BI_LIST_INIT_NODE(node) do { \ |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 19 | (node)->bnext = node; \ |
| 20 | (node)->bprev = node; \ |
| 21 | } while (0) |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 22 | |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 23 | /* Insert a new node after current node: (bnext) of current. */ |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 24 | #define BI_LIST_INSERT_AFTER(curr, node) do { \ |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 25 | (node)->bnext = (curr)->bnext; \ |
| 26 | (node)->bprev = curr; \ |
| 27 | (curr)->bnext->bprev = node; \ |
| 28 | (curr)->bnext = node; \ |
| 29 | } while (0) |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 30 | |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 31 | /* Add one node into list as the tail: (bprev) of head. */ |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 32 | #define BI_LIST_INSERT_BEFORE(curr, node) do { \ |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 33 | (curr)->bprev->bnext = node; \ |
| 34 | (node)->bprev = (curr)->bprev; \ |
| 35 | (curr)->bprev = node; \ |
| 36 | (node)->bnext = curr; \ |
| 37 | } while (0) |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 38 | |
| 39 | /* Remove one node from the list. */ |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 40 | #define BI_LIST_REMOVE_NODE(node) do { \ |
| 41 | (node)->bprev->bnext = (node)->bnext; \ |
| 42 | (node)->bnext->bprev = (node)->bprev; \ |
| 43 | } while (0) |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 44 | |
| 45 | /* Is the head empty? */ |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 46 | #define BI_LIST_IS_EMPTY(head) ((head)->bnext == (head)) |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 47 | |
| 48 | /* The node's next node */ |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 49 | #define BI_LIST_NEXT_NODE(node) ((node)->bnext) |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 50 | |
| 51 | /* Go through each node of a list */ |
| 52 | #define BI_LIST_FOR_EACH(node, head) \ |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 53 | for (node = (head)->bnext; node != head; node = (node)->bnext) |
| 54 | |
| 55 | /********* Uni-directional list operations ********/ |
| 56 | /* |
| 57 | * To use these single linked list operations, a head node must have been |
| 58 | * defined already, and the "next" pointer initialized to "NULL". Like: |
| 59 | * struct head_t { |
| 60 | * uint32_t data; |
| 61 | * User_Type *next; |
| 62 | * } head; |
| 63 | */ |
| 64 | |
| 65 | /* Initialize the head node */ |
| 66 | #define UNI_LISI_INIT_HEAD(head) do { \ |
Mingyang Sun | 40c6359 | 2021-06-30 19:08:48 +0800 | [diff] [blame] | 67 | if ((head) != NULL) { \ |
Mingyang Sun | e5c151d | 2021-05-25 21:04:12 +0800 | [diff] [blame] | 68 | (head)->next = NULL; \ |
| 69 | } \ |
| 70 | } while (0) |
| 71 | |
| 72 | /* Insert a node after current node */ |
| 73 | #define UNI_LIST_INSERT_AFTER(curr, node) do { \ |
| 74 | (node)->next = (curr)->next; \ |
| 75 | (curr)->next = node; \ |
| 76 | } while (0) |
| 77 | |
| 78 | /* Go through each node of a list */ |
| 79 | #define UNI_LIST_FOR_EACH(node, head) \ |
| 80 | for (node = (head)->next; node != NULL; node = (node)->next) |
Ken Liu | 2c47f7f | 2021-01-22 11:06:04 +0800 | [diff] [blame] | 81 | |
| 82 | #endif /* __LISTS_H__ */ |