4 * Pointer list manipulation
6 * (C) Copyright Linus Torvalds 2003-2005
14 int ptr_list_size(struct ptr_list
*head
)
19 struct ptr_list
*list
= head
;
22 } while ((list
= list
->next
) != head
);
28 * Linearize the entries of a list up to a total of 'max',
29 * and return the nr of entries linearized.
31 * The array to linearize into (second argument) should really
32 * be "void *x[]", but we want to let people fill in any kind
33 * of pointer array, so let's just call it "void *".
35 int linearize_ptr_list(struct ptr_list
*head
, void **arr
, int max
)
38 if (head
&& max
> 0) {
39 struct ptr_list
*list
= head
;
45 memcpy(arr
, list
->list
, i
*sizeof(void *));
51 } while ((list
= list
->next
) != head
);
57 * When we've walked the list and deleted entries,
58 * we may need to re-pack it so that we don't have
59 * any empty blocks left (empty blocks upset the
62 void pack_ptr_list(struct ptr_list
**listp
)
64 struct ptr_list
*head
= *listp
;
67 struct ptr_list
*entry
= head
;
69 struct ptr_list
*next
;
73 struct ptr_list
*prev
;
90 } while (entry
!= head
);
94 void split_ptr_list_head(struct ptr_list
*head
)
96 int old
= head
->nr
, nr
= old
/ 2;
97 struct ptr_list
*newlist
= malloc(sizeof(*newlist
));
98 struct ptr_list
*next
= head
->next
;
102 newlist
->next
= next
;
103 next
->prev
= newlist
;
104 newlist
->prev
= head
;
105 head
->next
= newlist
;
107 memcpy(newlist
->list
, head
->list
+ old
, nr
* sizeof(void *));
108 memset(head
->list
+ old
, 0xf0, nr
* sizeof(void *));
111 void **__add_ptr_list(struct ptr_list
**listp
, void *ptr
, unsigned long tag
)
113 struct ptr_list
*list
= *listp
;
114 struct ptr_list
*last
= NULL
; /* gcc complains needlessly */
118 /* The low two bits are reserved for tags */
119 assert((3 & (unsigned long)ptr
) == 0);
120 assert((~3 & tag
) == 0);
121 ptr
= (void *)(tag
| (unsigned long)ptr
);
123 if (!list
|| (nr
= (last
= list
->prev
)->nr
) >= LIST_NODE_NR
) {
124 struct ptr_list
*newlist
= malloc(sizeof(*newlist
));
126 memset(newlist
, 0, sizeof(*newlist
));
128 newlist
->next
= newlist
;
129 newlist
->prev
= newlist
;
132 newlist
->prev
= last
;
133 newlist
->next
= list
;
134 list
->prev
= newlist
;
135 last
->next
= newlist
;
140 ret
= last
->list
+ nr
;
147 int delete_ptr_list_entry(struct ptr_list
**list
, void *entry
, int count
)
151 FOR_EACH_PTR(*list
, ptr
) {
153 DELETE_CURRENT_PTR(ptr
);
157 } END_FOR_EACH_PTR(ptr
);
164 int replace_ptr_list_entry(struct ptr_list
**list
, void *old_ptr
, void *new_ptr
, int count
)
168 FOR_EACH_PTR(*list
, ptr
) {
170 REPLACE_CURRENT_PTR(ptr
, new_ptr
);
174 }END_FOR_EACH_PTR(ptr
);
180 void * delete_ptr_list_last(struct ptr_list
**head
)
183 struct ptr_list
*last
, *first
= *head
;
189 ptr
= last
->list
[--last
->nr
];
191 first
->prev
= last
->prev
;
192 last
->prev
->next
= first
;
200 void concat_ptr_list(struct ptr_list
*a
, struct ptr_list
**b
)
203 FOR_EACH_PTR(a
, entry
) {
204 add_ptr_list(b
, entry
);
205 } END_FOR_EACH_PTR(entry
);
208 void __free_ptr_list(struct ptr_list
**listp
)
210 struct ptr_list
*tmp
, *list
= *listp
;
215 list
->prev
->next
= NULL
;