summaryrefslogtreecommitdiff
path: root/amavutils/itemlist.c (plain)
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
28int 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}
35int itemlist_deinit(struct itemlist *itemlist)
36{
37 ITEM_LOCK_DESTROY(itemlist);
38 return 0;
39}
40
41struct item * item_alloc(int ext) {
42 return malloc(sizeof(struct item) + ext);
43}
44
45
46void item_free(struct item *item)
47{
48 free(item);
49}
50
51
52int 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
65struct 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
80struct 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
96struct 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
109struct 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}
121int 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
128int 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
137int 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
155struct 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
175struct 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/*
192we think the item->data is grow,
193we find the first item great or equal item->data;
194*/
195struct 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
220int 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}
241int itemlist_add_tail_data(struct itemlist *itemlist, unsigned long data)
242{
243 return itemlist_add_tail_data_ext(itemlist, data, 0, 0);
244}
245
246int 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
259int 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
272int 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
287int 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
300int itemlist_clean_data(struct itemlist *itemlist, data_free_fun free_fun)
301{
302 return itemlist_clean(itemlist, free_fun);
303}
304
305int 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
313int 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/*
325postion must in the itemlist.
326flags: 1: before position;
327 2: after postion;
328 3: replace postion;
329 else:
330 2:after postion;
331*/
332int 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
353int 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