summaryrefslogtreecommitdiffstats
path: root/drivers/staging/epl/SharedBuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/epl/SharedBuff.c')
-rw-r--r--drivers/staging/epl/SharedBuff.c1762
1 files changed, 0 insertions, 1762 deletions
diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c
deleted file mode 100644
index 2b10c375f3e6..000000000000
--- a/drivers/staging/epl/SharedBuff.c
+++ /dev/null
@@ -1,1762 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: Project independend shared buffer (linear + circular)
-
- Description: Implementation of platform independend part for the
- shared buffer
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- 2006/06/27 -rs: V 1.00 (initial version)
-
-****************************************************************************/
-
-#if defined(WIN32) || defined(_WIN32)
-
-#ifdef UNDER_RTSS
- // RTX header
-#include <windows.h>
-#include <process.h>
-#include <rtapi.h>
-
-#elif __BORLANDC__
- // borland C header
-#include <windows.h>
-#include <process.h>
-
-#elif WINCE
-#include <windows.h>
-
-#else
- // MSVC needs to include windows.h at first
- // the following defines ar necessary for function prototypes for waitable timers
-#define _WIN32_WINDOWS 0x0401
-#define _WIN32_WINNT 0x0400
-#include <windows.h>
-#include <process.h>
-#endif
-
-#endif
-
-#include "global.h"
-#include "SharedBuff.h"
-#include "ShbIpc.h"
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// Configuration
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Constant definitions
-//---------------------------------------------------------------------------
-
-#define SBC_MAGIC_ID 0x53424323 // magic ID ("SBC#")
-#define SBL_MAGIC_ID 0x53424C23 // magic ID ("SBL#")
-
-//---------------------------------------------------------------------------
-// Local types
-//---------------------------------------------------------------------------
-
-// structure to administrate circular shared buffer head
-typedef struct {
- unsigned long m_ShbCirMagicID; // magic ID ("SBC#")
- unsigned long m_ulBufferTotalSize; // over-all size of complete buffer
- unsigned long m_ulBufferDataSize; // size of complete data area
- unsigned long m_ulWrIndex; // current write index (set bevore write)
- unsigned long m_ulRdIndex; // current read index (set after read)
- unsigned long m_ulNumOfWriteJobs; // number of currently (parallel running) write operations
- unsigned long m_ulDataInUse; // currently used buffer size (incl. uncompleted write operations)
- unsigned long m_ulDataApended; // buffer size of complete new written but not yet readable data (in case of m_ulNumOfWriteJobs>1)
- unsigned long m_ulBlocksApended; // number of complete new written but not yet readable data blocks (in case of m_ulNumOfWriteJobs>1)
- unsigned long m_ulDataReadable; // buffer size with readable (complete written) data
- unsigned long m_ulBlocksReadable; // number of readable (complete written) data blocks
- tShbCirSigHndlrNewData m_pfnSigHndlrNewData; // application handler to signal new data
- unsigned int m_fBufferLocked; // TRUE if buffer is locked (because of pending reset request)
- tShbCirSigHndlrReset m_pfnSigHndlrReset; // application handler to signal buffer reset is done
- unsigned char m_Data; // start of data area (the real data size is unknown at this time)
-
-} tShbCirBuff;
-
-// structure to administrate linear shared buffer head
-typedef struct {
- unsigned int m_ShbLinMagicID; // magic ID ("SBL#")
- unsigned long m_ulBufferTotalSize; // over-all size of complete buffer
- unsigned long m_ulBufferDataSize; // size of complete data area
- unsigned char m_Data; // start of data area (the real data size is unknown at this time)
-
-} tShbLinBuff;
-
-// type to save size of a single data block inside the circular shared buffer
-typedef struct {
- unsigned int m_uiFullBlockSize:28; // a single block must not exceed a length of 256MByte :-)
- unsigned int m_uiAlignFillBytes:4;
-
-} tShbCirBlockSize;
-
-#define SBC_BLOCK_ALIGNMENT 4 // alignment must *not* be lower than sizeof(tShbCirBlockSize)!
-#define SBC_MAX_BLOCK_SIZE ((1<<28)-1) // = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-)
-
-#define SBL_BLOCK_ALIGNMENT 4
-#define SBL_MAX_BLOCK_SIZE ((1<<28)-1) // = (2^28 - 1) = (256MByte - 1) -> should be enought for real life :-)
-
-//---------------------------------------------------------------------------
-// Global variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Local variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Prototypes of internal functions
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Get pointer to Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbCirBuff *pShbCirBuff;
-
- pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance_p);
- ASSERT(pShbCirBuff->m_ShbCirMagicID == SBC_MAGIC_ID);
-
- return (pShbCirBuff);
-
-}
-
-//---------------------------------------------------------------------------
-// Get pointer to Linear Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbLinBuff *pShbLinBuff;
-
- pShbLinBuff = (tShbLinBuff *) ShbIpcGetShMemPtr(pShbInstance_p);
- ASSERT(pShbLinBuff->m_ShbLinMagicID == SBL_MAGIC_ID);
-
- return (pShbLinBuff);
-
-}
-
-// not inlined internal functions
-int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p);
-void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
- unsigned int fTimeOut_p);
-
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-// not inlined external functions
-
-//---------------------------------------------------------------------------
-// Initialize Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbInit(void)
-{
-
- tShbError ShbError;
-
- ShbError = ShbIpcInit();
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Deinitialize Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbExit(void)
-{
-
- tShbError ShbError;
-
- ShbError = ShbIpcExit();
-
- return (ShbError);
-
-}
-
-//-------------------------------------------------------------------------//
-// //
-// C i r c u l a r S h a r e d B u f f e r //
-// //
-//-------------------------------------------------------------------------//
-
-//---------------------------------------------------------------------------
-// Allocate Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirAllocBuffer(unsigned long ulBufferSize_p,
- const char *pszBufferID_p,
- tShbInstance * ppShbInstance_p,
- unsigned int *pfShbNewCreated_p)
-{
-
- tShbInstance pShbInstance;
- tShbCirBuff *pShbCirBuff;
- unsigned int fShbNewCreated;
- unsigned long ulBufferDataSize;
- unsigned long ulBufferTotalSize;
- tShbError ShbError;
-
- // check arguments
- if ((ulBufferSize_p == 0) || (ppShbInstance_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- // calculate length of memory to allocate
- ulBufferDataSize =
- (ulBufferSize_p +
- (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
- ulBufferTotalSize = ulBufferDataSize + sizeof(tShbCirBuff);
-
- // allocate a new or open an existing shared buffer
- ShbError = ShbIpcAllocBuffer(ulBufferTotalSize, pszBufferID_p,
- &pShbInstance, &fShbNewCreated);
- if (ShbError != kShbOk) {
- goto Exit;
- }
-
- if (pShbInstance == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
-
- // get pointer to shared buffer
- pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance);
-
- // if the shared buffer was new created, than this process has
- // to initialize it, otherwise the buffer is already in use
- // and *must not* be reseted
- if (fShbNewCreated) {
-#ifndef NDEBUG
- {
- memset(pShbCirBuff, 0xCC, ulBufferTotalSize);
- }
-#endif
-
- pShbCirBuff->m_ShbCirMagicID = SBC_MAGIC_ID;
- pShbCirBuff->m_ulBufferTotalSize = ulBufferTotalSize;
- pShbCirBuff->m_ulBufferDataSize = ulBufferDataSize;
- pShbCirBuff->m_ulWrIndex = 0;
- pShbCirBuff->m_ulRdIndex = 0;
- pShbCirBuff->m_ulNumOfWriteJobs = 0;
- pShbCirBuff->m_ulDataInUse = 0;
- pShbCirBuff->m_ulDataApended = 0;
- pShbCirBuff->m_ulBlocksApended = 0;
- pShbCirBuff->m_ulDataReadable = 0;
- pShbCirBuff->m_ulBlocksReadable = 0;
- pShbCirBuff->m_pfnSigHndlrNewData = NULL;
- pShbCirBuff->m_fBufferLocked = FALSE;
- pShbCirBuff->m_pfnSigHndlrReset = NULL;
- } else {
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
- }
-
- Exit:
-
- *ppShbInstance_p = pShbInstance;
- *pfShbNewCreated_p = fShbNewCreated;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Release Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbOk;
- goto Exit;
- }
-
- ShbError = ShbIpcReleaseBuffer(pShbInstance_p);
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Reset Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
- unsigned long ulTimeOut_p,
- tShbCirSigHndlrReset pfnSignalHandlerReset_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned long ulNumOfWriteJobs = 0; // d.k. GCC complains about uninitialized variable otherwise
- tShbError ShbError;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // start reset job by setting request request in buffer header
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- if (!pShbCirBuff->m_fBufferLocked) {
- ulNumOfWriteJobs = pShbCirBuff->m_ulNumOfWriteJobs;
-
- pShbCirBuff->m_fBufferLocked = TRUE;
- pShbCirBuff->m_pfnSigHndlrReset =
- pfnSignalHandlerReset_p;
- } else {
- ShbError = kShbAlreadyReseting;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- if (ShbError != kShbOk) {
- goto Exit;
- }
-
- // if there is currently no running write operation then reset buffer
- // immediately, otherwise wait until the last write job is ready by
- // starting a signal process
- if (ulNumOfWriteJobs == 0) {
- // there is currently no running write operation
- // -> reset buffer immediately
- ShbCirSignalHandlerReset(pShbInstance_p, FALSE);
- ShbError = kShbOk;
- } else {
- // there is currently at least one running write operation
- // -> starting signal process to wait until the last write job is ready
- ShbError =
- ShbIpcStartSignalingJobReady(pShbInstance_p, ulTimeOut_p,
- ShbCirSignalHandlerReset);
- }
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Write data block to Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
- const void *pSrcDataBlock_p,
- unsigned long ulDataBlockSize_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- tShbCirBlockSize ShbCirBlockSize;
- unsigned int uiFullBlockSize;
- unsigned int uiAlignFillBytes;
- unsigned char *pShbCirDataPtr;
- unsigned char *pScrDataPtr;
- unsigned long ulDataSize;
- unsigned long ulChunkSize;
- unsigned long ulWrIndex = 0; // d.k. GCC complains about uninitialized variable otherwise
- unsigned int fSignalNewData;
- unsigned int fSignalReset;
- tShbError ShbError;
- tShbError ShbError2;
- int fRes;
-
- // check arguments
- if (pShbInstance_p == NULL) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if ((pSrcDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) {
- // nothing to do here
- ShbError = kShbOk;
- goto Exit;
- }
-
- if (ulDataBlockSize_p > SBC_MAX_BLOCK_SIZE) {
- ShbError = kShbExceedDataSizeLimit;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- pScrDataPtr = (unsigned char *)pSrcDataBlock_p;
- fSignalNewData = FALSE;
- fSignalReset = FALSE;
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // calculate data block size in circular buffer
- ulDataSize =
- (ulDataBlockSize_p +
- (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
- uiFullBlockSize = ulDataSize + sizeof(tShbCirBlockSize); // data size + header
- uiAlignFillBytes = ulDataSize - ulDataBlockSize_p;
-
- ShbCirBlockSize.m_uiFullBlockSize = uiFullBlockSize;
- ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes;
-
- // reserve the needed memory for the write operation to do now
- // and make necessary adjustments in the circular buffer header
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- // check if there is sufficient memory available to store
- // the new data
- fRes =
- uiFullBlockSize <=
- (pShbCirBuff->m_ulBufferDataSize -
- pShbCirBuff->m_ulDataInUse);
- if (fRes) {
- // set write pointer for the write operation to do now
- // to the current write pointer of the circular buffer
- ulWrIndex = pShbCirBuff->m_ulWrIndex;
-
- // reserve the needed memory for the write operation to do now
- pShbCirBuff->m_ulDataInUse += uiFullBlockSize;
-
- // set new write pointer behind the reserved memory
- // for the write operation to do now
- pShbCirBuff->m_ulWrIndex += uiFullBlockSize;
- pShbCirBuff->m_ulWrIndex %=
- pShbCirBuff->m_ulBufferDataSize;
-
- // increment number of currently (parallel running)
- // write operations
- pShbCirBuff->m_ulNumOfWriteJobs++;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- if (!fRes) {
- ShbError = kShbBufferFull;
- goto Exit;
- }
-
- // copy the data to the circular buffer
- // (the copy process itself will be done outside of any
- // critical/locked section)
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
-
- // write real size of current block (incl. alignment fill bytes)
- *(tShbCirBlockSize *) (pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize;
- ulWrIndex += sizeof(tShbCirBlockSize);
- ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- if (ulWrIndex + ulDataBlockSize_p <= pShbCirBuff->m_ulBufferDataSize) {
- // linear write operation
- memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr,
- ulDataBlockSize_p);
- } else {
- // wrap-around write operation
- ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex;
- memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulChunkSize);
- memcpy(pShbCirDataPtr, pScrDataPtr + ulChunkSize,
- ulDataBlockSize_p - ulChunkSize);
- }
-
- // adjust header information for circular buffer with properties
- // of the wiritten data block
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- pShbCirBuff->m_ulDataApended += uiFullBlockSize;
- pShbCirBuff->m_ulBlocksApended++;
-
- // decrement number of currently (parallel running) write operations
- if (!--pShbCirBuff->m_ulNumOfWriteJobs) {
- // if there is no other write process running then
- // set new size of readable (complete written) data and
- // adjust number of readable blocks
- pShbCirBuff->m_ulDataReadable +=
- pShbCirBuff->m_ulDataApended;
- pShbCirBuff->m_ulBlocksReadable +=
- pShbCirBuff->m_ulBlocksApended;
-
- pShbCirBuff->m_ulDataApended = 0;
- pShbCirBuff->m_ulBlocksApended = 0;
-
- fSignalNewData = TRUE;
- fSignalReset = pShbCirBuff->m_fBufferLocked;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- // signal new data event to a potentially reading application
- if (fSignalNewData) {
- ShbError2 = ShbIpcSignalNewData(pShbInstance_p);
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
- }
- // signal that the last write job has been finished to allow
- // a waiting application to reset the buffer now
- if (fSignalReset) {
- ShbError2 = ShbIpcSignalJobReady(pShbInstance_p);
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
- }
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Allocate block within the Circular Shared Buffer for chunk writing
-//---------------------------------------------------------------------------
-
-tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
- tShbCirChunk * pShbCirChunk_p,
- unsigned long ulDataBufferSize_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- tShbCirBlockSize ShbCirBlockSize;
- unsigned int uiFullBlockSize;
- unsigned int uiAlignFillBytes;
- unsigned char *pShbCirDataPtr;
- unsigned long ulDataSize;
- unsigned long ulWrIndex = 0; // d.k. GCC complains about uninitialized variable otherwise
- tShbError ShbError;
- int fRes;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL)) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if (ulDataBufferSize_p == 0) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if (ulDataBufferSize_p > SBC_MAX_BLOCK_SIZE) {
- ShbError = kShbExceedDataSizeLimit;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // calculate data block size in circular buffer
- ulDataSize =
- (ulDataBufferSize_p +
- (SBC_BLOCK_ALIGNMENT - 1)) & ~(SBC_BLOCK_ALIGNMENT - 1);
- uiFullBlockSize = ulDataSize + sizeof(tShbCirBlockSize); // data size + header
- uiAlignFillBytes = ulDataSize - ulDataBufferSize_p;
-
- ShbCirBlockSize.m_uiFullBlockSize = uiFullBlockSize;
- ShbCirBlockSize.m_uiAlignFillBytes = uiAlignFillBytes;
-
- // reserve the needed memory for the write operation to do now
- // and make necessary adjustments in the circular buffer header
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- // check if there is sufficient memory available to store
- // the new data
- fRes =
- (uiFullBlockSize <=
- (pShbCirBuff->m_ulBufferDataSize -
- pShbCirBuff->m_ulDataInUse));
- if (fRes) {
- // set write pointer for the write operation to do now
- // to the current write pointer of the circular buffer
- ulWrIndex = pShbCirBuff->m_ulWrIndex;
-
- // reserve the needed memory for the write operation to do now
- pShbCirBuff->m_ulDataInUse += uiFullBlockSize;
-
- // set new write pointer behind the reserved memory
- // for the write operation to do now
- pShbCirBuff->m_ulWrIndex += uiFullBlockSize;
- pShbCirBuff->m_ulWrIndex %=
- pShbCirBuff->m_ulBufferDataSize;
-
- // increment number of currently (parallel running)
- // write operations
- pShbCirBuff->m_ulNumOfWriteJobs++;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- if (!fRes) {
- ShbError = kShbBufferFull;
- goto Exit;
- }
-
- // setup header information for allocated buffer
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
-
- // write real size of current block (incl. alignment fill bytes)
- *(tShbCirBlockSize *) (pShbCirDataPtr + ulWrIndex) = ShbCirBlockSize;
- ulWrIndex += sizeof(tShbCirBlockSize);
- ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- // setup chunk descriptor
- pShbCirChunk_p->m_uiFullBlockSize = uiFullBlockSize;
- pShbCirChunk_p->m_ulAvailableSize = ulDataBufferSize_p;
- pShbCirChunk_p->m_ulWrIndex = ulWrIndex;
- pShbCirChunk_p->m_fBufferCompleted = FALSE;
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Write data chunk into an allocated buffer of the Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
- tShbCirChunk *pShbCirChunk_p,
- const void *pSrcDataChunk_p,
- unsigned long ulDataChunkSize_p,
- unsigned int *pfBufferCompleted_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned char *pShbCirDataPtr;
- unsigned char *pScrDataPtr;
- unsigned long ulSubChunkSize;
- unsigned long ulWrIndex;
- unsigned int fBufferCompleted;
- unsigned int fSignalNewData;
- unsigned int fSignalReset;
- tShbError ShbError;
- tShbError ShbError2;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pShbCirChunk_p == NULL)
- || (pfBufferCompleted_p == NULL)) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- if ((pSrcDataChunk_p == NULL) || (ulDataChunkSize_p == 0)) {
- // nothing to do here
- ShbError = kShbOk;
- goto Exit;
- }
-
- if (pShbCirChunk_p->m_fBufferCompleted) {
- ShbError = kShbBufferAlreadyCompleted;
- goto Exit;
- }
-
- if (ulDataChunkSize_p > pShbCirChunk_p->m_ulAvailableSize) {
- ShbError = kShbExceedDataSizeLimit;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- pScrDataPtr = (unsigned char *)pSrcDataChunk_p;
- fSignalNewData = FALSE;
- fSignalReset = FALSE;
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- ulWrIndex = pShbCirChunk_p->m_ulWrIndex;
-
- // copy the data to the circular buffer
- // (the copy process itself will be done outside of any
- // critical/locked section)
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
-
- if (ulWrIndex + ulDataChunkSize_p <= pShbCirBuff->m_ulBufferDataSize) {
- // linear write operation
- memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr,
- ulDataChunkSize_p);
- } else {
- // wrap-around write operation
- ulSubChunkSize = pShbCirBuff->m_ulBufferDataSize - ulWrIndex;
- memcpy(pShbCirDataPtr + ulWrIndex, pScrDataPtr, ulSubChunkSize);
- memcpy(pShbCirDataPtr, pScrDataPtr + ulSubChunkSize,
- ulDataChunkSize_p - ulSubChunkSize);
- }
-
- // adjust chunk descriptor
- ulWrIndex += ulDataChunkSize_p;
- ulWrIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- pShbCirChunk_p->m_ulAvailableSize -= ulDataChunkSize_p;
- pShbCirChunk_p->m_ulWrIndex = ulWrIndex;
-
- fBufferCompleted = (pShbCirChunk_p->m_ulAvailableSize == 0);
- pShbCirChunk_p->m_fBufferCompleted = fBufferCompleted;
-
- // if the complete allocated buffer is filled with data then
- // adjust header information for circular buffer with properties
- // of the wiritten data block
- if (fBufferCompleted) {
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- pShbCirBuff->m_ulDataApended +=
- pShbCirChunk_p->m_uiFullBlockSize;
- pShbCirBuff->m_ulBlocksApended++;
-
- // decrement number of currently (parallel running) write operations
- if (!--pShbCirBuff->m_ulNumOfWriteJobs) {
- // if there is no other write process running then
- // set new size of readable (complete written) data and
- // adjust number of readable blocks
- pShbCirBuff->m_ulDataReadable +=
- pShbCirBuff->m_ulDataApended;
- pShbCirBuff->m_ulBlocksReadable +=
- pShbCirBuff->m_ulBlocksApended;
-
- pShbCirBuff->m_ulDataApended = 0;
- pShbCirBuff->m_ulBlocksApended = 0;
-
- fSignalNewData = TRUE;
- fSignalReset = pShbCirBuff->m_fBufferLocked;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
- }
-
- // signal new data event to a potentially reading application
- if (fSignalNewData) {
- ShbError2 = ShbIpcSignalNewData(pShbInstance_p);
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
- }
- // signal that the last write job has been finished to allow
- // a waiting application to reset the buffer now
- if (fSignalReset) {
- ShbError2 = ShbIpcSignalJobReady(pShbInstance_p);
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
- }
-
- *pfBufferCompleted_p = fBufferCompleted;
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Read data block from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
- void *pDstDataBlock_p,
- unsigned long ulRdBuffSize_p,
- unsigned long *pulDataBlockSize_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- tShbCirBlockSize ShbCirBlockSize;
- unsigned long ulDataReadable;
- unsigned char *pShbCirDataPtr;
- unsigned char *pDstDataPtr;
- unsigned long ulDataSize = 0; // d.k. GCC complains about uninitialized variable otherwise
- unsigned long ulChunkSize;
- unsigned long ulRdIndex;
- tShbError ShbError;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- if ((pDstDataBlock_p == NULL) || (ulRdBuffSize_p == 0)) {
- // nothing to do here
- ShbError = kShbOk;
- goto Exit;
- }
-
- ShbError = kShbOk;
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- pDstDataPtr = (unsigned char *)pDstDataBlock_p;
- ulDataSize = 0;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // get total number of readable bytes for the whole circular buffer
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- ulDataReadable = pShbCirBuff->m_ulDataReadable;
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- // if there are readable data available, then there must be at least
- // one complete readable data block
- if (ulDataReadable > 0) {
- // get pointer to start of data area and current read index
- pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area
- ulRdIndex = pShbCirBuff->m_ulRdIndex;
-
- // get real size of current block (incl. alignment fill bytes)
- ShbCirBlockSize =
- *(tShbCirBlockSize *) (pShbCirDataPtr + ulRdIndex);
- ulRdIndex += sizeof(tShbCirBlockSize);
- ulRdIndex %= pShbCirBuff->m_ulBufferDataSize;
-
- // get size of user data inside the current block
- ulDataSize =
- ShbCirBlockSize.m_uiFullBlockSize -
- ShbCirBlockSize.m_uiAlignFillBytes;
- ulDataSize -= sizeof(tShbCirBlockSize);
- }
-
- // ulDataSize = MIN(ulDataSize, ulRdBuffSize_p);
- if (ulDataSize > ulRdBuffSize_p) {
- ulDataSize = ulRdBuffSize_p;
- ShbError = kShbDataTruncated;
- }
-
- if (ulDataSize == 0) {
- // nothing to do here
- ShbError = kShbNoReadableData;
- goto Exit;
- }
-
- // copy the data from the circular buffer
- // (the copy process itself will be done outside of any
- // critical/locked section)
- if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) {
- // linear read operation
- memcpy(pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulDataSize);
- } else {
- // wrap-around read operation
- ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
- memcpy(pDstDataPtr, pShbCirDataPtr + ulRdIndex, ulChunkSize);
- memcpy(pDstDataPtr + ulChunkSize, pShbCirDataPtr,
- ulDataSize - ulChunkSize);
- }
-
-#ifndef NDEBUG
- {
- tShbCirBlockSize ClrShbCirBlockSize;
-
- if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) {
- // linear buffer
- memset(pShbCirDataPtr + ulRdIndex, 0xDD, ulDataSize);
- } else {
- // wrap-around read operation
- ulChunkSize =
- pShbCirBuff->m_ulBufferDataSize - ulRdIndex;
- memset(pShbCirDataPtr + ulRdIndex, 0xDD, ulChunkSize);
- memset(pShbCirDataPtr, 0xDD, ulDataSize - ulChunkSize);
- }
-
- ClrShbCirBlockSize.m_uiFullBlockSize = /*(unsigned int) */ -1; // -1 = xFFFFFFF
- ClrShbCirBlockSize.m_uiAlignFillBytes = /*(unsigned int) */ -1; // -1 = Fxxxxxxx
- *(tShbCirBlockSize *) (pShbCirDataPtr +
- pShbCirBuff->m_ulRdIndex) =
- ClrShbCirBlockSize;
- }
-#endif // #ifndef NDEBUG
-
- // set new size of readable data, data in use, new read index
- // and adjust number of readable blocks
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- pShbCirBuff->m_ulDataInUse -= ShbCirBlockSize.m_uiFullBlockSize;
- pShbCirBuff->m_ulDataReadable -=
- ShbCirBlockSize.m_uiFullBlockSize;
- pShbCirBuff->m_ulBlocksReadable--;
-
- //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
- if ((pShbCirBuff->m_ulDataInUse == 0)
- && (pShbCirBuff->m_ulDataReadable == 0)) {
- ASSERT(pShbCirBuff->m_ulBlocksReadable == 0);
-
- pShbCirBuff->m_ulWrIndex = 0;
- pShbCirBuff->m_ulRdIndex = 0;
- } else
- //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
- {
- pShbCirBuff->m_ulRdIndex +=
- ShbCirBlockSize.m_uiFullBlockSize;
- pShbCirBuff->m_ulRdIndex %=
- pShbCirBuff->m_ulBufferDataSize;
- }
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- Exit:
-
- *pulDataBlockSize_p = ulDataSize;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Get data size of next readable block from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
- unsigned long *pulDataBlockSize_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned long ulDataReadable;
- unsigned char *pShbCirDataPtr;
- tShbCirBlockSize ShbCirBlockSize;
- unsigned long ulDataSize;
- tShbError ShbError;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ulDataSize = 0;
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- // get total number of readable bytes for the whole circular buffer
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- ulDataReadable = pShbCirBuff->m_ulDataReadable;
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- // if there are readable data available, then there must be at least
- // one complete readable data block
- if (ulDataReadable > 0) {
- pShbCirDataPtr =
- &pShbCirBuff->m_Data + pShbCirBuff->m_ulRdIndex;
-
- // get real size of current block (incl. alignment fill bytes)
- ShbCirBlockSize = *(tShbCirBlockSize *) pShbCirDataPtr;
-
- // get size of user data inside the current block
- ulDataSize =
- ShbCirBlockSize.m_uiFullBlockSize -
- ShbCirBlockSize.m_uiAlignFillBytes;
- ulDataSize -= sizeof(tShbCirBlockSize);
- }
-
- Exit:
-
- *pulDataBlockSize_p = ulDataSize;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Get number of readable blocks from Circular Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
- unsigned long *pulDataBlockCount_p)
-{
-
- tShbCirBuff *pShbCirBuff;
- unsigned long ulBlockCount;
- tShbError ShbError;
-
- // check arguments
- if ((pShbInstance_p == NULL) || (pulDataBlockCount_p == NULL)) {
- ShbError = kShbInvalidArg;
- goto Exit;
- }
-
- pShbCirBuff = ShbCirGetBuffer(pShbInstance_p);
- ulBlockCount = 0;
- ShbError = kShbOk;
-
- if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) {
- ShbError = kShbInvalidBufferType;
- goto Exit;
- }
-
- ShbIpcEnterAtomicSection(pShbInstance_p);
- {
- ulBlockCount = pShbCirBuff->m_ulBlocksReadable;
- }
- ShbIpcLeaveAtomicSection(pShbInstance_p);
-
- *pulDataBlockCount_p = ulBlockCount;
-
- Exit:
-
- return (ShbError);
-
-}
-
-//------------------------------------------------