1c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati/****************************************************************************** 2c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * 3c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * Copyright (C) 2014 Google, Inc. 4c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * 5c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * Licensed under the Apache License, Version 2.0 (the "License"); 6c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * you may not use this file except in compliance with the License. 7c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * You may obtain a copy of the License at: 8c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * 9c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * http://www.apache.org/licenses/LICENSE-2.0 10c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * 11c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * Unless required by applicable law or agreed to in writing, software 12c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * distributed under the License is distributed on an "AS IS" BASIS, 13c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * See the License for the specific language governing permissions and 15c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * limitations under the License. 16c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati * 17c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati ******************************************************************************/ 18c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 19c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati#include <assert.h> 20c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati#include <pthread.h> 21c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati#include <stdlib.h> 22c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 23c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati#include "fixed_queue.h" 24c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati#include "list.h" 25c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati#include "osi.h" 26c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati#include "semaphore.h" 27c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 28c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavatitypedef struct fixed_queue_t { 29c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati list_t *list; 30c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_t *enqueue_sem; 31c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_t *dequeue_sem; 32c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati pthread_mutex_t lock; 33c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati size_t capacity; 34c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati} fixed_queue_t; 35c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 36c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavatifixed_queue_t *fixed_queue_new(size_t capacity) { 37c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati fixed_queue_t *ret = calloc(1, sizeof(fixed_queue_t)); 38c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati if (!ret) 39c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati goto error; 40c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 41c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati ret->list = list_new(NULL); 42c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati if (!ret->list) 43c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati goto error; 44c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 45c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati ret->enqueue_sem = semaphore_new(capacity); 46c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati if (!ret->enqueue_sem) 47c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati goto error; 48c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 49c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati ret->dequeue_sem = semaphore_new(0); 50c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati if (!ret->dequeue_sem) 51c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati goto error; 52c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 53c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati pthread_mutex_init(&ret->lock, NULL); 54c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati ret->capacity = capacity; 55c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 56c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati return ret; 57c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 58c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavatierror:; 59c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati if (ret) { 60c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati list_free(ret->list); 61c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_free(ret->enqueue_sem); 62c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_free(ret->dequeue_sem); 63c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati } 64c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 65c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati free(ret); 66c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati return NULL; 67c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati} 68c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 69c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavativoid fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb) { 70c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati if (!queue) 71c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati return; 72c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 73c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati if (free_cb) 74c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati for (const list_node_t *node = list_begin(queue->list); node != list_end(queue->list); node = list_next(node)) 75c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati free_cb(list_node(node)); 76c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 77c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati list_free(queue->list); 78c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_free(queue->enqueue_sem); 79c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_free(queue->dequeue_sem); 80c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati pthread_mutex_destroy(&queue->lock); 81c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati free(queue); 82c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati} 83c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 84c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavativoid fixed_queue_enqueue(fixed_queue_t *queue, void *data) { 85c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati assert(queue != NULL); 86c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati assert(data != NULL); 87c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 88c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_wait(queue->enqueue_sem); 89c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 90c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati pthread_mutex_lock(&queue->lock); 91c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati list_append(queue->list, data); 92c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati pthread_mutex_unlock(&queue->lock); 93c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 94c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_post(queue->dequeue_sem); 95c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati} 96c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 97c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavativoid *fixed_queue_dequeue(fixed_queue_t *queue) { 98c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati assert(queue != NULL); 99c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 100c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_wait(queue->dequeue_sem); 101c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 102c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati pthread_mutex_lock(&queue->lock); 103c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati void *ret = list_front(queue->list); 104c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati list_remove(queue->list, ret); 105c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati pthread_mutex_unlock(&queue->lock); 106c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 107c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati semaphore_post(queue->enqueue_sem); 108c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 109c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati return ret; 110c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati} 111c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 112c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavatibool fixed_queue_try_enqueue(fixed_queue_t *queue, void *data) { 113c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati assert(queue != NULL); 114c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati assert(data != NULL); 115c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 116c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati if (!semaphore_try_wait(queue->enqueue_sem)) 117c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati return false; 118c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 119c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati pthread_mutex_lock(&queue->lock); 120c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati list_append(queue->list, data); 121c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati pthread_mutex_unlock(&queue->lock); 122c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 123c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati semaphore_post(queue->dequeue_sem); 124c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati return true; 125c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati} 126c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 127c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavativoid *fixed_queue_try_dequeue(fixed_queue_t *queue) { 128c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati assert(queue != NULL); 129c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 130c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati if (!semaphore_try_wait(queue->dequeue_sem)) 131c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati return NULL; 132c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati 133c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati pthread_mutex_lock(&queue->lock); 134c5856ba565d4d6952f465164a98807fb274b96e6Sharvil Nanavati void *ret = list_front(queue->list); 135c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati list_remove(queue->list, ret); 136c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati pthread_mutex_unlock(&queue->lock); 137c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 138c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati semaphore_post(queue->enqueue_sem); 139c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati 140c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati return ret; 141c11b407e78d96e05b0991bbe6dfde0d7eb5349b5Sharvil Nanavati} 142ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavati 143ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavatiint fixed_queue_get_dequeue_fd(const fixed_queue_t *queue) { 144ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavati assert(queue != NULL); 145ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavati return semaphore_get_fd(queue->dequeue_sem); 146ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavati} 147ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavati 148ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavatiint fixed_queue_get_enqueue_fd(const fixed_queue_t *queue) { 149ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavati assert(queue != NULL); 150ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavati return semaphore_get_fd(queue->enqueue_sem); 151ab606b5ecd59ab9fd8a59cf4437993a44068a6eeSharvil Nanavati} 152