diff options
author | Felix Geyer <debfx-pkg@fobos.de> | 2011-07-29 17:55:18 +0200 |
---|---|---|
committer | Felix Geyer <debfx-pkg@fobos.de> | 2011-07-29 17:55:18 +0200 |
commit | cba113ca2826bc4814be2f69a7704c865a37d4ea (patch) | |
tree | 511123b10dd1e58e56958520534f5c50e6f570fc /src/VBox/Runtime/common/misc/circbuf.cpp | |
parent | 6a16f6900dd884e07125b51c9625f6be0a1f9b70 (diff) | |
download | virtualbox-cba113ca2826bc4814be2f69a7704c865a37d4ea.tar.gz |
Imported Upstream version 4.1.0-dfsgupstream/4.1.0-dfsg
Diffstat (limited to 'src/VBox/Runtime/common/misc/circbuf.cpp')
-rw-r--r-- | src/VBox/Runtime/common/misc/circbuf.cpp | 121 |
1 files changed, 62 insertions, 59 deletions
diff --git a/src/VBox/Runtime/common/misc/circbuf.cpp b/src/VBox/Runtime/common/misc/circbuf.cpp index da6c51f93..0a6f78b07 100644 --- a/src/VBox/Runtime/common/misc/circbuf.cpp +++ b/src/VBox/Runtime/common/misc/circbuf.cpp @@ -1,4 +1,4 @@ -/* $Id: circbuf.cpp $ */ +/* $Id: circbuf.cpp 37210 2011-05-25 09:55:16Z vboxsync $ */ /** @file * IPRT - Lock Free Circular Buffer */ @@ -25,18 +25,36 @@ */ -/****************************************************************************** - * Header Files * - ******************************************************************************/ +/******************************************************************************* +* Header Files * +*******************************************************************************/ #include <iprt/circbuf.h> #include <iprt/mem.h> #include <iprt/assert.h> #include <iprt/asm.h> #include <iprt/err.h> -/****************************************************************************** - * Public Functions * - ******************************************************************************/ + +/******************************************************************************* +* Structures and Typedefs * +*******************************************************************************/ +/** @todo r=bird: this is missing docs and magic. uXPos should be offX. + * cbBufSize should be cbBuf. */ +typedef struct RTCIRCBUF +{ + /** The current read position in the buffer. */ + size_t uReadPos; + /** The current write position in the buffer. */ + size_t uWritePos; + /** How much space of the buffer is currently in use. */ + volatile size_t cbBufUsed; + /** How big is the buffer. */ + size_t cbBufSize; + /** The buffer itself. */ + void *pvBuf; +} RTCIRCBUF; + + RTDECL(int) RTCircBufCreate(PRTCIRCBUF *ppBuf, size_t cbSize) { @@ -49,69 +67,59 @@ RTDECL(int) RTCircBufCreate(PRTCIRCBUF *ppBuf, size_t cbSize) if (!pTmpBuf) return VERR_NO_MEMORY; - int rc = VINF_SUCCESS; - do + pTmpBuf->pvBuf = RTMemAlloc(cbSize); + if (pTmpBuf->pvBuf) { - pTmpBuf->pvBuf = RTMemAlloc(cbSize); - if (!pTmpBuf) - { - rc = VERR_NO_MEMORY; - break; - } - pTmpBuf->cbBufSize = cbSize; *ppBuf = pTmpBuf; - }while (0); - - if (RT_FAILURE(rc)) - RTMemFree(pTmpBuf); + return VINF_SUCCESS; + } - return rc; + RTMemFree(pTmpBuf); + return VERR_NO_MEMORY; } + RTDECL(void) RTCircBufDestroy(PRTCIRCBUF pBuf) { /* Validate input. */ - AssertPtrNull(pBuf); - - if (pBuf) - { - if (pBuf->pvBuf) - RTMemFree(pBuf->pvBuf); - RTMemFree(pBuf); - } + if (!pBuf) + return; + AssertPtr(pBuf); + RTMemFree(pBuf->pvBuf); + RTMemFree(pBuf); } + RTDECL(void) RTCircBufReset(PRTCIRCBUF pBuf) { /* Validate input. */ AssertPtr(pBuf); - pBuf->uReadPos = 0; + pBuf->uReadPos = 0; pBuf->uWritePos = 0; pBuf->cbBufUsed = 0; } + RTDECL(size_t) RTCircBufFree(PRTCIRCBUF pBuf) { /* Validate input. */ AssertPtrReturn(pBuf, 0); - size_t cbSize = 0; - ASMAtomicReadSize(&pBuf->cbBufUsed, &cbSize); - return pBuf->cbBufSize - cbSize; + return pBuf->cbBufSize - ASMAtomicReadZ(&pBuf->cbBufUsed); } + RTDECL(size_t) RTCircBufUsed(PRTCIRCBUF pBuf) { /* Validate input. */ AssertPtrReturn(pBuf, 0); - size_t cbSize = 0; - ASMAtomicReadSize(&pBuf->cbBufUsed, &cbSize); - return cbSize; + return ASMAtomicReadZ(&pBuf->cbBufUsed); } + RTDECL(size_t) RTCircBufSize(PRTCIRCBUF pBuf) { /* Validate input. */ @@ -120,6 +128,7 @@ RTDECL(size_t) RTCircBufSize(PRTCIRCBUF pBuf) return pBuf->cbBufSize; } + RTDECL(void) RTCircBufAcquireReadBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void **ppvStart, size_t *pcbSize) { /* Validate input. */ @@ -128,29 +137,27 @@ RTDECL(void) RTCircBufAcquireReadBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void * AssertPtr(ppvStart); AssertPtr(pcbSize); - size_t uUsed = 0; - size_t uSize = 0; - *ppvStart = 0; *pcbSize = 0; /* How much is in use? */ - ASMAtomicReadSize(&pBuf->cbBufUsed, &uUsed); - if (uUsed > 0) + size_t cbUsed = ASMAtomicReadZ(&pBuf->cbBufUsed); + if (cbUsed > 0) { /* Get the size out of the requested size, the read block till the end * of the buffer & the currently used size. */ - uSize = RT_MIN(cbReqSize, RT_MIN(pBuf->cbBufSize - pBuf->uReadPos, uUsed)); - if (uSize > 0) + size_t cbSize = RT_MIN(cbReqSize, RT_MIN(pBuf->cbBufSize - pBuf->uReadPos, cbUsed)); + if (cbSize > 0) { /* Return the pointer address which point to the current read * position. */ - *ppvStart = (char*)pBuf->pvBuf + pBuf->uReadPos; - *pcbSize = uSize; + *ppvStart = (char *)pBuf->pvBuf + pBuf->uReadPos; + *pcbSize = cbSize; } } } + RTDECL(void) RTCircBufReleaseReadBlock(PRTCIRCBUF pBuf, size_t cbSize) { /* Validate input. */ @@ -159,10 +166,10 @@ RTDECL(void) RTCircBufReleaseReadBlock(PRTCIRCBUF pBuf, size_t cbSize) /* Split at the end of the buffer. */ pBuf->uReadPos = (pBuf->uReadPos + cbSize) % pBuf->cbBufSize; - size_t cbOld = 0; - ASMAtomicSubSize(&pBuf->cbBufUsed, cbSize, &cbOld); + ASMAtomicSubZ(&pBuf->cbBufUsed, cbSize); } + RTDECL(void) RTCircBufAcquireWriteBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void **ppvStart, size_t *pcbSize) { /* Validate input. */ @@ -171,31 +178,27 @@ RTDECL(void) RTCircBufAcquireWriteBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void AssertPtr(ppvStart); AssertPtr(pcbSize); - size_t uFree; - size_t uSize; - *ppvStart = 0; *pcbSize = 0; /* How much is free? */ - size_t cbSize = 0; - ASMAtomicReadSize(&pBuf->cbBufUsed, &cbSize); - uFree = pBuf->cbBufSize - cbSize; - if (uFree > 0) + size_t cbFree = pBuf->cbBufSize - ASMAtomicReadZ(&pBuf->cbBufUsed); + if (cbFree > 0) { /* Get the size out of the requested size, the write block till the end * of the buffer & the currently free size. */ - uSize = RT_MIN(cbReqSize, RT_MIN(pBuf->cbBufSize - pBuf->uWritePos, uFree)); - if (uSize > 0) + size_t cbSize = RT_MIN(cbReqSize, RT_MIN(pBuf->cbBufSize - pBuf->uWritePos, cbFree)); + if (cbSize > 0) { /* Return the pointer address which point to the current write * position. */ *ppvStart = (char*)pBuf->pvBuf + pBuf->uWritePos; - *pcbSize = uSize; + *pcbSize = cbSize; } } } + RTDECL(void) RTCircBufReleaseWriteBlock(PRTCIRCBUF pBuf, size_t cbSize) { /* Validate input. */ @@ -204,7 +207,7 @@ RTDECL(void) RTCircBufReleaseWriteBlock(PRTCIRCBUF pBuf, size_t cbSize) /* Split at the end of the buffer. */ pBuf->uWritePos = (pBuf->uWritePos + cbSize) % pBuf->cbBufSize; - size_t cbOld = 0; - ASMAtomicAddSize(&pBuf->cbBufUsed, cbSize, &cbOld); + size_t cbOldIgnored = 0; + ASMAtomicAddZ(&pBuf->cbBufUsed, cbSize); } |