1 /* Copyright (c) 2012, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #include "cam_list.h"
31
32 #include <stdlib.h>
33
34 typedef struct {
35 struct cam_list list;
36 void *data;
37 } cam_node_t;
38
39 typedef struct {
40 cam_node_t head; /* dummy head */
41 uint32_t size;
42 pthread_mutex_t lock;
43 } cam_queue_t;
44
cam_queue_init(cam_queue_t * queue)45 static inline int32_t cam_queue_init(cam_queue_t *queue)
46 {
47 pthread_mutex_init(&queue->lock, NULL);
48 cam_list_init(&queue->head.list);
49 queue->size = 0;
50 return 0;
51 }
52
cam_queue_enq(cam_queue_t * queue,void * data)53 static inline int32_t cam_queue_enq(cam_queue_t *queue, void *data)
54 {
55 cam_node_t *node =
56 (cam_node_t *)malloc(sizeof(cam_node_t));
57 if (NULL == node) {
58 return -1;
59 }
60
61 memset(node, 0, sizeof(cam_node_t));
62 node->data = data;
63
64 pthread_mutex_lock(&queue->lock);
65 cam_list_add_tail_node(&node->list, &queue->head.list);
66 queue->size++;
67 pthread_mutex_unlock(&queue->lock);
68
69 return 0;
70 }
71
cam_queue_deq(cam_queue_t * queue)72 static inline void *cam_queue_deq(cam_queue_t *queue)
73 {
74 cam_node_t *node = NULL;
75 void *data = NULL;
76 struct cam_list *head = NULL;
77 struct cam_list *pos = NULL;
78
79 pthread_mutex_lock(&queue->lock);
80 head = &queue->head.list;
81 pos = head->next;
82 if (pos != head) {
83 node = member_of(pos, cam_node_t, list);
84 cam_list_del_node(&node->list);
85 queue->size--;
86 }
87 pthread_mutex_unlock(&queue->lock);
88
89 if (NULL != node) {
90 data = node->data;
91 free(node);
92 }
93
94 return data;
95 }
96
cam_queue_flush(cam_queue_t * queue)97 static inline int32_t cam_queue_flush(cam_queue_t *queue)
98 {
99 cam_node_t *node = NULL;
100 struct cam_list *head = NULL;
101 struct cam_list *pos = NULL;
102
103 pthread_mutex_lock(&queue->lock);
104 head = &queue->head.list;
105 pos = head->next;
106
107 while(pos != head) {
108 node = member_of(pos, cam_node_t, list);
109 pos = pos->next;
110 cam_list_del_node(&node->list);
111 queue->size--;
112
113 /* TODO later to consider ptr inside data */
114 /* for now we only assume there is no ptr inside data
115 * so we free data directly */
116 if (NULL != node->data) {
117 free(node->data);
118 }
119 free(node);
120
121 }
122 queue->size = 0;
123 pthread_mutex_unlock(&queue->lock);
124 return 0;
125 }
126
cam_queue_deinit(cam_queue_t * queue)127 static inline int32_t cam_queue_deinit(cam_queue_t *queue)
128 {
129 cam_queue_flush(queue);
130 pthread_mutex_destroy(&queue->lock);
131 return 0;
132 }
133