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
;
91 } while (entry
!= head
);
95 void split_ptr_list_head(struct ptr_list
*head
)
97 int old
= head
->nr
, nr
= old
/ 2;
98 struct ptr_list
*newlist
= malloc(sizeof(*newlist
));
99 struct ptr_list
*next
= head
->next
;
103 newlist
->next
= next
;
104 next
->prev
= newlist
;
105 newlist
->prev
= head
;
106 head
->next
= newlist
;
108 memcpy(newlist
->list
, head
->list
+ old
, nr
* sizeof(void *));
109 memset(head
->list
+ old
, 0xf0, nr
* sizeof(void *));
112 void **__add_ptr_list(struct ptr_list
**listp
, void *ptr
, unsigned long tag
)
114 struct ptr_list
*list
= *listp
;
115 struct ptr_list
*last
= NULL
; /* gcc complains needlessly */
119 /* The low two bits are reserved for tags */
120 assert((3 & (unsigned long)ptr
) == 0);
121 assert((~3 & tag
) == 0);
122 ptr
= (void *)(tag
| (unsigned long)ptr
);
124 if (!list
|| (nr
= (last
= list
->prev
)->nr
) >= LIST_NODE_NR
) {
125 struct ptr_list
*newlist
= malloc(sizeof(*newlist
));
127 memset(newlist
, 0, sizeof(*newlist
));
129 newlist
->next
= newlist
;
130 newlist
->prev
= newlist
;
133 newlist
->prev
= last
;
134 newlist
->next
= list
;
135 list
->prev
= newlist
;
136 last
->next
= newlist
;
141 ret
= last
->list
+ nr
;
148 int delete_ptr_list_entry(struct ptr_list
**list
, void *entry
, int count
)
152 FOR_EACH_PTR(*list
, ptr
) {
154 DELETE_CURRENT_PTR(ptr
);
158 } END_FOR_EACH_PTR(ptr
);
165 int replace_ptr_list_entry(struct ptr_list
**list
, void *old_ptr
, void *new_ptr
, int count
)
169 FOR_EACH_PTR(*list
, ptr
) {
171 REPLACE_CURRENT_PTR(ptr
, new_ptr
);
175 }END_FOR_EACH_PTR(ptr
);
181 /* This removes the last entry, but doesn't pack the ptr list */
182 void * undo_ptr_list_last(struct ptr_list
**head
)
184 struct ptr_list
*last
, *first
= *head
;
194 ptr
= last
->list
[nr
];
195 last
->list
[nr
] = (void *)0xf1f1f1f1;
198 } while (last
!= first
);
202 void * delete_ptr_list_last(struct ptr_list
**head
)
205 struct ptr_list
*last
, *first
= *head
;
211 ptr
= last
->list
[--last
->nr
];
213 first
->prev
= last
->prev
;
214 last
->prev
->next
= first
;
222 void concat_ptr_list(struct ptr_list
*a
, struct ptr_list
**b
)
225 FOR_EACH_PTR(a
, entry
) {
226 add_ptr_list(b
, entry
);
227 } END_FOR_EACH_PTR(entry
);
230 void __free_ptr_list(struct ptr_list
**listp
)
232 struct ptr_list
*tmp
, *list
= *listp
;
237 list
->prev
->next
= NULL
;