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