1 /* Copyright (c) 2012-2014, 2016, 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 // System dependencies
31 #include <pthread.h>
32 
33 // JPEG dependencies
34 #include "mm_jpeg_dbg.h"
35 #include "mm_jpeg.h"
36 
mm_jpeg_queue_init(mm_jpeg_queue_t * queue)37 int32_t mm_jpeg_queue_init(mm_jpeg_queue_t* queue)
38 {
39     pthread_mutex_init(&queue->lock, NULL);
40     cam_list_init(&queue->head.list);
41     queue->size = 0;
42     return 0;
43 }
44 
mm_jpeg_queue_enq(mm_jpeg_queue_t * queue,mm_jpeg_q_data_t data)45 int32_t mm_jpeg_queue_enq(mm_jpeg_queue_t* queue, mm_jpeg_q_data_t data)
46 {
47     mm_jpeg_q_node_t* node =
48         (mm_jpeg_q_node_t *)malloc(sizeof(mm_jpeg_q_node_t));
49     if (NULL == node) {
50         LOGE("No memory for mm_jpeg_q_node_t");
51         return -1;
52     }
53 
54     memset(node, 0, sizeof(mm_jpeg_q_node_t));
55     node->data = data;
56 
57     pthread_mutex_lock(&queue->lock);
58     cam_list_add_tail_node(&node->list, &queue->head.list);
59     queue->size++;
60     pthread_mutex_unlock(&queue->lock);
61 
62     return 0;
63 
64 }
65 
mm_jpeg_queue_enq_head(mm_jpeg_queue_t * queue,mm_jpeg_q_data_t data)66 int32_t mm_jpeg_queue_enq_head(mm_jpeg_queue_t* queue, mm_jpeg_q_data_t data)
67 {
68   struct cam_list *head = NULL;
69   struct cam_list *pos = NULL;
70   mm_jpeg_q_node_t* node =
71         (mm_jpeg_q_node_t *)malloc(sizeof(mm_jpeg_q_node_t));
72     if (NULL == node) {
73         LOGE("No memory for mm_jpeg_q_node_t");
74         return -1;
75     }
76 
77     memset(node, 0, sizeof(mm_jpeg_q_node_t));
78     node->data = data;
79 
80     head = &queue->head.list;
81     pos = head->next;
82 
83     pthread_mutex_lock(&queue->lock);
84     cam_list_insert_before_node(&node->list, pos);
85     queue->size++;
86     pthread_mutex_unlock(&queue->lock);
87 
88     return 0;
89 }
90 
mm_jpeg_queue_deq(mm_jpeg_queue_t * queue)91 mm_jpeg_q_data_t mm_jpeg_queue_deq(mm_jpeg_queue_t* queue)
92 {
93     mm_jpeg_q_data_t data;
94     mm_jpeg_q_node_t* node = NULL;
95     struct cam_list *head = NULL;
96     struct cam_list *pos = NULL;
97 
98     memset(&data, 0, sizeof(data));
99 
100     pthread_mutex_lock(&queue->lock);
101     head = &queue->head.list;
102     pos = head->next;
103     if (pos != head) {
104         node = member_of(pos, mm_jpeg_q_node_t, list);
105         cam_list_del_node(&node->list);
106         queue->size--;
107     }
108     pthread_mutex_unlock(&queue->lock);
109 
110     if (NULL != node) {
111         data = node->data;
112         free(node);
113     }
114 
115     return data;
116 }
117 
mm_jpeg_queue_get_size(mm_jpeg_queue_t * queue)118 uint32_t mm_jpeg_queue_get_size(mm_jpeg_queue_t* queue)
119 {
120     uint32_t size = 0;
121 
122     pthread_mutex_lock(&queue->lock);
123     size = queue->size;
124     pthread_mutex_unlock(&queue->lock);
125 
126     return size;
127 
128 }
129 
mm_jpeg_queue_deinit(mm_jpeg_queue_t * queue)130 int32_t mm_jpeg_queue_deinit(mm_jpeg_queue_t* queue)
131 {
132     mm_jpeg_queue_flush(queue);
133     pthread_mutex_destroy(&queue->lock);
134     return 0;
135 }
136 
mm_jpeg_queue_flush(mm_jpeg_queue_t * queue)137 int32_t mm_jpeg_queue_flush(mm_jpeg_queue_t* queue)
138 {
139     mm_jpeg_q_node_t* node = NULL;
140     struct cam_list *head = NULL;
141     struct cam_list *pos = NULL;
142 
143     pthread_mutex_lock(&queue->lock);
144     head = &queue->head.list;
145     pos = head->next;
146 
147     while(pos != head) {
148         node = member_of(pos, mm_jpeg_q_node_t, list);
149         cam_list_del_node(&node->list);
150         queue->size--;
151 
152         /* for now we only assume there is no ptr inside data
153          * so we free data directly */
154         if (NULL != node->data.p) {
155             free(node->data.p);
156         }
157         free(node);
158         pos = pos->next;
159     }
160     queue->size = 0;
161     pthread_mutex_unlock(&queue->lock);
162     return 0;
163 }
164 
mm_jpeg_queue_peek(mm_jpeg_queue_t * queue)165 mm_jpeg_q_data_t mm_jpeg_queue_peek(mm_jpeg_queue_t* queue)
166 {
167     mm_jpeg_q_data_t data;
168     mm_jpeg_q_node_t* node = NULL;
169     struct cam_list *head = NULL;
170     struct cam_list *pos = NULL;
171 
172     memset(&data, 0, sizeof(data));
173 
174     pthread_mutex_lock(&queue->lock);
175     head = &queue->head.list;
176     pos = head->next;
177     if (pos != head) {
178         node = member_of(pos, mm_jpeg_q_node_t, list);
179     }
180     pthread_mutex_unlock(&queue->lock);
181 
182     if (NULL != node) {
183         data = node->data;
184     }
185     return data;
186 }
187