10b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam/* Copyright (c) 2012, The Linux Foundation. All rights reserved. 20b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * 30b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * Redistribution and use in source and binary forms, with or without 40b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * modification, are permitted provided that the following conditions are 50b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * met: 60b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * * Redistributions of source code must retain the above copyright 70b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * notice, this list of conditions and the following disclaimer. 80b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * * Redistributions in binary form must reproduce the above 90b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * copyright notice, this list of conditions and the following 100b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * disclaimer in the documentation and/or other materials provided 110b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * with the distribution. 120b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * * Neither the name of The Linux Foundation nor the names of its 130b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * contributors may be used to endorse or promote products derived 140b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * from this software without specific prior written permission. 150b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * 160b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 170b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 180b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 190b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 200b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 210b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 220b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 230b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 240b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 250b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 260b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 270b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * 280b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam */ 290b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 300b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam#include "cam_list.h" 310b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 320b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tamtypedef struct { 330b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam struct cam_list list; 340b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam void *data; 350b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam} cam_node_t; 360b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 370b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tamtypedef struct { 380b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_node_t head; /* dummy head */ 390b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam uint32_t size; 400b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_t lock; 410b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam} cam_queue_t; 420b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 430b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tamstatic inline int32_t cam_queue_init(cam_queue_t *queue) 440b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam{ 450b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_init(&queue->lock, NULL); 460b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_list_init(&queue->head.list); 470b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam queue->size = 0; 480b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam return 0; 490b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam} 500b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 510b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tamstatic inline int32_t cam_queue_enq(cam_queue_t *queue, void *data) 520b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam{ 530b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_node_t *node = 540b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam (cam_node_t *)malloc(sizeof(cam_node_t)); 550b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam if (NULL == node) { 560b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam return -1; 570b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam } 580b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 590b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam memset(node, 0, sizeof(cam_node_t)); 600b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam node->data = data; 610b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 620b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_lock(&queue->lock); 630b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_list_add_tail_node(&node->list, &queue->head.list); 640b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam queue->size++; 650b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_unlock(&queue->lock); 660b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 670b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam return 0; 680b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam} 690b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 700b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tamstatic inline void *cam_queue_deq(cam_queue_t *queue) 710b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam{ 720b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_node_t *node = NULL; 730b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam void *data = NULL; 740b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam struct cam_list *head = NULL; 750b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam struct cam_list *pos = NULL; 760b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 770b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_lock(&queue->lock); 780b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam head = &queue->head.list; 790b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pos = head->next; 800b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam if (pos != head) { 810b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam node = member_of(pos, cam_node_t, list); 820b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_list_del_node(&node->list); 830b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam queue->size--; 840b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam } 850b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_unlock(&queue->lock); 860b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 870b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam if (NULL != node) { 880b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam data = node->data; 890b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam free(node); 900b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam } 910b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 920b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam return data; 930b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam} 940b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 950b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tamstatic inline int32_t cam_queue_flush(cam_queue_t *queue) 960b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam{ 970b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_node_t *node = NULL; 980b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam struct cam_list *head = NULL; 990b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam struct cam_list *pos = NULL; 1000b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 1010b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_lock(&queue->lock); 1020b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam head = &queue->head.list; 1030b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pos = head->next; 1040b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 1050b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam while(pos != head) { 1060b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam node = member_of(pos, cam_node_t, list); 1070b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pos = pos->next; 1080b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_list_del_node(&node->list); 1090b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam queue->size--; 1100b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 1110b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam /* TODO later to consider ptr inside data */ 1120b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam /* for now we only assume there is no ptr inside data 1130b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam * so we free data directly */ 1140b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam if (NULL != node->data) { 1150b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam free(node->data); 1160b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam } 1170b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam free(node); 1180b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 1190b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam } 1200b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam queue->size = 0; 1210b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_unlock(&queue->lock); 1220b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam return 0; 1230b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam} 1240b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam 1250b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tamstatic inline int32_t cam_queue_deinit(cam_queue_t *queue) 1260b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam{ 1270b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam cam_queue_flush(queue); 1280b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam pthread_mutex_destroy(&queue->lock); 1290b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam return 0; 1300b22217da5945fcfef82ce2c0e0ccb2de2fb63ecEd Tam} 131