1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (c) Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #ifndef __OCF_LIST_H__ 7 #define __OCF_LIST_H__ 8 9 #define LIST_POISON1 ((void *) 0x00100100) 10 #define LIST_POISON2 ((void *) 0x00200200) 11 12 /** 13 * List entry structure mimicking linux kernel based one. 14 */ 15 struct list_head { 16 struct list_head *next; 17 struct list_head *prev; 18 } __attribute__((aligned(64))); 19 20 /** 21 * start an empty list 22 */ 23 #define INIT_LIST_HEAD(l) { (l)->prev = l; (l)->next = l; } 24 25 /** 26 * Add item to list head. 27 * @param it list entry to be added 28 * @param l1 list main node (head) 29 */ 30 static inline void 31 list_add(struct list_head *it, struct list_head *l1) 32 { 33 it->prev = l1; 34 it->next = l1->next; 35 36 l1->next->prev = it; 37 l1->next = it; 38 } 39 40 /** 41 * Add item it to tail. 42 * @param it list entry to be added 43 * @param l1 list main node (head) 44 */ 45 static inline void 46 list_add_tail(struct list_head *it, struct list_head *l1) 47 { 48 it->prev = l1->prev; 49 it->next = l1; 50 51 l1->prev->next = it; 52 l1->prev = it; 53 } 54 55 /** 56 * check if a list is empty (return true) 57 */ 58 static inline int 59 list_empty(struct list_head *it) 60 { 61 return it->next == it; 62 } 63 64 /** 65 * delete an entry from a list 66 */ 67 static inline void 68 list_del(struct list_head *it) 69 { 70 it->next->prev = it->prev; 71 it->prev->next = it->next; 72 } 73 74 static inline void 75 list_move_tail(struct list_head *list, 76 struct list_head *head) 77 { 78 list_del(list); 79 list_add_tail(list, head); 80 } 81 82 static inline void 83 list_move(struct list_head *list, 84 struct list_head *head) 85 { 86 list_del(list); 87 list_add(list, head); 88 } 89 90 /** 91 * Extract an entry. 92 * @param list_head_i list head item, from which entry is extracted 93 * @param item_type type (struct) of list entry 94 * @param field_name name of list_head field within item_type 95 */ 96 #define list_entry(list_head_i, item_type, field_name) \ 97 (item_type *)(((void*)(list_head_i)) - offsetof(item_type, field_name)) 98 99 #define list_first_entry(list_head_i, item_type, field_name) \ 100 list_entry((list_head_i)->next, item_type, field_name) 101 102 /** 103 * @param iterator uninitialized list_head pointer, to be used as iterator 104 * @param plist list head (main node) 105 */ 106 #define list_for_each(iterator, plist) \ 107 for (iterator = (plist)->next; \ 108 (iterator)->next != (plist)->next; \ 109 iterator = (iterator)->next) 110 111 /** 112 * Safe version of list_for_each which works even if entries are deleted during 113 * loop. 114 * @param iterator uninitialized list_head pointer, to be used as iterator 115 * @param q another uninitialized list_head, used as helper 116 * @param plist list head (main node) 117 */ 118 /* 119 * Algorithm handles situation, where q is deleted. 120 * consider in example 3 element list with header h: 121 * 122 * h -> 1 -> 2 -> 3 -> 123 *1. i q 124 * 125 *2. i q 126 * 127 *3. q i 128 */ 129 #define list_for_each_safe(iterator, q, plist) \ 130 for (iterator = (q = (plist)->next->next)->prev; \ 131 (q) != (plist)->next; \ 132 iterator = (q = (q)->next)->prev) 133 134 #define _list_entry_helper(item, head, field_name) list_entry(head, typeof(*item), field_name) 135 136 /** 137 * Iterate over list entries. 138 * @param list pointer to list item (iterator) 139 * @param plist pointer to list_head item 140 * @param field_name name of list_head field in list entry 141 */ 142 #define list_for_each_entry(item, plist, field_name) \ 143 for (item = _list_entry_helper(item, (plist)->next, field_name); \ 144 _list_entry_helper(item, (item)->field_name.next, field_name) !=\ 145 _list_entry_helper(item, (plist)->next, field_name); \ 146 item = _list_entry_helper(item, (item)->field_name.next, field_name)) 147 148 /** 149 * Safe version of list_for_each_entry which works even if entries are deleted 150 * during loop. 151 * @param list pointer to list item (iterator) 152 * @param q another pointer to list item, used as helper 153 * @param plist pointer to list_head item 154 * @param field_name name of list_head field in list entry 155 */ 156 #define list_for_each_entry_safe(item, q, plist, field_name) \ 157 for (item = _list_entry_helper(item, (plist)->next, field_name), \ 158 q = _list_entry_helper(item, (item)->field_name.next, field_name); \ 159 _list_entry_helper(item, (item)->field_name.next, field_name) != \ 160 _list_entry_helper(item, (plist)->next, field_name); \ 161 item = q, q = _list_entry_helper(q, (q)->field_name.next, field_name)) 162 163 #endif 164