OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / system / wlan / ti / sta_dk_4_0_4_32 / common / src / utils / bufferPool.c
diff --git a/system/wlan/ti/sta_dk_4_0_4_32/common/src/utils/bufferPool.c b/system/wlan/ti/sta_dk_4_0_4_32/common/src/utils/bufferPool.c
new file mode 100644 (file)
index 0000000..7de8ca5
--- /dev/null
@@ -0,0 +1,295 @@
+/** \file bufferPool.c
+ *  \brief This file include buffer pool module implementation
+ *  \author Ronen Kalish
+ *  \date 05-December-2005
+ */
+
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**|                                                                       |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
+**| All rights reserved.                                                  |**
+**|                                                                       |**
+**| Redistribution and use in source and binary forms, with or without    |**
+**| modification, are permitted provided that the following conditions    |**
+**| are met:                                                              |**
+**|                                                                       |**
+**|  * Redistributions of source code must retain the above copyright     |**
+**|    notice, this list of conditions and the following disclaimer.      |**
+**|  * 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.                                                      |**
+**|  * Neither the name Texas Instruments nor the names of its            |**
+**|    contributors may be used to endorse or promote products derived    |**
+**|    from this software without specific prior written permission.      |**
+**|                                                                       |**
+**| 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  |**
+**| OWNER 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.  |**
+**|                                                                       |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+#include "bufferPool.h"
+#include "osApi.h"
+#include "report.h"
+
+/**
+ * \author Ronen Kalish\n
+ * \date 05-December-2005\n
+ * \brief Creates a buffer pool object
+ *
+ * Function Scope \e Public.\n
+ * \param hOS - handle to the OS object.\n
+ * \param numOfBuffers - the number of buffers to allocate for this pool.\n
+ * \param bufferSize - the size of each buffer in this pool.\n
+ * \return a handle to a buffer pool object, NULL if an error occurred.\n
+ */
+TI_HANDLE bufferPool_create( TI_HANDLE hOS, UINT32 numOfBuffers, UINT32 bufferSize )
+{
+    /* allocate the buffer pool object */
+    bufferPool_t *pBufferPool = os_memoryAlloc( hOS, sizeof(bufferPool_t) );
+    if ( NULL == pBufferPool )
+    {
+        WLAN_OS_REPORT( ("ERROR: Failed to create buffer pool object") );
+        return NULL;
+    }
+
+    /* 
+     * adjust buffer size if necessary - the buffer must at least store the pointer to the
+     * next free buffer when it is free.
+     */
+    if ( sizeof( bufferPool_buffer_t ) > bufferSize )
+    {
+        bufferSize = sizeof( bufferPool_buffer_t );
+    }
+
+    /* nullify the buffer pool object */
+    os_memoryZero( hOS, pBufferPool, sizeof( bufferPool_t ) );
+
+    /* allocate the buffers */
+    pBufferPool->firstBuffer = pBufferPool->firstFreeBuffer = os_memoryAlloc( hOS, numOfBuffers * bufferSize );
+    if ( NULL == pBufferPool->firstBuffer )
+    {
+        WLAN_OS_REPORT( ("ERROR: Failed to allocate buffer storage space") );
+        bufferPool_destroy( (TI_HANDLE)pBufferPool );
+        return NULL;
+    }
+
+    /* store the OS handle */
+    pBufferPool->hOS = hOS;
+
+    /* store buffer pool information */
+    pBufferPool->bufferSize = bufferSize;
+    pBufferPool->numberOfBuffers = numOfBuffers;
+
+    /* initialize the free buffers list */
+    bufferPool_reinit( (TI_HANDLE)pBufferPool );
+
+#ifdef TI_DBG
+       /* initialize debug information */
+       os_memoryZero( pBufferPool->hOS, &(pBufferPool->bufferPoolDbg), sizeof( bufferPoolDbg_t ) );
+#endif /* TI_DBG */
+
+    return pBufferPool;
+}
+
+/**
+ * \author Ronen Kalish\n
+ * \date 05-December-2005\n
+ * \brief Configures a buffer pool object.\n
+ *
+ * Function Scope \e Public.\n
+ * \param hbufferPool - handle to a buffer pool object.\n
+ * \param hReport - handle to the report module.\n
+ */
+void bufferPool_config( TI_HANDLE hBufferPool, TI_HANDLE hReport )
+{
+    bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
+
+    /* keep the report handle */
+    pBufferPool->hReport = hReport;
+}
+
+/**
+ * \author Ronen Kalish\n
+ * \date 05-December-2005\n
+ * \brief releasing a buffer pool object.\n
+ *
+ * Function Scope \e Public.\n
+ * \param hbufferPool - handle to a buffer pool object.\n
+ */
+void bufferPool_destroy( TI_HANDLE hBufferPool )
+{
+    bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
+
+    /* release the buffers storage space */
+    os_memoryFree( pBufferPool->hOS, pBufferPool->firstBuffer,
+                   pBufferPool->bufferSize * pBufferPool->numberOfBuffers );
+
+    /* release the buffer pool object */
+    os_memoryFree( pBufferPool->hOS, pBufferPool, sizeof(bufferPool_t) );
+}
+
+/**
+ * \author Ronen Kalish\n
+ * \date 05-December-2005\n
+ * \brief Reinitializes the buffer pool object, by marking all buffers 
+ * \brief as unallocated.\n
+ *
+ * Function Scope \e Public.\n
+ * \param hbufferPool - handle to a buffer pool object.\n
+ */
+void bufferPool_reinit( TI_HANDLE hBufferPool )
+{
+    bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
+    UINT32 i;
+
+    /* make the first free buffer point to the first buffer */
+    pBufferPool->firstFreeBuffer = pBufferPool->firstBuffer;
+
+    /* insert all buffers to free list - last buffer must point to NULL */
+    for ( i = 0; i < pBufferPool->numberOfBuffers - 1; i++ )
+    {
+        /* make the i'th buffer point to the next buffer */
+        *(bufferPool_buffer_t*)((char*)pBufferPool->firstBuffer + (pBufferPool->bufferSize * i)) = 
+            (bufferPool_buffer_t)((char*)pBufferPool->firstBuffer + (pBufferPool->bufferSize * (i+1)));
+    }
+
+    /* make the last buffer point to NULL */
+    *(bufferPool_buffer_t*)((char*)pBufferPool->firstBuffer + 
+        (pBufferPool->bufferSize * (pBufferPool->numberOfBuffers - 1))) = 
+            BUFFER_POOL_NO_BUFFER;
+
+#ifdef TI_DBG
+       /* mark that no buffers are allocated */
+       pBufferPool->bufferPoolDbg.numberOfUsedBuffers = 0;
+
+       /* mark all buffers as unallocated in the debug information */
+       for ( i = 0; i < BUFFER_POOL_MAX_NUM_OF_BUFFERS_FOR_DBG; i++ )
+       {
+               pBufferPool->bufferPoolDbg.bAllocated[ i ] = FALSE;
+       }
+#endif /* TI_DBG */
+}
+
+/**
+ * \author Ronen Kalish\n
+ * \date 05-December-2005\n
+ * \brief Allocates a buffer.\n
+ *
+ * Function Scope \e Public.\n
+ * \param hbufferPool - handle to a buffer pool object.\n
+ * \return a buffer object, BUFFER_POOL_NO_BUFFER indication if non is available.\n
+ */
+bufferPool_buffer_t bufferPool_allocateBuffer( TI_HANDLE hBufferPool )
+{
+    bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
+    bufferPool_buffer_t buffer;
+#ifdef TI_DBG
+       UINT32 bufferIndex;
+#endif
+
+    /* check if a buffer is available */
+    if ( BUFFER_POOL_NO_BUFFER == pBufferPool->firstFreeBuffer )
+    {
+#ifdef TI_DBG
+               pBufferPool->bufferPoolDbg.NumberOfDeclinedAllocations++;
+#endif /* TI_DBG */
+               return BUFFER_POOL_NO_BUFFER;
+    }
+
+    /* temporarily keep the first free buffer */
+    buffer = pBufferPool->firstFreeBuffer;
+
+    /* advance the first free buffer to point to the next buffer in the list */
+    pBufferPool->firstFreeBuffer = *(bufferPool_buffer_t*)((pBufferPool->firstFreeBuffer));
+
+#ifdef TI_DBG
+       /* increase the buffer in use count */
+       pBufferPool->bufferPoolDbg.numberOfUsedBuffers++;
+
+       /* count the successful allocation */
+       pBufferPool->bufferPoolDbg.NumberOfSuccessfulAllocations++;
+
+       /* mark the specific buffer as used */
+       bufferIndex = ((UINT8*)buffer - (UINT8*)pBufferPool->firstBuffer) / pBufferPool->bufferSize;
+       if ( bufferIndex < BUFFER_POOL_MAX_NUM_OF_BUFFERS_FOR_DBG )
+       {
+               pBufferPool->bufferPoolDbg.bAllocated[ bufferIndex ] = TRUE;
+       }
+#endif /* TI_DBG */
+
+    return buffer;
+}
+
+/**
+ * \author Ronen Kalish\n
+ * \date 05-December-2005\n
+ * \brief Returns a buffer to the pool.\n
+ *
+ * Function Scope \e Public.\n
+ * \param hbufferPool - handle to a buffer pool object.\n
+ * \param buffer - the buffer object to return to the pool.\n
+ */
+void bufferPool_releaseBuffer( TI_HANDLE hBufferPool, bufferPool_buffer_t buffer )
+{
+    bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
+#ifdef TI_DBG
+       UINT32 bufferIndex;
+
+       /* check if the buffer is currently allocated */
+       bufferIndex = ((UINT8*)buffer - (UINT8*)pBufferPool->firstBuffer) / pBufferPool->bufferSize;
+
+       if ( (bufferIndex < BUFFER_POOL_MAX_NUM_OF_BUFFERS_FOR_DBG) &&
+                (FALSE == pBufferPool->bufferPoolDbg.bAllocated[ bufferIndex ]) )
+       {
+               /* count number of free attempts for already free buffers */
+               pBufferPool->bufferPoolDbg.NumberOfFreeBufferRefreed++;
+
+               WLAN_OS_REPORT(("%s: Trying to re-free Buffer %d\n", __FUNCTION__, bufferIndex));
+               return;
+       }
+       else
+       {
+               /* decrease the buffers in use count */
+               pBufferPool->bufferPoolDbg.numberOfUsedBuffers--;
+
+               /* mark that the specific buffer is not in use */
+               pBufferPool->bufferPoolDbg.bAllocated[ bufferIndex ] = FALSE;
+       }
+#endif /* TI_DBG */
+
+    /* make the newly released buffer point to the current first free buffer */
+    *((bufferPool_buffer_t*)buffer) = pBufferPool->firstFreeBuffer;
+
+    /* make the newly release buffer the first free buffer */
+    pBufferPool->firstFreeBuffer = buffer;
+}
+
+#ifdef TI_DBG
+/**
+ * \author Ronen Kalish\n
+ * \date 29-December-2005\n
+ * \brief Returns the buffer pool debug structure.\n
+ *
+ * Function Scope \e Public.\n
+ * \param hbufferPool - handle to a buffer pool object.\n
+ */
+bufferPoolDbg_t *bufferPool_getDebugInformation( TI_HANDLE hBufferPool )
+{
+    bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
+
+       return &(pBufferPool->bufferPoolDbg);
+}
+#endif
+