1f08c3bdfSopenharmony_ci#ifndef PTR_LIST_H 2f08c3bdfSopenharmony_ci#define PTR_LIST_H 3f08c3bdfSopenharmony_ci 4f08c3bdfSopenharmony_ci#include <stdlib.h> 5f08c3bdfSopenharmony_ci#include <stdbool.h> 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/* 8f08c3bdfSopenharmony_ci * Generic pointer list manipulation code. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * (C) Copyright Linus Torvalds 2003-2005 11f08c3bdfSopenharmony_ci */ 12f08c3bdfSopenharmony_ci 13f08c3bdfSopenharmony_ci/* Silly type-safety check ;) */ 14f08c3bdfSopenharmony_ci#define CHECK_TYPE(head,ptr) (void)(&(ptr) == &(head)->list[0]) 15f08c3bdfSopenharmony_ci#define PTRLIST_TYPE(head) __typeof__((head)->list[0]) 16f08c3bdfSopenharmony_ci#define VRFY_PTR_LIST(head) (void)(sizeof((head)->list[0])) 17f08c3bdfSopenharmony_ci 18f08c3bdfSopenharmony_ci#define LIST_NODE_NR (13) 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci#define DECLARE_PTR_LIST(listname, type) \ 21f08c3bdfSopenharmony_ci struct listname { \ 22f08c3bdfSopenharmony_ci int nr:8; \ 23f08c3bdfSopenharmony_ci int rm:8; \ 24f08c3bdfSopenharmony_ci struct listname *prev; \ 25f08c3bdfSopenharmony_ci struct listname *next; \ 26f08c3bdfSopenharmony_ci type *list[LIST_NODE_NR]; \ 27f08c3bdfSopenharmony_ci } 28f08c3bdfSopenharmony_ci 29f08c3bdfSopenharmony_ciDECLARE_PTR_LIST(ptr_list, void); 30f08c3bdfSopenharmony_ci 31f08c3bdfSopenharmony_ci 32f08c3bdfSopenharmony_civoid * undo_ptr_list_last(struct ptr_list **head); 33f08c3bdfSopenharmony_civoid * delete_ptr_list_last(struct ptr_list **head); 34f08c3bdfSopenharmony_ciint delete_ptr_list_entry(struct ptr_list **, void *, int); 35f08c3bdfSopenharmony_ciint replace_ptr_list_entry(struct ptr_list **, void *old, void *new, int); 36f08c3bdfSopenharmony_cibool lookup_ptr_list_entry(const struct ptr_list *head, const void *entry); 37f08c3bdfSopenharmony_ciextern void sort_list(struct ptr_list **, int (*)(const void *, const void *)); 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_ciextern void concat_ptr_list(struct ptr_list *a, struct ptr_list **b); 40f08c3bdfSopenharmony_ciextern void copy_ptr_list(struct ptr_list **h, struct ptr_list *t); 41f08c3bdfSopenharmony_ciextern int ptr_list_size(struct ptr_list *); 42f08c3bdfSopenharmony_ciextern bool ptr_list_empty(const struct ptr_list *head); 43f08c3bdfSopenharmony_ciextern bool ptr_list_multiple(const struct ptr_list *head); 44f08c3bdfSopenharmony_ciextern int linearize_ptr_list(struct ptr_list *, void **, int); 45f08c3bdfSopenharmony_ciextern void *first_ptr_list(struct ptr_list *); 46f08c3bdfSopenharmony_ciextern void *last_ptr_list(struct ptr_list *); 47f08c3bdfSopenharmony_ciextern void *ptr_list_nth_entry(struct ptr_list *, unsigned int idx); 48f08c3bdfSopenharmony_ciextern void pack_ptr_list(struct ptr_list **); 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci/* 51f08c3bdfSopenharmony_ci * Hey, who said that you can't do overloading in C? 52f08c3bdfSopenharmony_ci * 53f08c3bdfSopenharmony_ci * You just have to be creative, and use some gcc 54f08c3bdfSopenharmony_ci * extensions.. 55f08c3bdfSopenharmony_ci */ 56f08c3bdfSopenharmony_ciextern void **__add_ptr_list(struct ptr_list **, void *); 57f08c3bdfSopenharmony_ciextern void **__add_ptr_list_tag(struct ptr_list **, void *, unsigned long); 58f08c3bdfSopenharmony_ci 59f08c3bdfSopenharmony_ci#define add_ptr_list(list, ptr) ({ \ 60f08c3bdfSopenharmony_ci struct ptr_list** head = (struct ptr_list**)(list); \ 61f08c3bdfSopenharmony_ci CHECK_TYPE(*(list),ptr); \ 62f08c3bdfSopenharmony_ci (__typeof__(&(ptr))) __add_ptr_list(head, ptr); \ 63f08c3bdfSopenharmony_ci }) 64f08c3bdfSopenharmony_ci#define add_ptr_list_tag(list, ptr, tag) ({ \ 65f08c3bdfSopenharmony_ci struct ptr_list** head = (struct ptr_list**)(list); \ 66f08c3bdfSopenharmony_ci CHECK_TYPE(*(list),ptr); \ 67f08c3bdfSopenharmony_ci (__typeof__(&(ptr))) __add_ptr_list_tag(head, ptr, tag);\ 68f08c3bdfSopenharmony_ci }) 69f08c3bdfSopenharmony_ci 70f08c3bdfSopenharmony_ci#define pop_ptr_list(l) ({ \ 71f08c3bdfSopenharmony_ci PTRLIST_TYPE(*(l)) ptr; \ 72f08c3bdfSopenharmony_ci ptr = delete_ptr_list_last((struct ptr_list**)(l)); \ 73f08c3bdfSopenharmony_ci ptr; \ 74f08c3bdfSopenharmony_ci }) 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ciextern void __free_ptr_list(struct ptr_list **); 77f08c3bdfSopenharmony_ci#define free_ptr_list(list) do { \ 78f08c3bdfSopenharmony_ci VRFY_PTR_LIST(*(list)); \ 79f08c3bdfSopenharmony_ci __free_ptr_list((struct ptr_list **)(list)); \ 80f08c3bdfSopenharmony_ci } while (0) 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ci#define ptr_list_nth(lst, nth) ({ \ 83f08c3bdfSopenharmony_ci struct ptr_list* head = (struct ptr_list*)(lst); \ 84f08c3bdfSopenharmony_ci (PTRLIST_TYPE(lst)) ptr_list_nth_entry(head, nth);\ 85f08c3bdfSopenharmony_ci }) 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci#define ptr_list_to_array(list, array, size) ({ \ 88f08c3bdfSopenharmony_ci struct ptr_list* head = (struct ptr_list*)(list); \ 89f08c3bdfSopenharmony_ci CHECK_TYPE(list, *array); \ 90f08c3bdfSopenharmony_ci linearize_ptr_list(head, (void**)array, size); \ 91f08c3bdfSopenharmony_ci }) 92f08c3bdfSopenharmony_ci 93f08c3bdfSopenharmony_ci//////////////////////////////////////////////////////////////////////// 94f08c3bdfSopenharmony_ci// API 95f08c3bdfSopenharmony_ci#define PREPARE_PTR_LIST(head, ptr) \ 96f08c3bdfSopenharmony_ci DO_PREPARE(head, ptr, __head##ptr, __list##ptr, __nr##ptr, PTR_ENTRY_UNTAG) 97f08c3bdfSopenharmony_ci 98f08c3bdfSopenharmony_ci#define NEXT_PTR_LIST(ptr) \ 99f08c3bdfSopenharmony_ci DO_NEXT(ptr, __head##ptr, __list##ptr, __nr##ptr, PTR_ENTRY_UNTAG) 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ci#define RESET_PTR_LIST(ptr) \ 102f08c3bdfSopenharmony_ci DO_RESET(ptr, __head##ptr, __list##ptr, __nr##ptr, PTR_ENTRY_UNTAG) 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci#define FINISH_PTR_LIST(ptr) \ 105f08c3bdfSopenharmony_ci DO_FINISH(ptr, __head##ptr, __list##ptr, __nr##ptr) 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci#define RECURSE_PTR_REVERSE(ptr, new) \ 108f08c3bdfSopenharmony_ci DO_REVERSE(ptr, __head##ptr, __list##ptr, __nr##ptr, __rname##new, \ 109f08c3bdfSopenharmony_ci new, __head##new, __list##new, __nr##new, PTR_ENTRY_UNTAG) 110f08c3bdfSopenharmony_ci 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_ci#define FOR_EACH_PTR(head, ptr) \ 113f08c3bdfSopenharmony_ci DO_FOR_EACH(head, ptr, __head##ptr, __list##ptr, __nr##ptr, __name##ptr, PTR_ENTRY_NOTAG) 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ci#define FOR_EACH_PTR_TAG(head, ptr) \ 116f08c3bdfSopenharmony_ci DO_FOR_EACH(head, ptr, __head##ptr, __list##ptr, __nr##ptr, __name##ptr, PTR_ENTRY_UNTAG) 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci#define END_FOR_EACH_PTR(ptr) \ 119f08c3bdfSopenharmony_ci DO_END_FOR_EACH(ptr, __head##ptr, __list##ptr, __nr##ptr, __name##ptr) 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_ci#define FOR_EACH_PTR_REVERSE(head, ptr) \ 122f08c3bdfSopenharmony_ci DO_FOR_EACH_REVERSE(head, ptr, __head##ptr, __list##ptr, __nr##ptr, __rname##ptr, PTR_ENTRY_NOTAG) 123f08c3bdfSopenharmony_ci 124f08c3bdfSopenharmony_ci#define FOR_EACH_PTR_REVERSE_TAG(head, ptr) \ 125f08c3bdfSopenharmony_ci DO_FOR_EACH_REVERSE(head, ptr, __head##ptr, __list##ptr, __nr##ptr, __rname##ptr, PTR_ENTRY_UNTAG) 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci#define END_FOR_EACH_PTR_REVERSE(ptr) \ 128f08c3bdfSopenharmony_ci DO_END_FOR_EACH_REVERSE(ptr, __head##ptr, __list##ptr, __nr##ptr, __rname##ptr) 129f08c3bdfSopenharmony_ci 130f08c3bdfSopenharmony_ci#define THIS_ADDRESS(ptr) \ 131f08c3bdfSopenharmony_ci DO_THIS_ADDRESS(ptr, __head##ptr, __list##ptr, __nr##ptr) 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci#define INSERT_CURRENT(new, ptr) \ 134f08c3bdfSopenharmony_ci DO_INSERT_CURRENT(new, __head##ptr, __list##ptr, __nr##ptr) 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci#define DELETE_CURRENT_PTR(ptr) \ 137f08c3bdfSopenharmony_ci DO_DELETE_CURRENT(__head##ptr, __list##ptr, __nr##ptr) 138f08c3bdfSopenharmony_ci 139f08c3bdfSopenharmony_ci#define REPLACE_CURRENT_PTR(ptr, new_ptr) \ 140f08c3bdfSopenharmony_ci do { *THIS_ADDRESS(ptr) = (new_ptr); } while (0) 141f08c3bdfSopenharmony_ci 142f08c3bdfSopenharmony_ci// This replace the current element by a null-pointer. 143f08c3bdfSopenharmony_ci// It's used when an element of the list must be removed 144f08c3bdfSopenharmony_ci// but the address of the other elements must not be changed. 145f08c3bdfSopenharmony_ci#define MARK_CURRENT_DELETED(ptr) \ 146f08c3bdfSopenharmony_ci DO_MARK_CURRENT_DELETED(ptr, __list##ptr) 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_ci#define PACK_PTR_LIST(x) \ 149f08c3bdfSopenharmony_ci pack_ptr_list((struct ptr_list **)(x)) 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_ci#define CURRENT_TAG(ptr) (3 & (unsigned long)*THIS_ADDRESS(ptr)) 152f08c3bdfSopenharmony_ci#define TAG_CURRENT(ptr,val) update_tag(THIS_ADDRESS(ptr),val) 153f08c3bdfSopenharmony_ci 154f08c3bdfSopenharmony_ci// backward compatibility for smatch 155f08c3bdfSopenharmony_ci#define FOR_EACH_PTR_NOTAG(list, ptr) FOR_EACH_PTR(list, ptr) 156f08c3bdfSopenharmony_ci#define END_FOR_EACH_PTR_NOTAG(ptr) END_FOR_EACH_PTR(ptr) 157f08c3bdfSopenharmony_ci 158f08c3bdfSopenharmony_ci//////////////////////////////////////////////////////////////////////// 159f08c3bdfSopenharmony_ci// Implementation 160f08c3bdfSopenharmony_ci#define PTR_UNTAG(p) ((void*)(~3UL & (unsigned long)(p))) 161f08c3bdfSopenharmony_ci#define PTR_ENTRY_NOTAG(h,i) ((h)->list[i]) 162f08c3bdfSopenharmony_ci#define PTR_ENTRY_UNTAG(h,i) PTR_UNTAG((h)->list[i]) 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ci 165f08c3bdfSopenharmony_ci#define PTR_NEXT(ptr, __head, __list, __nr, PTR_ENTRY) \ 166f08c3bdfSopenharmony_ci do { \ 167f08c3bdfSopenharmony_ci if (__nr < __list->nr) { \ 168f08c3bdfSopenharmony_ci ptr = PTR_ENTRY(__list,__nr); \ 169f08c3bdfSopenharmony_ci __nr++; \ 170f08c3bdfSopenharmony_ci break; \ 171f08c3bdfSopenharmony_ci } \ 172f08c3bdfSopenharmony_ci ptr = NULL; \ 173f08c3bdfSopenharmony_ci __nr = 0; \ 174f08c3bdfSopenharmony_ci } while ((__list = __list->next) != __head) \ 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ci#define DO_PREPARE(head, ptr, __head, __list, __nr, PTR_ENTRY) \ 177f08c3bdfSopenharmony_ci do { \ 178f08c3bdfSopenharmony_ci __typeof__(head) __head = (head); \ 179f08c3bdfSopenharmony_ci __typeof__(head) __list = __head; \ 180f08c3bdfSopenharmony_ci int __nr = 0; \ 181f08c3bdfSopenharmony_ci ptr = NULL; \ 182f08c3bdfSopenharmony_ci if (__head) { \ 183f08c3bdfSopenharmony_ci PTR_NEXT(ptr, __head, __list, __nr, PTR_ENTRY); \ 184f08c3bdfSopenharmony_ci } \ 185f08c3bdfSopenharmony_ci 186f08c3bdfSopenharmony_ci#define DO_NEXT(ptr, __head, __list, __nr, PTR_ENTRY) \ 187f08c3bdfSopenharmony_ci if (ptr) { \ 188f08c3bdfSopenharmony_ci PTR_NEXT(ptr, __head, __list, __nr, PTR_ENTRY); \ 189f08c3bdfSopenharmony_ci } 190f08c3bdfSopenharmony_ci 191f08c3bdfSopenharmony_ci#define DO_RESET(ptr, __head, __list, __nr, PTR_ENTRY) \ 192f08c3bdfSopenharmony_ci do { \ 193f08c3bdfSopenharmony_ci __nr = 0; \ 194f08c3bdfSopenharmony_ci __list = __head; \ 195f08c3bdfSopenharmony_ci if (__head) \ 196f08c3bdfSopenharmony_ci PTR_NEXT(ptr, __head, __list, __nr, PTR_ENTRY); \ 197f08c3bdfSopenharmony_ci } while (0) 198f08c3bdfSopenharmony_ci 199f08c3bdfSopenharmony_ci#define DO_FINISH(ptr, __head, __list, __nr) \ 200f08c3bdfSopenharmony_ci VRFY_PTR_LIST(__head); /* Sanity-check nesting */ \ 201f08c3bdfSopenharmony_ci } while (0) 202f08c3bdfSopenharmony_ci 203f08c3bdfSopenharmony_ci#define DO_FOR_EACH(head, ptr, __head, __list, __nr, __name, PTR_ENTRY) do { \ 204f08c3bdfSopenharmony_ci __typeof__(head) __head = (head); \ 205f08c3bdfSopenharmony_ci __typeof__(head) __list = __head; \ 206f08c3bdfSopenharmony_ci __typeof__(head) __name = __head; \ 207f08c3bdfSopenharmony_ci int __nr; \ 208f08c3bdfSopenharmony_ci if (!__head) \ 209f08c3bdfSopenharmony_ci break; \ 210f08c3bdfSopenharmony_ci do { \ 211f08c3bdfSopenharmony_ci for (__nr = 0; __nr < __list->nr; __nr++) { \ 212f08c3bdfSopenharmony_ci ptr = PTR_ENTRY(__list,__nr); \ 213f08c3bdfSopenharmony_ci if (__list->rm && !ptr) \ 214f08c3bdfSopenharmony_ci continue; \ 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci#define DO_END_FOR_EACH(ptr, __head, __list, __nr, __name) \ 217f08c3bdfSopenharmony_ci } \ 218f08c3bdfSopenharmony_ci } while ((__list = __list->next) != __head); \ 219f08c3bdfSopenharmony_ci (void) __name; \ 220f08c3bdfSopenharmony_ci} while (0) 221f08c3bdfSopenharmony_ci 222f08c3bdfSopenharmony_ci#define DO_FOR_EACH_REVERSE(head, ptr, __head, __list, __nr, __name, PTR_ENTRY) do { \ 223f08c3bdfSopenharmony_ci __typeof__(head) __head = (head); \ 224f08c3bdfSopenharmony_ci __typeof__(head) __list = __head; \ 225f08c3bdfSopenharmony_ci __typeof__(head) __name = __head; \ 226f08c3bdfSopenharmony_ci int __nr; \ 227f08c3bdfSopenharmony_ci if (!head) \ 228f08c3bdfSopenharmony_ci break; \ 229f08c3bdfSopenharmony_ci do { \ 230f08c3bdfSopenharmony_ci __list = __list->prev; \ 231f08c3bdfSopenharmony_ci __nr = __list->nr; \ 232f08c3bdfSopenharmony_ci while (--__nr >= 0) { \ 233f08c3bdfSopenharmony_ci ptr = PTR_ENTRY(__list,__nr); \ 234f08c3bdfSopenharmony_ci if (__list->rm && !ptr) \ 235f08c3bdfSopenharmony_ci continue; \ 236f08c3bdfSopenharmony_ci 237f08c3bdfSopenharmony_ci 238f08c3bdfSopenharmony_ci#define DO_END_FOR_EACH_REVERSE(ptr, __head, __list, __nr, __name) \ 239f08c3bdfSopenharmony_ci } \ 240f08c3bdfSopenharmony_ci } while (__list != __head); \ 241f08c3bdfSopenharmony_ci (void) __name; \ 242f08c3bdfSopenharmony_ci} while (0) 243f08c3bdfSopenharmony_ci 244f08c3bdfSopenharmony_ci#define DO_REVERSE(ptr, __head, __list, __nr, __name, new, __newhead, \ 245f08c3bdfSopenharmony_ci __newlist, __newnr, PTR_ENTRY) do { \ 246f08c3bdfSopenharmony_ci __typeof__(__head) __newhead = __head; \ 247f08c3bdfSopenharmony_ci __typeof__(__head) __newlist = __list; \ 248f08c3bdfSopenharmony_ci __typeof__(__head) __name = __list; \ 249f08c3bdfSopenharmony_ci int __newnr = __nr; \ 250f08c3bdfSopenharmony_ci new = ptr; \ 251f08c3bdfSopenharmony_ci goto __inside##new; \ 252f08c3bdfSopenharmony_ci do { \ 253f08c3bdfSopenharmony_ci __newlist = __newlist->prev; \ 254f08c3bdfSopenharmony_ci __newnr = __newlist->nr; \ 255f08c3bdfSopenharmony_ci __inside##new: \ 256f08c3bdfSopenharmony_ci while (--__newnr >= 0) { \ 257f08c3bdfSopenharmony_ci new = PTR_ENTRY(__newlist,__newnr); \ 258f08c3bdfSopenharmony_ci 259f08c3bdfSopenharmony_ci#define DO_THIS_ADDRESS(ptr, __head, __list, __nr) \ 260f08c3bdfSopenharmony_ci (&__list->list[__nr]) 261f08c3bdfSopenharmony_ci 262f08c3bdfSopenharmony_ci 263f08c3bdfSopenharmony_ciextern void split_ptr_list_head(struct ptr_list *); 264f08c3bdfSopenharmony_ci 265f08c3bdfSopenharmony_ci#define DO_INSERT_CURRENT(new, __head, __list, __nr) do { \ 266f08c3bdfSopenharmony_ci PTRLIST_TYPE(__head) *__this, *__last; \ 267f08c3bdfSopenharmony_ci if (__list->nr == LIST_NODE_NR) { \ 268f08c3bdfSopenharmony_ci split_ptr_list_head((struct ptr_list*)__list); \ 269f08c3bdfSopenharmony_ci if (__nr >= __list->nr) { \ 270f08c3bdfSopenharmony_ci __nr -= __list->nr; \ 271f08c3bdfSopenharmony_ci __list = __list->next; \ 272f08c3bdfSopenharmony_ci } \ 273f08c3bdfSopenharmony_ci } \ 274f08c3bdfSopenharmony_ci __this = __list->list + __nr; \ 275f08c3bdfSopenharmony_ci __last = __list->list + __list->nr - 1; \ 276f08c3bdfSopenharmony_ci while (__last >= __this) { \ 277f08c3bdfSopenharmony_ci __last[1] = __last[0]; \ 278f08c3bdfSopenharmony_ci __last--; \ 279f08c3bdfSopenharmony_ci } \ 280f08c3bdfSopenharmony_ci *__this = (new); \ 281f08c3bdfSopenharmony_ci __list->nr++; \ 282f08c3bdfSopenharmony_ci} while (0) 283f08c3bdfSopenharmony_ci 284f08c3bdfSopenharmony_ci#define DO_DELETE_CURRENT(__head, __list, __nr) do { \ 285f08c3bdfSopenharmony_ci PTRLIST_TYPE(__head) *__this = __list->list + __nr; \ 286f08c3bdfSopenharmony_ci PTRLIST_TYPE(__head) *__last = __list->list + __list->nr - 1; \ 287f08c3bdfSopenharmony_ci while (__this < __last) { \ 288f08c3bdfSopenharmony_ci __this[0] = __this[1]; \ 289f08c3bdfSopenharmony_ci __this++; \ 290f08c3bdfSopenharmony_ci } \ 291f08c3bdfSopenharmony_ci *__this = (void *)0xf0f0f0f0; \ 292f08c3bdfSopenharmony_ci __list->nr--; __nr--; \ 293f08c3bdfSopenharmony_ci} while (0) 294f08c3bdfSopenharmony_ci 295f08c3bdfSopenharmony_ci 296f08c3bdfSopenharmony_ci#define DO_MARK_CURRENT_DELETED(ptr, __list) do { \ 297f08c3bdfSopenharmony_ci REPLACE_CURRENT_PTR(ptr, NULL); \ 298f08c3bdfSopenharmony_ci __list->rm++; \ 299f08c3bdfSopenharmony_ci } while (0) 300f08c3bdfSopenharmony_ci 301f08c3bdfSopenharmony_ci 302f08c3bdfSopenharmony_cistatic inline void update_tag(void *p, unsigned long tag) 303f08c3bdfSopenharmony_ci{ 304f08c3bdfSopenharmony_ci unsigned long *ptr = p; 305f08c3bdfSopenharmony_ci *ptr = tag | (~3UL & *ptr); 306f08c3bdfSopenharmony_ci} 307f08c3bdfSopenharmony_ci 308f08c3bdfSopenharmony_cistatic inline void *tag_ptr(void *ptr, unsigned long tag) 309f08c3bdfSopenharmony_ci{ 310f08c3bdfSopenharmony_ci return (void *)(tag | (unsigned long)ptr); 311f08c3bdfSopenharmony_ci} 312f08c3bdfSopenharmony_ci 313f08c3bdfSopenharmony_ci#endif /* PTR_LIST_H */ 314