Path: blob/main/sys/contrib/vchiq/interface/vchiq_arm/vchiq_util.c
48383 views
/**1* Copyright (c) 2010-2012 Broadcom. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6* 1. Redistributions of source code must retain the above copyright7* notice, this list of conditions, and the following disclaimer,8* without modification.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. The names of the above-listed copyright holders may not be used13* to endorse or promote products derived from this software without14* specific prior written permission.15*16* ALTERNATIVELY, this software may be distributed under the terms of the17* GNU General Public License ("GPL") version 2, as published by the Free18* Software Foundation.19*20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS21* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,22* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR23* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR24* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,25* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,26* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR27* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF28* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING29* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS30* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.31*/3233#include "vchiq_util.h"3435static inline int is_pow2(int i)36{37return i && !(i & (i - 1));38}3940int vchiu_queue_init(VCHIU_QUEUE_T *queue, int size)41{42WARN_ON(!is_pow2(size));4344queue->size = size;45queue->read = 0;46queue->write = 0;47queue->initialized = 1;4849_sema_init(&queue->pop, 0);50_sema_init(&queue->push, 0);5152queue->storage = kzalloc(size * sizeof(VCHIQ_HEADER_T *), GFP_KERNEL);53if (queue->storage == NULL) {54vchiu_queue_delete(queue);55return 0;56}57return 1;58}5960void vchiu_queue_delete(VCHIU_QUEUE_T *queue)61{62if (queue->storage != NULL)63kfree(queue->storage);64}6566int vchiu_queue_is_empty(VCHIU_QUEUE_T *queue)67{68return queue->read == queue->write;69}7071int vchiu_queue_is_full(VCHIU_QUEUE_T *queue)72{73return queue->write == queue->read + queue->size;74}7576void vchiu_queue_push(VCHIU_QUEUE_T *queue, VCHIQ_HEADER_T *header)77{78if (!queue->initialized)79return;8081while (queue->write == queue->read + queue->size) {82if (down_interruptible(&queue->pop) != 0) {83flush_signals(current);84}85}8687/*88* Write to queue->storage must be visible after read from89* queue->read90*/91smp_mb();9293queue->storage[queue->write & (queue->size - 1)] = header;9495/*96* Write to queue->storage must be visible before write to97* queue->write98*/99smp_wmb();100101queue->write++;102103up(&queue->push);104}105106VCHIQ_HEADER_T *vchiu_queue_peek(VCHIU_QUEUE_T *queue)107{108while (queue->write == queue->read) {109if (down_interruptible(&queue->push) != 0) {110flush_signals(current);111}112}113114up(&queue->push); // We haven't removed anything from the queue.115116/*117* Read from queue->storage must be visible after read from118* queue->write119*/120smp_rmb();121122return queue->storage[queue->read & (queue->size - 1)];123}124125VCHIQ_HEADER_T *vchiu_queue_pop(VCHIU_QUEUE_T *queue)126{127VCHIQ_HEADER_T *header;128129while (queue->write == queue->read) {130if (down_interruptible(&queue->push) != 0) {131flush_signals(current);132}133}134135/*136* Read from queue->storage must be visible after read from137* queue->write138*/139smp_rmb();140141header = queue->storage[queue->read & (queue->size - 1)];142143/*144* Read from queue->storage must be visible before write to145* queue->read146*/147smp_mb();148149queue->read++;150151up(&queue->pop);152153return header;154}155156157