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