13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Stream Library 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * --------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Thread safe ringbuffer 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRingbuffer.h" 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deInt32.h" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSemaphore.h" 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdlib.h> 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <stdio.h> 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct deRingbuffer_s 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 blockSize; 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 blockCount; 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32* blockUsage; 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* buffer; 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore emptyCount; 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore fullCount; 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 outBlock; 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 outPos; 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 inBlock; 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 inPos; 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deBool stopNotified; 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deBool consumerStopping; 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 523c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeRingbuffer* deRingbuffer_create (deInt32 blockSize, deInt32 blockCount) 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deRingbuffer* ringbuffer = (deRingbuffer*)deCalloc(sizeof(deRingbuffer)); 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(ringbuffer); 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(blockCount > 0); 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(blockSize > 0); 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->blockSize = blockSize; 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->blockCount = blockCount; 62f096bcea8008dac1cb75d09ee03164321dc6ad14Jarkko Pöyry ringbuffer->buffer = (deUint8*)deMalloc(sizeof(deUint8) * (size_t)blockSize * (size_t)blockCount); 63f096bcea8008dac1cb75d09ee03164321dc6ad14Jarkko Pöyry ringbuffer->blockUsage = (deInt32*)deMalloc(sizeof(deUint32) * (size_t)blockCount); 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->emptyCount = deSemaphore_create(ringbuffer->blockCount, DE_NULL); 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->fullCount = deSemaphore_create(0, DE_NULL); 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!ringbuffer->buffer || 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !ringbuffer->blockUsage || 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !ringbuffer->emptyCount || 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry !ringbuffer->fullCount) 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->emptyCount) 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_destroy(ringbuffer->emptyCount); 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->fullCount) 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_destroy(ringbuffer->fullCount); 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deFree(ringbuffer->buffer); 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deFree(ringbuffer->blockUsage); 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deFree(ringbuffer); 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 82f096bcea8008dac1cb75d09ee03164321dc6ad14Jarkko Pöyry memset(ringbuffer->blockUsage, 0, sizeof(deInt32) * (size_t)blockCount); 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->outBlock = 0; 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->outPos = 0; 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inBlock = 0; 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inPos = 0; 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->stopNotified = DE_FALSE; 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->consumerStopping = DE_FALSE; 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return ringbuffer; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid deRingbuffer_stop (deRingbuffer* ringbuffer) 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Set notify to true and increment fullCount to let consumer continue */ 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->stopNotified = DE_TRUE; 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_increment(ringbuffer->fullCount); 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid deRingbuffer_destroy (deRingbuffer* ringbuffer) 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_destroy(ringbuffer->emptyCount); 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_destroy(ringbuffer->fullCount); 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry free(ringbuffer->buffer); 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry free(ringbuffer->blockUsage); 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry free(ringbuffer); 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deStreamResult producerStream_write (deStreamData* stream, const void* buf, deInt32 bufSize, deInt32* written) 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deRingbuffer* ringbuffer = (deRingbuffer*)stream; 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(stream); 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* If ringbuffer is stopping return error on write */ 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->stopNotified) 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(DE_FALSE); 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMRESULT_ERROR; 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *written = 0; 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Write while more data available */ 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (*written < bufSize) 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 writeSize = 0; 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* src = DE_NULL; 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* dst = DE_NULL; 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* If between blocks accuire new block */ 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->inPos == 0) 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_decrement(ringbuffer->emptyCount); 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeSize = deMin32(ringbuffer->blockSize - ringbuffer->inPos, bufSize - *written); 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst = ringbuffer->buffer + ringbuffer->blockSize * ringbuffer->inBlock + ringbuffer->inPos; 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src = (deUint8*)buf + *written; 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 144f096bcea8008dac1cb75d09ee03164321dc6ad14Jarkko Pöyry deMemcpy(dst, src, (size_t)writeSize); 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inPos += writeSize; 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *written += writeSize; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->blockUsage[ringbuffer->inBlock] += writeSize; 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Block is full move to next one (or "between" this and next block) */ 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->inPos == ringbuffer->blockSize) 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inPos = 0; 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inBlock++; 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->inBlock == ringbuffer->blockCount) 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inBlock = 0; 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_increment(ringbuffer->fullCount); 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMRESULT_SUCCESS; 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deStreamResult producerStream_flush (deStreamData* stream) 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deRingbuffer* ringbuffer = (deRingbuffer*)stream; 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(stream); 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* No blocks reserved by producer */ 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->inPos == 0) 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMRESULT_SUCCESS; 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inPos = 0; 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inBlock++; 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->inBlock == ringbuffer->blockCount) 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->inBlock = 0; 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_increment(ringbuffer->fullCount); 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMRESULT_SUCCESS; 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deStreamResult producerStream_deinit (deStreamData* stream) 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(stream); 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry producerStream_flush(stream); 1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* \note mika Stream doesn't own ringbuffer, so it's not deallocated */ 1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMRESULT_SUCCESS; 1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deStreamResult consumerStream_read (deStreamData* stream, void* buf, deInt32 bufSize, deInt32* read) 1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deRingbuffer* ringbuffer = (deRingbuffer*)stream; 1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(stream); 2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *read = 0; 2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(ringbuffer); 2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry while (*read < bufSize) 2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deInt32 writeSize = 0; 2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* src = DE_NULL; 2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint8* dst = DE_NULL; 2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* If between blocks accuire new block */ 2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->outPos == 0) 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* If consumer is set to stop after everything is consumed, 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * do not block if there is no more input left 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry */ 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->consumerStopping) 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Try to accuire new block, if can't there is no more input */ 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!deSemaphore_tryDecrement(ringbuffer->fullCount)) 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMRESULT_END_OF_STREAM; 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* If not stopping block until there is more input */ 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_decrement(ringbuffer->fullCount); 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Ringbuffer was set to stop */ 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->stopNotified) 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->consumerStopping = DE_TRUE; 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry writeSize = deMin32(ringbuffer->blockUsage[ringbuffer->outBlock] - ringbuffer->outPos, bufSize - *read); 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry src = ringbuffer->buffer + ringbuffer->blockSize * ringbuffer->outBlock + ringbuffer->outPos; 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dst = (deUint8*)buf + *read; 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 241f096bcea8008dac1cb75d09ee03164321dc6ad14Jarkko Pöyry deMemcpy(dst, src, (size_t)writeSize); 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->outPos += writeSize; 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *read += writeSize; 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry /* Block is consumed move to next one (or "between" this and next block) */ 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->outPos == ringbuffer->blockUsage[ringbuffer->outBlock]) 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->blockUsage[ringbuffer->outBlock] = 0; 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->outPos = 0; 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->outBlock++; 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ringbuffer->outBlock == ringbuffer->blockCount) 2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ringbuffer->outBlock = 0; 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSemaphore_increment(ringbuffer->emptyCount); 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMRESULT_SUCCESS; 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deStreamResult consumerStream_deinit (deStreamData* stream) 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(stream); 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(stream); 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMRESULT_SUCCESS; 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* There are no sensible errors so status is always good */ 2733c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeStreamStatus dummy_getStatus (deStreamData* stream) 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(stream); 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_STREAMSTATUS_GOOD; 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/* There are no sensible errors in ringbuffer */ 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const char* dummy_getError (deStreamData* stream) 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(stream); 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_UNREF(stream); 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return DE_NULL; 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const deIOStreamVFTable producerStreamVFTable = { 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_NULL, 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry producerStream_write, 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dummy_getError, 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry producerStream_flush, 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry producerStream_deinit, 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dummy_getStatus 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const deIOStreamVFTable consumerStreamVFTable = { 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry consumerStream_read, 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_NULL, 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dummy_getError, 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_NULL, 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry consumerStream_deinit, 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry dummy_getStatus 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid deProducerStream_init (deOutStream* stream, deRingbuffer* buffer) 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream->ioStream.streamData = (deStreamData*)buffer; 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream->ioStream.vfTable = &producerStreamVFTable; 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid deConsumerStream_init (deInStream* stream, deRingbuffer* buffer) 3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream->ioStream.streamData = (deStreamData*)buffer; 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry stream->ioStream.vfTable = &consumerStreamVFTable; 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 317