From 9d7164cfdb611c2f864d535ae5794f23db3d84f7 Mon Sep 17 00:00:00 2001 From: Daniel Krueger Date: Fri, 19 Dec 2008 11:41:57 -0800 Subject: Staging: add epl stack This is the openPOWERLINK network stack from systec electronic. It's a bit messed up as there is a driver mixed into the middle of it, lots of work needs to be done to unwind the different portions to make it sane. Cc: Daniel Krueger Cc: Ronald Sieber Signed-off-by: Greg Kroah-Hartman --- drivers/staging/epl/SharedBuff.c | 2041 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 2041 insertions(+) create mode 100644 drivers/staging/epl/SharedBuff.c (limited to 'drivers/staging/epl/SharedBuff.c') diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c new file mode 100644 index 0000000..1833d71 --- /dev/null +++ b/drivers/staging/epl/SharedBuff.c @@ -0,0 +1,2041 @@ +/**************************************************************************** + + (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 + #include + #include + + #elif __BORLANDC__ + // borland C header + #include + #include + + #elif WINCE + #include + + #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 + #include + #endif + +#endif + +#include "global.h" +#include "SharedBuff.h" +#include "ShbIpc.h" + +// d.k. Linux kernel modules needs other header files for memcpy() +#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__) + #include +#else + #include + #include + #include +#endif + + + + +/***************************************************************************/ +/* */ +/* */ +/* G L O B A L D E F I N I T I O N S */ +/* */ +/* */ +/***************************************************************************/ + +#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED) + +//--------------------------------------------------------------------------- +// 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 +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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 +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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); + +#endif + + + +//=========================================================================// +// // +// P U B L I C F U N C T I O N S // +// // +//=========================================================================// + +#if !defined(INLINE_ENABLED) +// 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); + +} + + +#endif // !defined(INLINE_ENABLED) + +#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED) + +//--------------------------------------------------------------------------- +// Reset Circular Shared Buffer +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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 +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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 +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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 +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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 +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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 +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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 +//--------------------------------------------------------------------------- + +INLINE_FUNCTION 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); + +} + + + +//--------------------------------------------------------------------------- +// Set application handler to signal new data for Circular Shared Buffer +// d.k.: new parameter priority as enum +//--------------------------------------------------------------------------- + +INLINE_FUNCTION tShbError ShbCirSetSignalHandlerNewData ( + tShbInstance pShbInstance_p, + tShbCirSigHndlrNewData pfnSignalHandlerNewData_p, + tShbPriority ShbPriority_p) +{ + +tShbCirBuff* pShbCirBuff; +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; + } + + + if (pfnSignalHandlerNewData_p != NULL) + { + // set a new signal handler + if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) + { + ShbError = kShbAlreadySignaling; + goto Exit; + } + + pShbCirBuff->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p; + ShbError = ShbIpcStartSignalingNewData (pShbInstance_p, ShbCirSignalHandlerNewData, ShbPriority_p); + } + else + { + // remove existing signal handler + ShbError = ShbIpcStopSignalingNewData (pShbInstance_p); + if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) + { + pShbCirBuff->m_pfnSigHndlrNewData (pShbInstance_p, 0); + } + pShbCirBuff->m_pfnSigHndlrNewData = NULL; + } + + +Exit: + + return (ShbError); + +} + +#endif + +#if !defined(INLINE_ENABLED) + +//--------------------------------------------------------------------------- +// DEBUG: Trace Circular Shared Buffer +//--------------------------------------------------------------------------- + +#ifndef NDEBUG +tShbError ShbCirTraceBuffer ( + tShbInstance pShbInstance_p) +{ + +tShbCirBuff* pShbCirBuff; +char szMagigID[sizeof(SBC_MAGIC_ID)+1]; +tShbCirBlockSize ShbCirBlockSize; +unsigned long ulDataReadable; +unsigned char* pShbCirDataPtr; +unsigned long ulBlockIndex; +unsigned int nBlockCount; +unsigned long ulDataSize; +unsigned long ulChunkSize; +unsigned long ulRdIndex; +tShbError ShbError; + + + TRACE0("\n\n##### Circular Shared Buffer #####\n"); + + // check arguments + if (pShbInstance_p == NULL) + { + TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", (unsigned long)pShbInstance_p); + ShbError = kShbInvalidArg; + goto Exit; + } + + + pShbCirBuff = ShbCirGetBuffer (pShbInstance_p); + ShbError = kShbOk; + + if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) + { + ShbError = kShbInvalidBufferType; + goto Exit; + } + + + *(unsigned long*) &szMagigID[0] = pShbCirBuff->m_ShbCirMagicID; + szMagigID[sizeof(SBC_MAGIC_ID)] = '\0'; + + + ShbIpcEnterAtomicSection (pShbInstance_p); + { + TRACE1("\nBuffer Address: 0x%08lX\n", (unsigned long)pShbCirBuff); + + TRACE0("\nHeader Info:"); + TRACE2("\nMagigID: '%s' (%08lX)", szMagigID, pShbCirBuff->m_ShbCirMagicID); + TRACE1("\nBufferTotalSize: %4lu [Bytes]", pShbCirBuff->m_ulBufferTotalSize); + TRACE1("\nBufferDataSize: %4lu [Bytes]", pShbCirBuff->m_ulBufferDataSize); + TRACE1("\nWrIndex: %4lu", pShbCirBuff->m_ulWrIndex); + TRACE1("\nRdIndex: %4lu", pShbCirBuff->m_ulRdIndex); + TRACE1("\nNumOfWriteJobs: %4lu", pShbCirBuff->m_ulNumOfWriteJobs); + TRACE1("\nDataInUse: %4lu [Bytes]", pShbCirBuff->m_ulDataInUse); + TRACE1("\nDataApended: %4lu [Bytes]", pShbCirBuff->m_ulDataApended); + TRACE1("\nBlocksApended: %4lu", pShbCirBuff->m_ulBlocksApended); + TRACE1("\nDataReadable: %4lu [Bytes]", pShbCirBuff->m_ulDataReadable); + TRACE1("\nBlocksReadable: %4lu", pShbCirBuff->m_ulBlocksReadable); + TRACE1("\nSigHndlrNewData: %08lX", (unsigned long)pShbCirBuff->m_pfnSigHndlrNewData); + TRACE1("\nBufferLocked: %d", pShbCirBuff->m_fBufferLocked); + TRACE1("\nSigHndlrReset: %08lX", (unsigned long)pShbCirBuff->m_pfnSigHndlrReset); + + ShbTraceDump (&pShbCirBuff->m_Data, pShbCirBuff->m_ulBufferDataSize, + 0x00000000L, "\nData Area:"); + + + ulDataReadable = pShbCirBuff->m_ulDataReadable; + nBlockCount = 1; + ulBlockIndex = pShbCirBuff->m_ulRdIndex; + + while (ulDataReadable > 0) + { + TRACE1("\n\n--- Block #%u ---", nBlockCount); + + // get pointer to start of data area and current read index + pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area + ulRdIndex = ulBlockIndex; + + // 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); + + TRACE1("\nFull Data Size: %4u [Bytes] (incl. header and alignment fill bytes)", ShbCirBlockSize.m_uiFullBlockSize); + TRACE1("\nUser Data Size: %4lu [Bytes]", ulDataSize); + TRACE1("\nAlignment Fill Bytes: %4u [Bytes]", ShbCirBlockSize.m_uiAlignFillBytes); + + + if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) + { + // linear data buffer + ShbTraceDump (pShbCirDataPtr + ulRdIndex, ulDataSize, 0x00000000L, NULL); + } + else + { + // wrap-around data buffer + ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex; + ShbTraceDump (pShbCirDataPtr + ulRdIndex, ulChunkSize, 0x00000000L, NULL); + ShbTraceDump (pShbCirDataPtr, ulDataSize - ulChunkSize, ulChunkSize, NULL); + } + + nBlockCount++; + + ulBlockIndex += ShbCirBlockSize.m_uiFullBlockSize; + ulBlockIndex %= pShbCirBuff->m_ulBufferDataSize; + + ulDataReadable -= ShbCirBlockSize.m_uiFullBlockSize; + } + + ASSERT(pShbCirBuff->m_ulBlocksReadable == nBlockCount-1); + } + ShbIpcLeaveAtomicSection (pShbInstance_p); + + + +Exit: + + return (ShbError); + +} +#endif + + + + + +//-------------------------------------------------------------------------// +// // +// L i n e a r S h a r e d B u f f e r // +// // +//-------------------------------------------------------------------------// + +//--------------------------------------------------------------------------- +// Allocate Linear Shared Buffer +//--------------------------------------------------------------------------- + +tShbError ShbLinAllocBuffer ( + unsigned long ulBufferSize_p, + const char* pszBufferID_p, + tShbInstance* ppShbInstance_p, + unsigned int* pfShbNewCreated_p) +{ + +tShbInstance pShbInstance; +tShbLinBuff* pShbLinBuff; +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 + (SBL_BLOCK_ALIGNMENT-1)) & ~(SBL_BLOCK_ALIGNMENT-1); + ulBufferTotalSize = ulBufferDataSize + sizeof(tShbLinBuff); + + // 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 + pShbLinBuff = (tShbLinBuff*) 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 (pShbLinBuff, 0xCC, ulBufferTotalSize); + } + #endif + + + pShbLinBuff->m_ShbLinMagicID = SBL_MAGIC_ID; + pShbLinBuff->m_ulBufferTotalSize = ulBufferTotalSize; + pShbLinBuff->m_ulBufferDataSize = ulBufferDataSize; + } + else + { + if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) + { + ShbError = kShbInvalidBufferType; + goto Exit; + } + } + + +Exit: + + *ppShbInstance_p = pShbInstance; + *pfShbNewCreated_p = fShbNewCreated; + + return (ShbError); + +} + + + +//--------------------------------------------------------------------------- +// Release Linear Shared Buffer +//--------------------------------------------------------------------------- + +tShbError ShbLinReleaseBuffer ( + tShbInstance pShbInstance_p) +{ + +tShbError ShbError; + + + // check arguments + if (pShbInstance_p == NULL) + { + ShbError = kShbOk; + goto Exit; + } + + + ShbError = ShbIpcReleaseBuffer (pShbInstance_p); + + +Exit: + + return (ShbError); + +} + + +#endif // !defined(INLINE_ENABLED) + +#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED) + +//--------------------------------------------------------------------------- +// Write data block to Linear Shared Buffer +//--------------------------------------------------------------------------- + +INLINE_FUNCTION tShbError ShbLinWriteDataBlock ( + tShbInstance pShbInstance_p, + unsigned long ulDstBufferOffs_p, + const void* pSrcDataBlock_p, + unsigned long ulDataBlockSize_p) +{ + +tShbLinBuff* pShbLinBuff; +unsigned char* pShbLinDataPtr; +unsigned char* pScrDataPtr; +unsigned long ulBufferDataSize; +tShbError ShbError; + + + // 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 > SBL_MAX_BLOCK_SIZE) + { + ShbError = kShbExceedDataSizeLimit; + goto Exit; + } + + + pShbLinBuff = ShbLinGetBuffer (pShbInstance_p); + pScrDataPtr = (unsigned char*)pSrcDataBlock_p; + ShbError = kShbOk; + + if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) + { + ShbError = kShbInvalidBufferType; + goto Exit; + } + + + // check if offeset and size for the write operation matches with + // the size of the shared buffer + ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize; + if ( (ulDstBufferOffs_p > ulBufferDataSize) || + (ulDataBlockSize_p > ulBufferDataSize) || + ((ulDstBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize) ) + { + ShbError = kShbDataOutsideBufferArea; + goto Exit; + } + + + // copy the data to the linear buffer + // (the copy process will be done inside of any critical/locked section) + pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area + pShbLinDataPtr += ulDstBufferOffs_p; + + ShbIpcEnterAtomicSection (pShbInstance_p); + { + memcpy (pShbLinDataPtr, pScrDataPtr, ulDataBlockSize_p); + } + ShbIpcLeaveAtomicSection (pShbInstance_p); + + +Exit: + + return (ShbError); + +} + + + +//--------------------------------------------------------------------------- +// Read data block from Linear Shared Buffer +//--------------------------------------------------------------------------- + +INLINE_FUNCTION tShbError ShbLinReadDataBlock ( + tShbInstance pShbInstance_p, + void* pDstDataBlock_p, + unsigned long ulSrcBufferOffs_p, + unsigned long ulDataBlockSize_p) +{ + +tShbLinBuff* pShbLinBuff; +unsigned char* pShbLinDataPtr; +unsigned char* pDstDataPtr; +unsigned long ulBufferDataSize; +tShbError ShbError; + + + // check arguments + if (pShbInstance_p == NULL) + { + ShbError = kShbInvalidArg; + goto Exit; + } + + if ((pDstDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) + { + // nothing to do here + ShbError = kShbOk; + goto Exit; + } + + if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) + { + ShbError = kShbExceedDataSizeLimit; + goto Exit; + } + + + pShbLinBuff = ShbLinGetBuffer (pShbInstance_p); + pDstDataPtr = (unsigned char*)pDstDataBlock_p; + ShbError = kShbOk; + + if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) + { + ShbError = kShbInvalidBufferType; + goto Exit; + } + + + // check if offeset and size for the read operation matches with + // the size of the shared buffer + ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize; + if ( (ulSrcBufferOffs_p > ulBufferDataSize) || + (ulDataBlockSize_p > ulBufferDataSize) || + ((ulSrcBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize) ) + { + ShbError = kShbDataOutsideBufferArea; + goto Exit; + } + + + // copy the data to the linear buffer + // (the copy process will be done inside of any critical/locked section) + pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area + pShbLinDataPtr += ulSrcBufferOffs_p; + + ShbIpcEnterAtomicSection (pShbInstance_p); + { + memcpy (pDstDataPtr, pShbLinDataPtr, ulDataBlockSize_p); + } + ShbIpcLeaveAtomicSection (pShbInstance_p); + + +Exit: + + return (ShbError); + +} + +#endif + + +#if !defined(INLINE_ENABLED) + + +//--------------------------------------------------------------------------- +// DEBUG: Trace Linear Shared Buffer +//--------------------------------------------------------------------------- + +#ifndef NDEBUG +tShbError ShbLinTraceBuffer ( + tShbInstance pShbInstance_p) +{ + +tShbLinBuff* pShbLinBuff; +char szMagigID[sizeof(SBL_MAGIC_ID)+1]; +tShbError ShbError; + + + TRACE0("\n\n##### Linear Shared Buffer #####\n"); + + // check arguments + if (pShbInstance_p == NULL) + { + TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", (unsigned long)pShbInstance_p); + ShbError = kShbInvalidArg; + goto Exit; + } + + + pShbLinBuff = ShbLinGetBuffer (pShbInstance_p); + ShbError = kShbOk; + + if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) + { + ShbError = kShbInvalidBufferType; + goto Exit; + } + + + *(unsigned int*) &szMagigID[0] = pShbLinBuff->m_ShbLinMagicID; + szMagigID[sizeof(SBL_MAGIC_ID)] = '\0'; + + + ShbIpcEnterAtomicSection (pShbInstance_p); + { + TRACE1("\nBuffer Address: 0x%08lX\n", (unsigned long)pShbLinBuff); + + TRACE0("\nHeader Info:"); + TRACE2("\nMagigID: '%s' (%08X)", szMagigID, pShbLinBuff->m_ShbLinMagicID); + TRACE1("\nBufferTotalSize: %4lu [Bytes]", pShbLinBuff->m_ulBufferTotalSize); + TRACE1("\nBufferDataSize: %4lu [Bytes]", pShbLinBuff->m_ulBufferDataSize); + + ShbTraceDump (&pShbLinBuff->m_Data, pShbLinBuff->m_ulBufferDataSize, + 0x00000000L, "\nData Area:"); + } + ShbIpcLeaveAtomicSection (pShbInstance_p); + + + +Exit: + + return (ShbError); + +} +#endif + + + + + +//--------------------------------------------------------------------------- +// Dump buffer contents +//--------------------------------------------------------------------------- + +#ifndef NDEBUG +tShbError ShbTraceDump ( + const unsigned char* pabStartAddr_p, + unsigned long ulDataSize_p, + unsigned long ulAddrOffset_p, + const char* pszInfoText_p) +{ + +const unsigned char* pabBuffData; +unsigned long ulBuffSize; +unsigned char bData; +int nRow; +int nCol; + + + // get pointer to buffer and length of buffer + pabBuffData = pabStartAddr_p; + ulBuffSize = ulDataSize_p; + + + if (pszInfoText_p != NULL) + { + TRACE0(pszInfoText_p); + } + + // dump buffer contents + for (nRow=0; ; nRow++) + { + TRACE1("\n%08lX: ", (unsigned long)(nRow*0x10) + ulAddrOffset_p); + + for (nCol=0; nCol<16; nCol++) + { + if ((unsigned long)nCol < ulBuffSize) + { + TRACE1("%02X ", (unsigned int)*(pabBuffData+nCol)); + } + else + { + TRACE0(" "); + } + } + + TRACE0(" "); + + for (nCol=0; nCol<16; nCol++) + { + bData = *pabBuffData++; + if ((unsigned long)nCol < ulBuffSize) + { + if ((bData >= 0x20) && (bData < 0x7F)) + { + TRACE1("%c", bData); + } + else + { + TRACE0("."); + } + } + else + { + TRACE0(" "); + } + } + + if (ulBuffSize > 16) + { + ulBuffSize -= 16; + } + else + { + break; + } + } + + + return (kShbOk); + +} +#endif // #ifndef NDEBUG + + + + + + + +//=========================================================================// +// // +// P R I V A T E F U N C T I O N S // +// // +//=========================================================================// + +//--------------------------------------------------------------------------- +// Handler to signal new data event for Circular Shared Buffer +//--------------------------------------------------------------------------- + +int ShbCirSignalHandlerNewData ( + tShbInstance pShbInstance_p) +{ + +tShbCirBuff* pShbCirBuff; +unsigned long ulDataSize; +unsigned long ulBlockCount; +tShbError ShbError; + + + // check arguments + if (pShbInstance_p == NULL) + { + return FALSE; + } + + pShbCirBuff = ShbCirGetBuffer (pShbInstance_p); + ShbError = kShbOk; + + if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) + { + return FALSE; + } + + + // call application handler + if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) + { +/* do + {*/ + ShbError = ShbCirGetReadDataSize (pShbInstance_p, &ulDataSize); + if ((ulDataSize > 0) && (ShbError == kShbOk)) + { + pShbCirBuff->m_pfnSigHndlrNewData (pShbInstance_p, ulDataSize); + } + + ShbError = ShbCirGetReadBlockCount (pShbInstance_p, &ulBlockCount); +/* } + while ((ulBlockCount > 0) && (ShbError == kShbOk));*/ + } + + // Return TRUE if there are pending blocks. + // In that case ShbIpc tries to call this function again immediately if there + // is no other filled shared buffer with higher priority. + return ((ulBlockCount > 0) && (ShbError == kShbOk)); + +} + + + +//--------------------------------------------------------------------------- +// Handler to reset Circular Shared Buffer +//--------------------------------------------------------------------------- + +void ShbCirSignalHandlerReset ( + tShbInstance pShbInstance_p, + unsigned int fTimeOut_p) +{ + +tShbCirBuff* pShbCirBuff; + + + // check arguments + if (pShbInstance_p == NULL) + { + return; + } + + pShbCirBuff = ShbCirGetBuffer (pShbInstance_p); + if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) + { + return; + } + + + // reset buffer header + if ( !fTimeOut_p ) + { + ShbIpcEnterAtomicSection (pShbInstance_p); + { + 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; + } + ShbIpcLeaveAtomicSection (pShbInstance_p); + + + #ifndef NDEBUG + { + memset (&pShbCirBuff->m_Data, 0xCC, pShbCirBuff->m_ulBufferDataSize); + } + #endif + } + + + // call application handler + if (pShbCirBuff->m_pfnSigHndlrReset != NULL) + { + pShbCirBuff->m_pfnSigHndlrReset (pShbInstance_p, fTimeOut_p); + } + + + // unlock buffer + ShbIpcEnterAtomicSection (pShbInstance_p); + { + pShbCirBuff->m_fBufferLocked = FALSE; + pShbCirBuff->m_pfnSigHndlrReset = NULL; + } + ShbIpcLeaveAtomicSection (pShbInstance_p); + + + return; + +} + +#endif + + +// EOF + -- cgit v1.1 From 833dfbe746f85898dcbcf421c1177c3fd5773ff2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 19 Dec 2008 17:11:52 -0800 Subject: Staging: epl: run Lindent on *.c files It's a start, still a mess... Cc: Daniel Krueger Cc: Ronald Sieber Signed-off-by: Greg Kroah-Hartman --- drivers/staging/epl/SharedBuff.c | 2960 +++++++++++++++++--------------------- 1 file changed, 1359 insertions(+), 1601 deletions(-) (limited to 'drivers/staging/epl/SharedBuff.c') diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c index 1833d71..9fb09d6 100644 --- a/drivers/staging/epl/SharedBuff.c +++ b/drivers/staging/epl/SharedBuff.c @@ -56,28 +56,28 @@ #if defined(WIN32) || defined(_WIN32) - #ifdef UNDER_RTSS - // RTX header - #include - #include - #include - - #elif __BORLANDC__ - // borland C header - #include - #include - - #elif WINCE - #include - - #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 - #include - #endif +#ifdef UNDER_RTSS + // RTX header +#include +#include +#include + +#elif __BORLANDC__ + // borland C header +#include +#include + +#elif WINCE +#include + +#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 +#include +#endif #endif @@ -87,16 +87,13 @@ // d.k. Linux kernel modules needs other header files for memcpy() #if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__) - #include +#include #else - #include - #include - #include +#include +#include +#include #endif - - - /***************************************************************************/ /* */ /* */ @@ -111,82 +108,67 @@ // Configuration //--------------------------------------------------------------------------- - - //--------------------------------------------------------------------------- // Constant definitions //--------------------------------------------------------------------------- -#define SBC_MAGIC_ID 0x53424323 // magic ID ("SBC#") -#define SBL_MAGIC_ID 0x53424C23 // magic ID ("SBL#") - - +#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) +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) +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; +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 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 :-) - - +#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 //--------------------------------------------------------------------------- @@ -195,50 +177,41 @@ typedef struct // Get pointer to Circular Shared Buffer //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbCirBuff* ShbCirGetBuffer ( - tShbInstance pShbInstance_p) +INLINE_FUNCTION tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p) { -tShbCirBuff* pShbCirBuff; - + tShbCirBuff *pShbCirBuff; - pShbCirBuff = (tShbCirBuff*) ShbIpcGetShMemPtr (pShbInstance_p); - ASSERT(pShbCirBuff->m_ShbCirMagicID == SBC_MAGIC_ID); + pShbCirBuff = (tShbCirBuff *) ShbIpcGetShMemPtr(pShbInstance_p); + ASSERT(pShbCirBuff->m_ShbCirMagicID == SBC_MAGIC_ID); - return (pShbCirBuff); + return (pShbCirBuff); } - - //--------------------------------------------------------------------------- // Get pointer to Linear Shared Buffer //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbLinBuff* ShbLinGetBuffer ( - tShbInstance pShbInstance_p) +INLINE_FUNCTION tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p) { -tShbLinBuff* pShbLinBuff; + tShbLinBuff *pShbLinBuff; + pShbLinBuff = (tShbLinBuff *) ShbIpcGetShMemPtr(pShbInstance_p); + ASSERT(pShbLinBuff->m_ShbLinMagicID == SBL_MAGIC_ID); - pShbLinBuff = (tShbLinBuff*) ShbIpcGetShMemPtr (pShbInstance_p); - ASSERT(pShbLinBuff->m_ShbLinMagicID == SBL_MAGIC_ID); - - return (pShbLinBuff); + return (pShbLinBuff); } - - // not inlined internal functions -int ShbCirSignalHandlerNewData (tShbInstance pShbInstance_p); -void ShbCirSignalHandlerReset (tShbInstance pShbInstance_p, unsigned int fTimeOut_p); +int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p); +void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p, + unsigned int fTimeOut_p); #endif - - //=========================================================================// // // // P U B L I C F U N C T I O N S // @@ -252,40 +225,32 @@ void ShbCirSignalHandlerReset (tShbInstance pShbInstance_p, unsigned // Initialize Shared Buffer Module //--------------------------------------------------------------------------- -tShbError ShbInit (void) +tShbError ShbInit(void) { -tShbError ShbError; + tShbError ShbError; + ShbError = ShbIpcInit(); - ShbError = ShbIpcInit(); - - return (ShbError); + return (ShbError); } - - //--------------------------------------------------------------------------- // Deinitialize Shared Buffer Module //--------------------------------------------------------------------------- -tShbError ShbExit (void) +tShbError ShbExit(void) { -tShbError ShbError; - + tShbError ShbError; - ShbError = ShbIpcExit(); + ShbError = ShbIpcExit(); - return (ShbError); + return (ShbError); } - - - - //-------------------------------------------------------------------------// // // // C i r c u l a r S h a r e d B u f f e r // @@ -296,128 +261,109 @@ tShbError ShbError; // Allocate Circular Shared Buffer //--------------------------------------------------------------------------- -tShbError ShbCirAllocBuffer ( - unsigned long ulBufferSize_p, - const char* pszBufferID_p, - tShbInstance* ppShbInstance_p, - unsigned int* pfShbNewCreated_p) +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); - -} + 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 ShbCirReleaseBuffer(tShbInstance pShbInstance_p) { -tShbError ShbError; + tShbError ShbError; + // check arguments + if (pShbInstance_p == NULL) { + ShbError = kShbOk; + goto Exit; + } - // check arguments - if (pShbInstance_p == NULL) - { - ShbError = kShbOk; - goto Exit; - } + ShbError = ShbIpcReleaseBuffer(pShbInstance_p); + Exit: - ShbError = ShbIpcReleaseBuffer (pShbInstance_p); - - -Exit: - - return (ShbError); + return (ShbError); } - -#endif // !defined(INLINE_ENABLED) +#endif // !defined(INLINE_ENABLED) #if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED) @@ -425,895 +371,797 @@ Exit: // Reset Circular Shared Buffer //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbCirResetBuffer ( - tShbInstance pShbInstance_p, - unsigned long ulTimeOut_p, - tShbCirSigHndlrReset pfnSignalHandlerReset_p) +INLINE_FUNCTION 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); + 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 //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbCirWriteDataBlock ( - tShbInstance pShbInstance_p, - const void* pSrcDataBlock_p, - unsigned long ulDataBlockSize_p) +INLINE_FUNCTION 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); + 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 //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbCirAllocDataBlock ( - tShbInstance pShbInstance_p, - tShbCirChunk* pShbCirChunk_p, - unsigned long ulDataBufferSize_p) +INLINE_FUNCTION 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); + 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 //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbCirWriteDataChunk ( - tShbInstance pShbInstance_p, - tShbCirChunk* pShbCirChunk_p, - const void* pSrcDataChunk_p, - unsigned long ulDataChunkSize_p, - unsigned int* pfBufferCompleted_p) +INLINE_FUNCTION 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); + 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 //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbCirReadDataBlock ( - tShbInstance pShbInstance_p, - void* pDstDataBlock_p, - unsigned long ulRdBuffSize_p, - unsigned long* pulDataBlockSize_p) +INLINE_FUNCTION 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); - -} + 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 //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbCirGetReadDataSize ( - tShbInstance pShbInstance_p, - unsigned long* pulDataBlockSize_p) +INLINE_FUNCTION tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p, + unsigned long + *pulDataBlockSize_p) { -tShbCirBuff* pShbCirBuff; -unsigned long ulDataReadable; -unsigned char* pShbCirDataPtr; -tShbCirBlockSize ShbCirBlockSize; -unsigned long ulDataSize; -tShbError ShbError; - + 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); - } + // check arguments + if ((pShbInstance_p == NULL) || (pulDataBlockSize_p == NULL)) { + return (kShbInvalidArg); + } + pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); + ulDataSize = 0; + ShbError = kShbOk; - pShbCirBuff = ShbCirGetBuffer (pShbInstance_p); - ulDataSize = 0; - ShbError = kShbOk; + if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { + ShbError = kShbInvalidBufferType; + goto Exit; + } - 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 total number of readable bytes for the whole circular buffer - ShbIpcEnterAtomicSection (pShbInstance_p); - { - ulDataReadable = pShbCirBuff->m_ulDataReadable; - } - ShbIpcLeaveAtomicSection (pShbInstance_p); + // 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); + } - // 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; + Exit: - // get real size of current block (incl. alignment fill bytes) - ShbCirBlockSize = *(tShbCirBlockSize*)pShbCirDataPtr; + *pulDataBlockSize_p = ulDataSize; - // 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); + return (ShbError); } - - //--------------------------------------------------------------------------- // Get number of readable blocks from Circular Shared Buffer //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbCirGetReadBlockCount ( - tShbInstance pShbInstance_p, - unsigned long* pulDataBlockCount_p) +INLINE_FUNCTION tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p, + unsigned long + *pulDataBlockCount_p) { -tShbCirBuff* pShbCirBuff; -unsigned long ulBlockCount; -tShbError ShbError; - + tShbCirBuff *pShbCirBuff; + unsigned long ulBlockCount; + tShbError ShbError; - // check arguments - if ((pShbInstance_p == NULL) || (pulDataBlockCount_p == NULL)) - { - ShbError = kShbInvalidArg; - goto Exit; - } + // check arguments + if ((pShbInstance_p == NULL) || (pulDataBlockCount_p == NULL)) { + ShbError = kShbInvalidArg; + goto Exit; + } + pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); + ulBlockCount = 0; + ShbError = kShbOk; - pShbCirBuff = ShbCirGetBuffer (pShbInstance_p); - ulBlockCount = 0; - ShbError = kShbOk; + if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { + ShbError = kShbInvalidBufferType; + goto Exit; + } - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) - { - ShbError = kShbInvalidBufferType; - goto Exit; - } + ShbIpcEnterAtomicSection(pShbInstance_p); + { + ulBlockCount = pShbCirBuff->m_ulBlocksReadable; + } + ShbIpcLeaveAtomicSection(pShbInstance_p); + *pulDataBlockCount_p = ulBlockCount; - ShbIpcEnterAtomicSection (pShbInstance_p); - { - ulBlockCount = pShbCirBuff->m_ulBlocksReadable; - } - ShbIpcLeaveAtomicSection (pShbInstance_p); + Exit: - - *pulDataBlockCount_p = ulBlockCount; - - -Exit: - - return (ShbError); + return (ShbError); } - - //--------------------------------------------------------------------------- // Set application handler to signal new data for Circular Shared Buffer // d.k.: new parameter priority as enum //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbCirSetSignalHandlerNewData ( - tShbInstance pShbInstance_p, - tShbCirSigHndlrNewData pfnSignalHandlerNewData_p, - tShbPriority ShbPriority_p) +INLINE_FUNCTION tShbError ShbCirSetSignalHandlerNewData(tShbInstance + pShbInstance_p, + tShbCirSigHndlrNewData + pfnSignalHandlerNewData_p, + tShbPriority + ShbPriority_p) { -tShbCirBuff* pShbCirBuff; -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; - } - - - if (pfnSignalHandlerNewData_p != NULL) - { - // set a new signal handler - if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) - { - ShbError = kShbAlreadySignaling; - goto Exit; - } - - pShbCirBuff->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p; - ShbError = ShbIpcStartSignalingNewData (pShbInstance_p, ShbCirSignalHandlerNewData, ShbPriority_p); - } - else - { - // remove existing signal handler - ShbError = ShbIpcStopSignalingNewData (pShbInstance_p); - if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) - { - pShbCirBuff->m_pfnSigHndlrNewData (pShbInstance_p, 0); - } - pShbCirBuff->m_pfnSigHndlrNewData = NULL; - } - - -Exit: - - return (ShbError); + tShbCirBuff *pShbCirBuff; + 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; + } + + if (pfnSignalHandlerNewData_p != NULL) { + // set a new signal handler + if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) { + ShbError = kShbAlreadySignaling; + goto Exit; + } + + pShbCirBuff->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p; + ShbError = + ShbIpcStartSignalingNewData(pShbInstance_p, + ShbCirSignalHandlerNewData, + ShbPriority_p); + } else { + // remove existing signal handler + ShbError = ShbIpcStopSignalingNewData(pShbInstance_p); + if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) { + pShbCirBuff->m_pfnSigHndlrNewData(pShbInstance_p, 0); + } + pShbCirBuff->m_pfnSigHndlrNewData = NULL; + } + + Exit: + + return (ShbError); } @@ -1326,136 +1174,144 @@ Exit: //--------------------------------------------------------------------------- #ifndef NDEBUG -tShbError ShbCirTraceBuffer ( - tShbInstance pShbInstance_p) +tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p) { -tShbCirBuff* pShbCirBuff; -char szMagigID[sizeof(SBC_MAGIC_ID)+1]; -tShbCirBlockSize ShbCirBlockSize; -unsigned long ulDataReadable; -unsigned char* pShbCirDataPtr; -unsigned long ulBlockIndex; -unsigned int nBlockCount; -unsigned long ulDataSize; -unsigned long ulChunkSize; -unsigned long ulRdIndex; -tShbError ShbError; - - - TRACE0("\n\n##### Circular Shared Buffer #####\n"); - - // check arguments - if (pShbInstance_p == NULL) - { - TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", (unsigned long)pShbInstance_p); - ShbError = kShbInvalidArg; - goto Exit; - } - - - pShbCirBuff = ShbCirGetBuffer (pShbInstance_p); - ShbError = kShbOk; - - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) - { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - - *(unsigned long*) &szMagigID[0] = pShbCirBuff->m_ShbCirMagicID; - szMagigID[sizeof(SBC_MAGIC_ID)] = '\0'; - - - ShbIpcEnterAtomicSection (pShbInstance_p); - { - TRACE1("\nBuffer Address: 0x%08lX\n", (unsigned long)pShbCirBuff); - - TRACE0("\nHeader Info:"); - TRACE2("\nMagigID: '%s' (%08lX)", szMagigID, pShbCirBuff->m_ShbCirMagicID); - TRACE1("\nBufferTotalSize: %4lu [Bytes]", pShbCirBuff->m_ulBufferTotalSize); - TRACE1("\nBufferDataSize: %4lu [Bytes]", pShbCirBuff->m_ulBufferDataSize); - TRACE1("\nWrIndex: %4lu", pShbCirBuff->m_ulWrIndex); - TRACE1("\nRdIndex: %4lu", pShbCirBuff->m_ulRdIndex); - TRACE1("\nNumOfWriteJobs: %4lu", pShbCirBuff->m_ulNumOfWriteJobs); - TRACE1("\nDataInUse: %4lu [Bytes]", pShbCirBuff->m_ulDataInUse); - TRACE1("\nDataApended: %4lu [Bytes]", pShbCirBuff->m_ulDataApended); - TRACE1("\nBlocksApended: %4lu", pShbCirBuff->m_ulBlocksApended); - TRACE1("\nDataReadable: %4lu [Bytes]", pShbCirBuff->m_ulDataReadable); - TRACE1("\nBlocksReadable: %4lu", pShbCirBuff->m_ulBlocksReadable); - TRACE1("\nSigHndlrNewData: %08lX", (unsigned long)pShbCirBuff->m_pfnSigHndlrNewData); - TRACE1("\nBufferLocked: %d", pShbCirBuff->m_fBufferLocked); - TRACE1("\nSigHndlrReset: %08lX", (unsigned long)pShbCirBuff->m_pfnSigHndlrReset); - - ShbTraceDump (&pShbCirBuff->m_Data, pShbCirBuff->m_ulBufferDataSize, - 0x00000000L, "\nData Area:"); - - - ulDataReadable = pShbCirBuff->m_ulDataReadable; - nBlockCount = 1; - ulBlockIndex = pShbCirBuff->m_ulRdIndex; - - while (ulDataReadable > 0) - { - TRACE1("\n\n--- Block #%u ---", nBlockCount); - - // get pointer to start of data area and current read index - pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area - ulRdIndex = ulBlockIndex; - - // 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); - - TRACE1("\nFull Data Size: %4u [Bytes] (incl. header and alignment fill bytes)", ShbCirBlockSize.m_uiFullBlockSize); - TRACE1("\nUser Data Size: %4lu [Bytes]", ulDataSize); - TRACE1("\nAlignment Fill Bytes: %4u [Bytes]", ShbCirBlockSize.m_uiAlignFillBytes); - - - if (ulRdIndex + ulDataSize <= pShbCirBuff->m_ulBufferDataSize) - { - // linear data buffer - ShbTraceDump (pShbCirDataPtr + ulRdIndex, ulDataSize, 0x00000000L, NULL); - } - else - { - // wrap-around data buffer - ulChunkSize = pShbCirBuff->m_ulBufferDataSize - ulRdIndex; - ShbTraceDump (pShbCirDataPtr + ulRdIndex, ulChunkSize, 0x00000000L, NULL); - ShbTraceDump (pShbCirDataPtr, ulDataSize - ulChunkSize, ulChunkSize, NULL); - } - - nBlockCount++; - - ulBlockIndex += ShbCirBlockSize.m_uiFullBlockSize; - ulBlockIndex %= pShbCirBuff->m_ulBufferDataSize; - - ulDataReadable -= ShbCirBlockSize.m_uiFullBlockSize; - } - - ASSERT(pShbCirBuff->m_ulBlocksReadable == nBlockCount-1); - } - ShbIpcLeaveAtomicSection (pShbInstance_p); - - - -Exit: - - return (ShbError); + tShbCirBuff *pShbCirBuff; + char szMagigID[sizeof(SBC_MAGIC_ID) + 1]; + tShbCirBlockSize ShbCirBlockSize; + unsigned long ulDataReadable; + unsigned char *pShbCirDataPtr; + unsigned long ulBlockIndex; + unsigned int nBlockCount; + unsigned long ulDataSize; + unsigned long ulChunkSize; + unsigned long ulRdIndex; + tShbError ShbError; + + TRACE0("\n\n##### Circular Shared Buffer #####\n"); + + // check arguments + if (pShbInstance_p == NULL) { + TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", + (unsigned long)pShbInstance_p); + ShbError = kShbInvalidArg; + goto Exit; + } + + pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); + ShbError = kShbOk; + + if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { + ShbError = kShbInvalidBufferType; + goto Exit; + } + + *(unsigned long *)&szMagigID[0] = pShbCirBuff->m_ShbCirMagicID; + szMagigID[sizeof(SBC_MAGIC_ID)] = '\0'; + + ShbIpcEnterAtomicSection(pShbInstance_p); + { + TRACE1("\nBuffer Address: 0x%08lX\n", + (unsigned long)pShbCirBuff); + + TRACE0("\nHeader Info:"); + TRACE2("\nMagigID: '%s' (%08lX)", szMagigID, + pShbCirBuff->m_ShbCirMagicID); + TRACE1("\nBufferTotalSize: %4lu [Bytes]", + pShbCirBuff->m_ulBufferTotalSize); + TRACE1("\nBufferDataSize: %4lu [Bytes]", + pShbCirBuff->m_ulBufferDataSize); + TRACE1("\nWrIndex: %4lu", pShbCirBuff->m_ulWrIndex); + TRACE1("\nRdIndex: %4lu", pShbCirBuff->m_ulRdIndex); + TRACE1("\nNumOfWriteJobs: %4lu", + pShbCirBuff->m_ulNumOfWriteJobs); + TRACE1("\nDataInUse: %4lu [Bytes]", + pShbCirBuff->m_ulDataInUse); + TRACE1("\nDataApended: %4lu [Bytes]", + pShbCirBuff->m_ulDataApended); + TRACE1("\nBlocksApended: %4lu", + pShbCirBuff->m_ulBlocksApended); + TRACE1("\nDataReadable: %4lu [Bytes]", + pShbCirBuff->m_ulDataReadable); + TRACE1("\nBlocksReadable: %4lu", + pShbCirBuff->m_ulBlocksReadable); + TRACE1("\nSigHndlrNewData: %08lX", + (unsigned long)pShbCirBuff->m_pfnSigHndlrNewData); + TRACE1("\nBufferLocked: %d", pShbCirBuff->m_fBufferLocked); + TRACE1("\nSigHndlrReset: %08lX", + (unsigned long)pShbCirBuff->m_pfnSigHndlrReset); + + ShbTraceDump(&pShbCirBuff->m_Data, + pShbCirBuff->m_ulBufferDataSize, 0x00000000L, + "\nData Area:"); + + ulDataReadable = pShbCirBuff->m_ulDataReadable; + nBlockCount = 1; + ulBlockIndex = pShbCirBuff->m_ulRdIndex; + + while (ulDataReadable > 0) { + TRACE1("\n\n--- Block #%u ---", nBlockCount); + + // get pointer to start of data area and current read index + pShbCirDataPtr = &pShbCirBuff->m_Data; // ptr to start of data area + ulRdIndex = ulBlockIndex; + + // 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); + + TRACE1 + ("\nFull Data Size: %4u [Bytes] (incl. header and alignment fill bytes)", + ShbCirBlockSize.m_uiFullBlockSize); + TRACE1("\nUser Data Size: %4lu [Bytes]", + ulDataSize); + TRACE1("\nAlignment Fill Bytes: %4u [Bytes]", + ShbCirBlockSize.m_uiAlignFillBytes); + + if (ulRdIndex + ulDataSize <= + pShbCirBuff->m_ulBufferDataSize) { + // linear data buffer + ShbTraceDump(pShbCirDataPtr + ulRdIndex, + ulDataSize, 0x00000000L, NULL); + } else { + // wrap-around data buffer + ulChunkSize = + pShbCirBuff->m_ulBufferDataSize - ulRdIndex; + ShbTraceDump(pShbCirDataPtr + ulRdIndex, + ulChunkSize, 0x00000000L, NULL); + ShbTraceDump(pShbCirDataPtr, + ulDataSize - ulChunkSize, + ulChunkSize, NULL); + } + + nBlockCount++; + + ulBlockIndex += ShbCirBlockSize.m_uiFullBlockSize; + ulBlockIndex %= pShbCirBuff->m_ulBufferDataSize; + + ulDataReadable -= ShbCirBlockSize.m_uiFullBlockSize; + } + + ASSERT(pShbCirBuff->m_ulBlocksReadable == nBlockCount - 1); + } + ShbIpcLeaveAtomicSection(pShbInstance_p); + + Exit: + + return (ShbError); } #endif - - - - //-------------------------------------------------------------------------// // // // L i n e a r S h a r e d B u f f e r // @@ -1466,117 +1322,98 @@ Exit: // Allocate Linear Shared Buffer //--------------------------------------------------------------------------- -tShbError ShbLinAllocBuffer ( - unsigned long ulBufferSize_p, - const char* pszBufferID_p, - tShbInstance* ppShbInstance_p, - unsigned int* pfShbNewCreated_p) +tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p, + const char *pszBufferID_p, + tShbInstance * ppShbInstance_p, + unsigned int *pfShbNewCreated_p) { -tShbInstance pShbInstance; -tShbLinBuff* pShbLinBuff; -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 + (SBL_BLOCK_ALIGNMENT-1)) & ~(SBL_BLOCK_ALIGNMENT-1); - ulBufferTotalSize = ulBufferDataSize + sizeof(tShbLinBuff); - - // 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 - pShbLinBuff = (tShbLinBuff*) 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 (pShbLinBuff, 0xCC, ulBufferTotalSize); - } - #endif - - - pShbLinBuff->m_ShbLinMagicID = SBL_MAGIC_ID; - pShbLinBuff->m_ulBufferTotalSize = ulBufferTotalSize; - pShbLinBuff->m_ulBufferDataSize = ulBufferDataSize; - } - else - { - if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) - { - ShbError = kShbInvalidBufferType; - goto Exit; - } - } + tShbInstance pShbInstance; + tShbLinBuff *pShbLinBuff; + 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 + + (SBL_BLOCK_ALIGNMENT - 1)) & ~(SBL_BLOCK_ALIGNMENT - 1); + ulBufferTotalSize = ulBufferDataSize + sizeof(tShbLinBuff); + + // 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 + pShbLinBuff = (tShbLinBuff *) 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(pShbLinBuff, 0xCC, ulBufferTotalSize); + } +#endif + pShbLinBuff->m_ShbLinMagicID = SBL_MAGIC_ID; + pShbLinBuff->m_ulBufferTotalSize = ulBufferTotalSize; + pShbLinBuff->m_ulBufferDataSize = ulBufferDataSize; + } else { + if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) { + ShbError = kShbInvalidBufferType; + goto Exit; + } + } -Exit: + Exit: - *ppShbInstance_p = pShbInstance; - *pfShbNewCreated_p = fShbNewCreated; + *ppShbInstance_p = pShbInstance; + *pfShbNewCreated_p = fShbNewCreated; - return (ShbError); + return (ShbError); } - - //--------------------------------------------------------------------------- // Release Linear Shared Buffer //--------------------------------------------------------------------------- -tShbError ShbLinReleaseBuffer ( - tShbInstance pShbInstance_p) +tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p) { -tShbError ShbError; - - - // check arguments - if (pShbInstance_p == NULL) - { - ShbError = kShbOk; - goto Exit; - } + tShbError ShbError; + // check arguments + if (pShbInstance_p == NULL) { + ShbError = kShbOk; + goto Exit; + } - ShbError = ShbIpcReleaseBuffer (pShbInstance_p); + ShbError = ShbIpcReleaseBuffer(pShbInstance_p); + Exit: -Exit: - - return (ShbError); + return (ShbError); } - -#endif // !defined(INLINE_ENABLED) +#endif // !defined(INLINE_ENABLED) #if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED) @@ -1584,325 +1421,266 @@ Exit: // Write data block to Linear Shared Buffer //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbLinWriteDataBlock ( - tShbInstance pShbInstance_p, - unsigned long ulDstBufferOffs_p, - const void* pSrcDataBlock_p, - unsigned long ulDataBlockSize_p) +INLINE_FUNCTION tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p, + unsigned long ulDstBufferOffs_p, + const void *pSrcDataBlock_p, + unsigned long ulDataBlockSize_p) { -tShbLinBuff* pShbLinBuff; -unsigned char* pShbLinDataPtr; -unsigned char* pScrDataPtr; -unsigned long ulBufferDataSize; -tShbError ShbError; - - - // 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 > SBL_MAX_BLOCK_SIZE) - { - ShbError = kShbExceedDataSizeLimit; - goto Exit; - } - - - pShbLinBuff = ShbLinGetBuffer (pShbInstance_p); - pScrDataPtr = (unsigned char*)pSrcDataBlock_p; - ShbError = kShbOk; - - if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) - { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - - // check if offeset and size for the write operation matches with - // the size of the shared buffer - ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize; - if ( (ulDstBufferOffs_p > ulBufferDataSize) || - (ulDataBlockSize_p > ulBufferDataSize) || - ((ulDstBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize) ) - { - ShbError = kShbDataOutsideBufferArea; - goto Exit; - } - - - // copy the data to the linear buffer - // (the copy process will be done inside of any critical/locked section) - pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area - pShbLinDataPtr += ulDstBufferOffs_p; - - ShbIpcEnterAtomicSection (pShbInstance_p); - { - memcpy (pShbLinDataPtr, pScrDataPtr, ulDataBlockSize_p); - } - ShbIpcLeaveAtomicSection (pShbInstance_p); - - -Exit: - - return (ShbError); + tShbLinBuff *pShbLinBuff; + unsigned char *pShbLinDataPtr; + unsigned char *pScrDataPtr; + unsigned long ulBufferDataSize; + tShbError ShbError; + + // 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 > SBL_MAX_BLOCK_SIZE) { + ShbError = kShbExceedDataSizeLimit; + goto Exit; + } + + pShbLinBuff = ShbLinGetBuffer(pShbInstance_p); + pScrDataPtr = (unsigned char *)pSrcDataBlock_p; + ShbError = kShbOk; + + if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) { + ShbError = kShbInvalidBufferType; + goto Exit; + } + + // check if offeset and size for the write operation matches with + // the size of the shared buffer + ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize; + if ((ulDstBufferOffs_p > ulBufferDataSize) || + (ulDataBlockSize_p > ulBufferDataSize) || + ((ulDstBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize)) { + ShbError = kShbDataOutsideBufferArea; + goto Exit; + } + + // copy the data to the linear buffer + // (the copy process will be done inside of any critical/locked section) + pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area + pShbLinDataPtr += ulDstBufferOffs_p; + + ShbIpcEnterAtomicSection(pShbInstance_p); + { + memcpy(pShbLinDataPtr, pScrDataPtr, ulDataBlockSize_p); + } + ShbIpcLeaveAtomicSection(pShbInstance_p); + + Exit: + + return (ShbError); } - - //--------------------------------------------------------------------------- // Read data block from Linear Shared Buffer //--------------------------------------------------------------------------- -INLINE_FUNCTION tShbError ShbLinReadDataBlock ( - tShbInstance pShbInstance_p, - void* pDstDataBlock_p, - unsigned long ulSrcBufferOffs_p, - unsigned long ulDataBlockSize_p) +INLINE_FUNCTION tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p, + void *pDstDataBlock_p, + unsigned long ulSrcBufferOffs_p, + unsigned long ulDataBlockSize_p) { -tShbLinBuff* pShbLinBuff; -unsigned char* pShbLinDataPtr; -unsigned char* pDstDataPtr; -unsigned long ulBufferDataSize; -tShbError ShbError; - - - // check arguments - if (pShbInstance_p == NULL) - { - ShbError = kShbInvalidArg; - goto Exit; - } - - if ((pDstDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) - { - // nothing to do here - ShbError = kShbOk; - goto Exit; - } - - if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) - { - ShbError = kShbExceedDataSizeLimit; - goto Exit; - } - - - pShbLinBuff = ShbLinGetBuffer (pShbInstance_p); - pDstDataPtr = (unsigned char*)pDstDataBlock_p; - ShbError = kShbOk; - - if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) - { - ShbError = kShbInvalidBufferType; - goto Exit; - } - - - // check if offeset and size for the read operation matches with - // the size of the shared buffer - ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize; - if ( (ulSrcBufferOffs_p > ulBufferDataSize) || - (ulDataBlockSize_p > ulBufferDataSize) || - ((ulSrcBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize) ) - { - ShbError = kShbDataOutsideBufferArea; - goto Exit; - } - - - // copy the data to the linear buffer - // (the copy process will be done inside of any critical/locked section) - pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area - pShbLinDataPtr += ulSrcBufferOffs_p; - - ShbIpcEnterAtomicSection (pShbInstance_p); - { - memcpy (pDstDataPtr, pShbLinDataPtr, ulDataBlockSize_p); - } - ShbIpcLeaveAtomicSection (pShbInstance_p); - - -Exit: - - return (ShbError); + tShbLinBuff *pShbLinBuff; + unsigned char *pShbLinDataPtr; + unsigned char *pDstDataPtr; + unsigned long ulBufferDataSize; + tShbError ShbError; + + // check arguments + if (pShbInstance_p == NULL) { + ShbError = kShbInvalidArg; + goto Exit; + } + + if ((pDstDataBlock_p == NULL) || (ulDataBlockSize_p == 0)) { + // nothing to do here + ShbError = kShbOk; + goto Exit; + } + + if (ulDataBlockSize_p > SBL_MAX_BLOCK_SIZE) { + ShbError = kShbExceedDataSizeLimit; + goto Exit; + } + + pShbLinBuff = ShbLinGetBuffer(pShbInstance_p); + pDstDataPtr = (unsigned char *)pDstDataBlock_p; + ShbError = kShbOk; + + if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) { + ShbError = kShbInvalidBufferType; + goto Exit; + } + + // check if offeset and size for the read operation matches with + // the size of the shared buffer + ulBufferDataSize = pShbLinBuff->m_ulBufferDataSize; + if ((ulSrcBufferOffs_p > ulBufferDataSize) || + (ulDataBlockSize_p > ulBufferDataSize) || + ((ulSrcBufferOffs_p + ulDataBlockSize_p) > ulBufferDataSize)) { + ShbError = kShbDataOutsideBufferArea; + goto Exit; + } + + // copy the data to the linear buffer + // (the copy process will be done inside of any critical/locked section) + pShbLinDataPtr = &pShbLinBuff->m_Data; // ptr to start of data area + pShbLinDataPtr += ulSrcBufferOffs_p; + + ShbIpcEnterAtomicSection(pShbInstance_p); + { + memcpy(pDstDataPtr, pShbLinDataPtr, ulDataBlockSize_p); + } + ShbIpcLeaveAtomicSection(pShbInstance_p); + + Exit: + + return (ShbError); } #endif - #if !defined(INLINE_ENABLED) - //--------------------------------------------------------------------------- // DEBUG: Trace Linear Shared Buffer //--------------------------------------------------------------------------- #ifndef NDEBUG -tShbError ShbLinTraceBuffer ( - tShbInstance pShbInstance_p) +tShbError ShbLinTraceBuffer(tShbInstance pShbInstance_p) { -tShbLinBuff* pShbLinBuff; -char szMagigID[sizeof(SBL_MAGIC_ID)+1]; -tShbError ShbError; + tShbLinBuff *pShbLinBuff; + char szMagigID[sizeof(SBL_MAGIC_ID) + 1]; + tShbError ShbError; + TRACE0("\n\n##### Linear Shared Buffer #####\n"); - TRACE0("\n\n##### Linear Shared Buffer #####\n"); + // check arguments + if (pShbInstance_p == NULL) { + TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", + (unsigned long)pShbInstance_p); + ShbError = kShbInvalidArg; + goto Exit; + } - // check arguments - if (pShbInstance_p == NULL) - { - TRACE1("\nERROR: invalid buffer address (0x%08lX)\n", (unsigned long)pShbInstance_p); - ShbError = kShbInvalidArg; - goto Exit; - } + pShbLinBuff = ShbLinGetBuffer(pShbInstance_p); + ShbError = kShbOk; + if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) { + ShbError = kShbInvalidBufferType; + goto Exit; + } - pShbLinBuff = ShbLinGetBuffer (pShbInstance_p); - ShbError = kShbOk; + *(unsigned int *)&szMagigID[0] = pShbLinBuff->m_ShbLinMagicID; + szMagigID[sizeof(SBL_MAGIC_ID)] = '\0'; - if (pShbLinBuff->m_ShbLinMagicID != SBL_MAGIC_ID) - { - ShbError = kShbInvalidBufferType; - goto Exit; - } + ShbIpcEnterAtomicSection(pShbInstance_p); + { + TRACE1("\nBuffer Address: 0x%08lX\n", + (unsigned long)pShbLinBuff); + TRACE0("\nHeader Info:"); + TRACE2("\nMagigID: '%s' (%08X)", szMagigID, + pShbLinBuff->m_ShbLinMagicID); + TRACE1("\nBufferTotalSize: %4lu [Bytes]", + pShbLinBuff->m_ulBufferTotalSize); + TRACE1("\nBufferDataSize: %4lu [Bytes]", + pShbLinBuff->m_ulBufferDataSize); - *(unsigned int*) &szMagigID[0] = pShbLinBuff->m_ShbLinMagicID; - szMagigID[sizeof(SBL_MAGIC_ID)] = '\0'; + ShbTraceDump(&pShbLinBuff->m_Data, + pShbLinBuff->m_ulBufferDataSize, 0x00000000L, + "\nData Area:"); + } + ShbIpcLeaveAtomicSection(pShbInstance_p); + Exit: - ShbIpcEnterAtomicSection (pShbInstance_p); - { - TRACE1("\nBuffer Address: 0x%08lX\n", (unsigned long)pShbLinBuff); - - TRACE0("\nHeader Info:"); - TRACE2("\nMagigID: '%s' (%08X)", szMagigID, pShbLinBuff->m_ShbLinMagicID); - TRACE1("\nBufferTotalSize: %4lu [Bytes]", pShbLinBuff->m_ulBufferTotalSize); - TRACE1("\nBufferDataSize: %4lu [Bytes]", pShbLinBuff->m_ulBufferDataSize); - - ShbTraceDump (&pShbLinBuff->m_Data, pShbLinBuff->m_ulBufferDataSize, - 0x00000000L, "\nData Area:"); - } - ShbIpcLeaveAtomicSection (pShbInstance_p); - - - -Exit: - - return (ShbError); + return (ShbError); } #endif - - - - //--------------------------------------------------------------------------- // Dump buffer contents //--------------------------------------------------------------------------- #ifndef NDEBUG -tShbError ShbTraceDump ( - const unsigned char* pabStartAddr_p, - unsigned long ulDataSize_p, - unsigned long ulAddrOffset_p, - const char* pszInfoText_p) +tShbError ShbTraceDump(const unsigned char *pabStartAddr_p, + unsigned long ulDataSize_p, + unsigned long ulAddrOffset_p, const char *pszInfoText_p) { -const unsigned char* pabBuffData; -unsigned long ulBuffSize; -unsigned char bData; -int nRow; -int nCol; - - - // get pointer to buffer and length of buffer - pabBuffData = pabStartAddr_p; - ulBuffSize = ulDataSize_p; - - - if (pszInfoText_p != NULL) - { - TRACE0(pszInfoText_p); - } - - // dump buffer contents - for (nRow=0; ; nRow++) - { - TRACE1("\n%08lX: ", (unsigned long)(nRow*0x10) + ulAddrOffset_p); - - for (nCol=0; nCol<16; nCol++) - { - if ((unsigned long)nCol < ulBuffSize) - { - TRACE1("%02X ", (unsigned int)*(pabBuffData+nCol)); - } - else - { - TRACE0(" "); - } - } - - TRACE0(" "); - - for (nCol=0; nCol<16; nCol++) - { - bData = *pabBuffData++; - if ((unsigned long)nCol < ulBuffSize) - { - if ((bData >= 0x20) && (bData < 0x7F)) - { - TRACE1("%c", bData); - } - else - { - TRACE0("."); - } - } - else - { - TRACE0(" "); - } - } - - if (ulBuffSize > 16) - { - ulBuffSize -= 16; - } - else - { - break; - } - } - - - return (kShbOk); + const unsigned char *pabBuffData; + unsigned long ulBuffSize; + unsigned char bData; + int nRow; + int nCol; + + // get pointer to buffer and length of buffer + pabBuffData = pabStartAddr_p; + ulBuffSize = ulDataSize_p; + + if (pszInfoText_p != NULL) { + TRACE0(pszInfoText_p); + } + // dump buffer contents + for (nRow = 0;; nRow++) { + TRACE1("\n%08lX: ", + (unsigned long)(nRow * 0x10) + ulAddrOffset_p); + + for (nCol = 0; nCol < 16; nCol++) { + if ((unsigned long)nCol < ulBuffSize) { + TRACE1("%02X ", + (unsigned int)*(pabBuffData + nCol)); + } else { + TRACE0(" "); + } + } + + TRACE0(" "); + + for (nCol = 0; nCol < 16; nCol++) { + bData = *pabBuffData++; + if ((unsigned long)nCol < ulBuffSize) { + if ((bData >= 0x20) && (bData < 0x7F)) { + TRACE1("%c", bData); + } else { + TRACE0("."); + } + } else { + TRACE0(" "); + } + } + + if (ulBuffSize > 16) { + ulBuffSize -= 16; + } else { + break; + } + } + + return (kShbOk); } -#endif // #ifndef NDEBUG - - - - - - +#endif // #ifndef NDEBUG //=========================================================================// // // @@ -1914,128 +1692,108 @@ int nCol; // Handler to signal new data event for Circular Shared Buffer //--------------------------------------------------------------------------- -int ShbCirSignalHandlerNewData ( - tShbInstance pShbInstance_p) +int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p) { -tShbCirBuff* pShbCirBuff; -unsigned long ulDataSize; -unsigned long ulBlockCount; -tShbError ShbError; - - - // check arguments - if (pShbInstance_p == NULL) - { - return FALSE; - } + tShbCirBuff *pShbCirBuff; + unsigned long ulDataSize; + unsigned long ulBlockCount; + tShbError ShbError; - pShbCirBuff = ShbCirGetBuffer (pShbInstance_p); - ShbError = kShbOk; + // check arguments + if (pShbInstance_p == NULL) { + return FALSE; + } - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) - { - return FALSE; - } + pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); + ShbError = kShbOk; + if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { + return FALSE; + } - // call application handler - if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) - { + // call application handler + if (pShbCirBuff->m_pfnSigHndlrNewData != NULL) { /* do {*/ - ShbError = ShbCirGetReadDataSize (pShbInstance_p, &ulDataSize); - if ((ulDataSize > 0) && (ShbError == kShbOk)) - { - pShbCirBuff->m_pfnSigHndlrNewData (pShbInstance_p, ulDataSize); - } - - ShbError = ShbCirGetReadBlockCount (pShbInstance_p, &ulBlockCount); + ShbError = ShbCirGetReadDataSize(pShbInstance_p, &ulDataSize); + if ((ulDataSize > 0) && (ShbError == kShbOk)) { + pShbCirBuff->m_pfnSigHndlrNewData(pShbInstance_p, + ulDataSize); + } + + ShbError = + ShbCirGetReadBlockCount(pShbInstance_p, &ulBlockCount); /* } while ((ulBlockCount > 0) && (ShbError == kShbOk));*/ - } - - // Return TRUE if there are pending blocks. - // In that case ShbIpc tries to call this function again immediately if there - // is no other filled shared buffer with higher priority. - return ((ulBlockCount > 0) && (ShbError == kShbOk)); + } + // Return TRUE if there are pending blocks. + // In that case ShbIpc tries to call this function again immediately if there + // is no other filled shared buffer with higher priority. + return ((ulBlockCount > 0) && (ShbError == kShbOk)); } - - //--------------------------------------------------------------------------- // Handler to reset Circular Shared Buffer //--------------------------------------------------------------------------- -void ShbCirSignalHandlerReset ( - tShbInstance pShbInstance_p, - unsigned int fTimeOut_p) +void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p, + unsigned int fTimeOut_p) { -tShbCirBuff* pShbCirBuff; - - - // check arguments - if (pShbInstance_p == NULL) - { - return; - } - - pShbCirBuff = ShbCirGetBuffer (pShbInstance_p); - if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) - { - return; - } - - - // reset buffer header - if ( !fTimeOut_p ) - { - ShbIpcEnterAtomicSection (pShbInstance_p); - { - 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; - } - ShbIpcLeaveAtomicSection (pShbInstance_p); - - - #ifndef NDEBUG - { - memset (&pShbCirBuff->m_Data, 0xCC, pShbCirBuff->m_ulBufferDataSize); - } - #endif - } - - - // call application handler - if (pShbCirBuff->m_pfnSigHndlrReset != NULL) - { - pShbCirBuff->m_pfnSigHndlrReset (pShbInstance_p, fTimeOut_p); - } + tShbCirBuff *pShbCirBuff; + + // check arguments + if (pShbInstance_p == NULL) { + return; + } + + pShbCirBuff = ShbCirGetBuffer(pShbInstance_p); + if (pShbCirBuff->m_ShbCirMagicID != SBC_MAGIC_ID) { + return; + } + + // reset buffer header + if (!fTimeOut_p) { + ShbIpcEnterAtomicSection(pShbInstance_p); + { + 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; + } + ShbIpcLeaveAtomicSection(pShbInstance_p); +#ifndef NDEBUG + { + memset(&pShbCirBuff->m_Data, 0xCC, + pShbCirBuff->m_ulBufferDataSize); + } +#endif + } - // unlock buffer - ShbIpcEnterAtomicSection (pShbInstance_p); - { - pShbCirBuff->m_fBufferLocked = FALSE; - pShbCirBuff->m_pfnSigHndlrReset = NULL; - } - ShbIpcLeaveAtomicSection (pShbInstance_p); + // call application handler + if (pShbCirBuff->m_pfnSigHndlrReset != NULL) { + pShbCirBuff->m_pfnSigHndlrReset(pShbInstance_p, fTimeOut_p); + } + // unlock buffer + ShbIpcEnterAtomicSection(pShbInstance_p); + { + pShbCirBuff->m_fBufferLocked = FALSE; + pShbCirBuff->m_pfnSigHndlrReset = NULL; + } + ShbIpcLeaveAtomicSection(pShbInstance_p); - return; + return; } #endif - // EOF - -- cgit v1.1