cam_queue.h revision 6f83d735d8e3b918da42e6b559fcd0efb78133e5
16f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
26f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *
36f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * Redistribution and use in source and binary forms, with or without
46f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * modification, are permitted provided that the following conditions are
56f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * met:
66f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *     * Redistributions of source code must retain the above copyright
76f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *       notice, this list of conditions and the following disclaimer.
86f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *     * Redistributions in binary form must reproduce the above
96f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *       copyright notice, this list of conditions and the following
106f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *       disclaimer in the documentation and/or other materials provided
116f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *       with the distribution.
126f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *     * Neither the name of The Linux Foundation nor the names of its
136f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *       contributors may be used to endorse or promote products derived
146f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *       from this software without specific prior written permission.
156f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *
166f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
176f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
186f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
196f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
206f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
216f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
226f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
236f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
246f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
256f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
266f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev *
286f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev */
296f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
306f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev#include "cam_list.h"
316f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
326f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchevtypedef struct {
336f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    struct cam_list list;
346f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    void *data;
356f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev} cam_node_t;
366f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
376f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchevtypedef struct {
386f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    cam_node_t head; /* dummy head */
396f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    uint32_t size;
406f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_t lock;
416f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev} cam_queue_t;
426f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
436f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchevstatic inline int32_t cam_queue_init(cam_queue_t *queue)
446f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev{
456f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_init(&queue->lock, NULL);
466f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    cam_list_init(&queue->head.list);
476f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    queue->size = 0;
486f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    return 0;
496f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev}
506f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
516f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchevstatic inline int32_t cam_queue_enq(cam_queue_t *queue, void *data)
526f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev{
536f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    cam_node_t *node =
546f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        (cam_node_t *)malloc(sizeof(cam_node_t));
556f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    if (NULL == node) {
566f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        return -1;
576f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    }
586f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
596f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    memset(node, 0, sizeof(cam_node_t));
606f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    node->data = data;
616f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
626f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_lock(&queue->lock);
636f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    cam_list_add_tail_node(&node->list, &queue->head.list);
646f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    queue->size++;
656f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_unlock(&queue->lock);
666f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
676f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    return 0;
686f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev}
696f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
706f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchevstatic inline void *cam_queue_deq(cam_queue_t *queue)
716f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev{
726f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    cam_node_t *node = NULL;
736f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    void *data = NULL;
746f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    struct cam_list *head = NULL;
756f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    struct cam_list *pos = NULL;
766f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
776f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_lock(&queue->lock);
786f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    head = &queue->head.list;
796f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pos = head->next;
806f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    if (pos != head) {
816f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        node = member_of(pos, cam_node_t, list);
826f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        cam_list_del_node(&node->list);
836f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        queue->size--;
846f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    }
856f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_unlock(&queue->lock);
866f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
876f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    if (NULL != node) {
886f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        data = node->data;
896f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        free(node);
906f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    }
916f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
926f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    return data;
936f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev}
946f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
956f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchevstatic inline int32_t cam_queue_flush(cam_queue_t *queue)
966f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev{
976f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    cam_node_t *node = NULL;
986f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    struct cam_list *head = NULL;
996f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    struct cam_list *pos = NULL;
1006f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
1016f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_lock(&queue->lock);
1026f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    head = &queue->head.list;
1036f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pos = head->next;
1046f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
1056f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    while(pos != head) {
1066f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        node = member_of(pos, cam_node_t, list);
1076f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        pos = pos->next;
1086f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        cam_list_del_node(&node->list);
1096f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        queue->size--;
1106f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
1116f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        /* TODO later to consider ptr inside data */
1126f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        /* for now we only assume there is no ptr inside data
1136f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev         * so we free data directly */
1146f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        if (NULL != node->data) {
1156f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev            free(node->data);
1166f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        }
1176f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev        free(node);
1186f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
1196f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    }
1206f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    queue->size = 0;
1216f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_unlock(&queue->lock);
1226f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    return 0;
1236f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev}
1246f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev
1256f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchevstatic inline int32_t cam_queue_deinit(cam_queue_t *queue)
1266f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev{
1276f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    cam_queue_flush(queue);
1286f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    pthread_mutex_destroy(&queue->lock);
1296f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev    return 0;
1306f83d735d8e3b918da42e6b559fcd0efb78133e5Iliyan Malchev}
131