blob: 40e2db37376cbdb82cb582bf82ea0e9def9935be
1 | /* |
2 | * Copyright (c) 2014 Amlogic, Inc. All rights reserved. |
3 | * |
4 | * This source code is subject to the terms and conditions defined in the |
5 | * file 'LICENSE' which is part of this source code package. |
6 | * |
7 | * Description: |
8 | */ |
9 | |
10 | |
11 | /******************************************** |
12 | * name : player_itemlis.c |
13 | * function: item fifo manage for muti threads |
14 | * date : 2011.3.23 |
15 | * author :zhouzhi |
16 | ********************************************/ |
17 | |
18 | #include <stdio.h> |
19 | #include <sys/time.h> |
20 | #include <time.h> |
21 | #include <pthread.h> |
22 | #include <stdlib.h> |
23 | #include <itemlist.h> |
24 | |
25 | |
26 | |
27 | |
28 | int itemlist_init(struct itemlist *itemlist) |
29 | { |
30 | itemlist->item_count = 0; |
31 | INIT_LIST_HEAD(&itemlist->list); |
32 | ITEM_LOCK_INIT(itemlist); |
33 | return 0; |
34 | } |
35 | int itemlist_deinit(struct itemlist *itemlist) |
36 | { |
37 | ITEM_LOCK_DESTROY(itemlist); |
38 | return 0; |
39 | } |
40 | |
41 | struct item * item_alloc(int ext) { |
42 | return malloc(sizeof(struct item) + ext); |
43 | } |
44 | |
45 | |
46 | void item_free(struct item *item) |
47 | { |
48 | free(item); |
49 | } |
50 | |
51 | |
52 | int itemlist_add_tail(struct itemlist *itemlist, struct item *item) |
53 | { |
54 | ITEM_LOCK(itemlist); |
55 | if (itemlist->max_items > 0 && itemlist->max_items <= itemlist->item_count) { |
56 | ITEM_UNLOCK(itemlist); |
57 | return -1; |
58 | } |
59 | list_add_tail(&item->list, &itemlist->list); |
60 | itemlist->item_count++; |
61 | ITEM_UNLOCK(itemlist); |
62 | return 0; |
63 | } |
64 | |
65 | struct item * itemlist_get_head(struct itemlist *itemlist) { |
66 | struct item *item = NULL; |
67 | struct list_head *list = NULL; |
68 | |
69 | ITEM_LOCK(itemlist); |
70 | if (!list_empty(&itemlist->list)) { |
71 | list = itemlist->list.next; |
72 | item = list_entry(list, struct item, list); |
73 | list_del(list); |
74 | itemlist->item_count--; |
75 | } |
76 | ITEM_UNLOCK(itemlist); |
77 | return item; |
78 | } |
79 | |
80 | struct item * itemlist_get_tail(struct itemlist *itemlist) { |
81 | struct item *item = NULL; |
82 | struct list_head *list = NULL; |
83 | |
84 | ITEM_LOCK(itemlist); |
85 | if (!list_empty(&itemlist->list)) { |
86 | list = itemlist->list.prev; |
87 | item = list_entry(list, struct item, list); |
88 | list_del(list); |
89 | itemlist->item_count--; |
90 | } |
91 | ITEM_UNLOCK(itemlist); |
92 | return item; |
93 | } |
94 | |
95 | |
96 | struct item * itemlist_peek_head(struct itemlist *itemlist) { |
97 | struct item *item = NULL; |
98 | struct list_head *list = NULL; |
99 | |
100 | ITEM_LOCK(itemlist); |
101 | if (!list_empty(&itemlist->list)) { |
102 | list = itemlist->list.next; |
103 | item = list_entry(list, struct item, list); |
104 | } |
105 | ITEM_UNLOCK(itemlist); |
106 | return item; |
107 | } |
108 | |
109 | struct item * itemlist_peek_tail(struct itemlist *itemlist) { |
110 | struct item *item = NULL; |
111 | struct list_head *list = NULL; |
112 | |
113 | ITEM_LOCK(itemlist); |
114 | if (!list_empty(&itemlist->list)) { |
115 | list = itemlist->list.prev; |
116 | item = list_entry(list, struct item, list); |
117 | } |
118 | ITEM_UNLOCK(itemlist); |
119 | return item; |
120 | } |
121 | int itemlist_del_item_locked(struct itemlist *itemlist, struct item *item) |
122 | { |
123 | list_del(&item->list); |
124 | itemlist->item_count--; |
125 | return 0; |
126 | } |
127 | |
128 | int itemlist_del_item(struct itemlist *itemlist, struct item *item) |
129 | { |
130 | ITEM_LOCK(itemlist); |
131 | itemlist_del_item_locked(itemlist, item); |
132 | ITEM_UNLOCK(itemlist); |
133 | return 0; |
134 | } |
135 | |
136 | |
137 | int itemlist_clean(struct itemlist *itemlist, data_free_fun free_fun) |
138 | { |
139 | struct item *item = NULL; |
140 | struct list_head *llist, *tmplist; |
141 | ITEM_LOCK(itemlist); |
142 | list_for_each_safe(llist, tmplist, &itemlist->list) { |
143 | item = list_entry(llist, struct item, list); |
144 | if (free_fun != NULL && item->item_data != 0) { |
145 | free_fun((void *)item->item_data); |
146 | } |
147 | list_del(llist); |
148 | item_free(item); |
149 | itemlist->item_count--; |
150 | } |
151 | ITEM_UNLOCK(itemlist); |
152 | return 0; |
153 | } |
154 | |
155 | struct item * itemlist_get_match_item(struct itemlist *itemlist, unsigned long data) { |
156 | struct item *item = NULL; |
157 | struct list_head *llist, *tmplist; |
158 | struct item *finditem = NULL; |
159 | ITEM_LOCK(itemlist); |
160 | list_for_each_safe(llist, tmplist, &itemlist->list) { |
161 | item = list_entry(llist, struct item, list); |
162 | if (item->item_data == data) { |
163 | finditem = item; |
164 | break; |
165 | } |
166 | } |
167 | if (finditem != NULL) { |
168 | list_del(&finditem->list); |
169 | itemlist->item_count--; |
170 | } |
171 | ITEM_UNLOCK(itemlist); |
172 | return finditem; |
173 | } |
174 | |
175 | struct item * itemlist_find_match_item(struct itemlist *itemlist, unsigned long data) { |
176 | struct item *item = NULL; |
177 | struct list_head *llist, *tmplist; |
178 | struct item *finditem = NULL; |
179 | ITEM_LOCK(itemlist); |
180 | list_for_each_safe(llist, tmplist, &itemlist->list) { |
181 | item = list_entry(llist, struct item, list); |
182 | if (item->item_data == data) { |
183 | finditem = item; |
184 | break; |
185 | } |
186 | } |
187 | ITEM_UNLOCK(itemlist); |
188 | return finditem; |
189 | } |
190 | |
191 | /* |
192 | we think the item->data is grow, |
193 | we find the first item great or equal item->data; |
194 | */ |
195 | struct item * itemlist_find_match_item_ex(struct itemlist *itemlist, struct item *tomatch, item_is_match_fun match, int reveser) { |
196 | struct item *item = NULL; |
197 | struct list_head *llist, *tmplist; |
198 | struct item *finditem = NULL; |
199 | ITEM_LOCK(itemlist); |
200 | if (reveser) { |
201 | list_for_each_entry_reverse(item, &itemlist->list, list) { |
202 | if (match(item, tomatch)) { |
203 | finditem = item; |
204 | break; |
205 | } |
206 | } |
207 | } else { |
208 | list_for_each_entry(item, &itemlist->list, list) { |
209 | if (match(item, tomatch)) { |
210 | finditem = item; |
211 | break; |
212 | } |
213 | } |
214 | } |
215 | |
216 | ITEM_UNLOCK(itemlist); |
217 | return finditem; |
218 | } |
219 | |
220 | int itemlist_add_tail_data_ext(struct itemlist *itemlist, unsigned long data, int extnum, unsigned long *extdata) |
221 | { |
222 | struct item *item; |
223 | int i; |
224 | if (itemlist->reject_same_item_data && itemlist_have_match_data(itemlist, data)) { |
225 | return 0; /*have matched in list*/ |
226 | } |
227 | item = item_alloc(extnum * sizeof(unsigned long)); |
228 | if (item == NULL) { |
229 | return -12;//noMEM |
230 | } |
231 | item->item_data = data; |
232 | for (i = 0 ; i < extnum ; i++) { |
233 | item->extdata[i] = extdata[i]; |
234 | } |
235 | if (itemlist_add_tail(itemlist, item) != 0) { |
236 | item_free(item); |
237 | return -1; |
238 | } |
239 | return 0; |
240 | } |
241 | int itemlist_add_tail_data(struct itemlist *itemlist, unsigned long data) |
242 | { |
243 | return itemlist_add_tail_data_ext(itemlist, data, 0, 0); |
244 | } |
245 | |
246 | int itemlist_get_head_data(struct itemlist *itemlist, unsigned long *data) |
247 | { |
248 | struct item *item = NULL; |
249 | item = itemlist_get_head(itemlist); |
250 | if (item != NULL) { |
251 | *data = item->item_data; |
252 | item_free(item); |
253 | return 0; |
254 | } else { |
255 | return -1; |
256 | } |
257 | } |
258 | |
259 | int itemlist_get_tail_data(struct itemlist *itemlist, unsigned long *data) |
260 | { |
261 | struct item *item = NULL; |
262 | item = itemlist_get_tail(itemlist); |
263 | if (item != NULL) { |
264 | *data = item->item_data; |
265 | return 0; |
266 | } else { |
267 | return -1; |
268 | } |
269 | } |
270 | |
271 | |
272 | int itemlist_peek_head_data(struct itemlist *itemlist, unsigned long *data) |
273 | { |
274 | struct item *item = NULL; |
275 | item = itemlist_peek_head(itemlist); |
276 | if (item != NULL) { |
277 | *data = item->item_data; |
278 | return 0; |
279 | } else { |
280 | return -1; |
281 | } |
282 | } |
283 | |
284 | |
285 | |
286 | |
287 | int itemlist_peek_tail_data(struct itemlist *itemlist, unsigned long *data) |
288 | { |
289 | struct item *item = NULL; |
290 | item = itemlist_peek_tail(itemlist); |
291 | if (item != NULL) { |
292 | *data = item->item_data; |
293 | return 0; |
294 | } else { |
295 | return -1; |
296 | } |
297 | } |
298 | |
299 | |
300 | int itemlist_clean_data(struct itemlist *itemlist, data_free_fun free_fun) |
301 | { |
302 | return itemlist_clean(itemlist, free_fun); |
303 | } |
304 | |
305 | int itemlist_have_match_data(struct itemlist *itemlist, unsigned long data) |
306 | { |
307 | struct item *item = NULL; |
308 | item = itemlist_find_match_item(itemlist, data); |
309 | return item != NULL; |
310 | } |
311 | |
312 | |
313 | int itemlist_del_match_data_item(struct itemlist *itemlist, unsigned long data) |
314 | { |
315 | struct item *item = NULL; |
316 | item = itemlist_get_match_item(itemlist, data); |
317 | if (item) { |
318 | item_free(item); |
319 | return 0; |
320 | } |
321 | return -1; |
322 | } |
323 | |
324 | /* |
325 | postion must in the itemlist. |
326 | flags: 1: before position; |
327 | 2: after postion; |
328 | 3: replace postion; |
329 | else: |
330 | 2:after postion; |
331 | */ |
332 | int itemlist_item_insert(struct itemlist *itemlist, struct itemlist *position, struct itemlist *newitem, int flags) |
333 | { |
334 | ITEM_LOCK(itemlist); |
335 | if (flags != 3 && itemlist->max_items > 0 && itemlist->max_items <= itemlist->item_count) { |
336 | ITEM_UNLOCK(itemlist); |
337 | return -1; |
338 | } |
339 | if (flags == 1) { |
340 | list_add_tail(&newitem->list, &position->list); |
341 | } else { |
342 | list_add(&newitem->list, &position->list); |
343 | } |
344 | if (flags == 3) { |
345 | list_del(&position->list); |
346 | } else { |
347 | itemlist->item_count++; |
348 | } |
349 | ITEM_UNLOCK(itemlist); |
350 | return 0; |
351 | } |
352 | |
353 | int itemlist_print(struct itemlist *itemlist, printitem_fun print) |
354 | { |
355 | struct item *item = NULL; |
356 | struct list_head *llist, *tmplist; |
357 | ITEM_LOCK(itemlist); |
358 | list_for_each_safe(llist, tmplist, &itemlist->list) { |
359 | item = list_entry(llist, struct item, list); |
360 | print(item); |
361 | } |
362 | ITEM_UNLOCK(itemlist); |
363 | return 0; |
364 | } |
365 | |
366 |