• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** \file bufferPool.c
2  *  \brief This file include buffer pool module implementation
3  *  \author Ronen Kalish
4  *  \date 05-December-2005
5  */
6 
7 /****************************************************************************
8 **+-----------------------------------------------------------------------+**
9 **|                                                                       |**
10 **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved.      |**
11 **| All rights reserved.                                                  |**
12 **|                                                                       |**
13 **| Redistribution and use in source and binary forms, with or without    |**
14 **| modification, are permitted provided that the following conditions    |**
15 **| are met:                                                              |**
16 **|                                                                       |**
17 **|  * Redistributions of source code must retain the above copyright     |**
18 **|    notice, this list of conditions and the following disclaimer.      |**
19 **|  * Redistributions in binary form must reproduce the above copyright  |**
20 **|    notice, this list of conditions and the following disclaimer in    |**
21 **|    the documentation and/or other materials provided with the         |**
22 **|    distribution.                                                      |**
23 **|  * Neither the name Texas Instruments nor the names of its            |**
24 **|    contributors may be used to endorse or promote products derived    |**
25 **|    from this software without specific prior written permission.      |**
26 **|                                                                       |**
27 **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |**
28 **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |**
29 **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
30 **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |**
31 **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
32 **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |**
33 **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
34 **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
35 **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |**
36 **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
37 **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |**
38 **|                                                                       |**
39 **+-----------------------------------------------------------------------+**
40 ****************************************************************************/
41 
42 #include "bufferPool.h"
43 #include "osApi.h"
44 #include "report.h"
45 
46 /**
47  * \author Ronen Kalish\n
48  * \date 05-December-2005\n
49  * \brief Creates a buffer pool object
50  *
51  * Function Scope \e Public.\n
52  * \param hOS - handle to the OS object.\n
53  * \param numOfBuffers - the number of buffers to allocate for this pool.\n
54  * \param bufferSize - the size of each buffer in this pool.\n
55  * \return a handle to a buffer pool object, NULL if an error occurred.\n
56  */
bufferPool_create(TI_HANDLE hOS,UINT32 numOfBuffers,UINT32 bufferSize)57 TI_HANDLE bufferPool_create( TI_HANDLE hOS, UINT32 numOfBuffers, UINT32 bufferSize )
58 {
59     /* allocate the buffer pool object */
60     bufferPool_t *pBufferPool = os_memoryAlloc( hOS, sizeof(bufferPool_t) );
61     if ( NULL == pBufferPool )
62     {
63         WLAN_OS_REPORT( ("ERROR: Failed to create buffer pool object") );
64         return NULL;
65     }
66 
67     /*
68      * adjust buffer size if necessary - the buffer must at least store the pointer to the
69      * next free buffer when it is free.
70      */
71     if ( sizeof( bufferPool_buffer_t ) > bufferSize )
72     {
73         bufferSize = sizeof( bufferPool_buffer_t );
74     }
75 
76     /* nullify the buffer pool object */
77     os_memoryZero( hOS, pBufferPool, sizeof( bufferPool_t ) );
78 
79     /* allocate the buffers */
80     pBufferPool->firstBuffer = pBufferPool->firstFreeBuffer = os_memoryAlloc( hOS, numOfBuffers * bufferSize );
81     if ( NULL == pBufferPool->firstBuffer )
82     {
83         WLAN_OS_REPORT( ("ERROR: Failed to allocate buffer storage space") );
84         bufferPool_destroy( (TI_HANDLE)pBufferPool );
85         return NULL;
86     }
87 
88     /* store the OS handle */
89     pBufferPool->hOS = hOS;
90 
91     /* store buffer pool information */
92     pBufferPool->bufferSize = bufferSize;
93     pBufferPool->numberOfBuffers = numOfBuffers;
94 
95     /* initialize the free buffers list */
96     bufferPool_reinit( (TI_HANDLE)pBufferPool );
97 
98 #ifdef TI_DBG
99 	/* initialize debug information */
100 	os_memoryZero( pBufferPool->hOS, &(pBufferPool->bufferPoolDbg), sizeof( bufferPoolDbg_t ) );
101 #endif /* TI_DBG */
102 
103     return pBufferPool;
104 }
105 
106 /**
107  * \author Ronen Kalish\n
108  * \date 05-December-2005\n
109  * \brief Configures a buffer pool object.\n
110  *
111  * Function Scope \e Public.\n
112  * \param hbufferPool - handle to a buffer pool object.\n
113  * \param hReport - handle to the report module.\n
114  */
bufferPool_config(TI_HANDLE hBufferPool,TI_HANDLE hReport)115 void bufferPool_config( TI_HANDLE hBufferPool, TI_HANDLE hReport )
116 {
117     bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
118 
119     /* keep the report handle */
120     pBufferPool->hReport = hReport;
121 }
122 
123 /**
124  * \author Ronen Kalish\n
125  * \date 05-December-2005\n
126  * \brief releasing a buffer pool object.\n
127  *
128  * Function Scope \e Public.\n
129  * \param hbufferPool - handle to a buffer pool object.\n
130  */
bufferPool_destroy(TI_HANDLE hBufferPool)131 void bufferPool_destroy( TI_HANDLE hBufferPool )
132 {
133     bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
134 
135     /* release the buffers storage space */
136     os_memoryFree( pBufferPool->hOS, pBufferPool->firstBuffer,
137                    pBufferPool->bufferSize * pBufferPool->numberOfBuffers );
138 
139     /* release the buffer pool object */
140     os_memoryFree( pBufferPool->hOS, pBufferPool, sizeof(bufferPool_t) );
141 }
142 
143 /**
144  * \author Ronen Kalish\n
145  * \date 05-December-2005\n
146  * \brief Reinitializes the buffer pool object, by marking all buffers
147  * \brief as unallocated.\n
148  *
149  * Function Scope \e Public.\n
150  * \param hbufferPool - handle to a buffer pool object.\n
151  */
bufferPool_reinit(TI_HANDLE hBufferPool)152 void bufferPool_reinit( TI_HANDLE hBufferPool )
153 {
154     bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
155     UINT32 i;
156 
157     /* make the first free buffer point to the first buffer */
158     pBufferPool->firstFreeBuffer = pBufferPool->firstBuffer;
159 
160     /* insert all buffers to free list - last buffer must point to NULL */
161     for ( i = 0; i < pBufferPool->numberOfBuffers - 1; i++ )
162     {
163         /* make the i'th buffer point to the next buffer */
164         *(bufferPool_buffer_t*)((char*)pBufferPool->firstBuffer + (pBufferPool->bufferSize * i)) =
165             (bufferPool_buffer_t)((char*)pBufferPool->firstBuffer + (pBufferPool->bufferSize * (i+1)));
166     }
167 
168     /* make the last buffer point to NULL */
169     *(bufferPool_buffer_t*)((char*)pBufferPool->firstBuffer +
170         (pBufferPool->bufferSize * (pBufferPool->numberOfBuffers - 1))) =
171             BUFFER_POOL_NO_BUFFER;
172 
173 #ifdef TI_DBG
174 	/* mark that no buffers are allocated */
175 	pBufferPool->bufferPoolDbg.numberOfUsedBuffers = 0;
176 
177 	/* mark all buffers as unallocated in the debug information */
178 	for ( i = 0; i < BUFFER_POOL_MAX_NUM_OF_BUFFERS_FOR_DBG; i++ )
179 	{
180 		pBufferPool->bufferPoolDbg.bAllocated[ i ] = FALSE;
181 	}
182 #endif /* TI_DBG */
183 }
184 
185 /**
186  * \author Ronen Kalish\n
187  * \date 05-December-2005\n
188  * \brief Allocates a buffer.\n
189  *
190  * Function Scope \e Public.\n
191  * \param hbufferPool - handle to a buffer pool object.\n
192  * \return a buffer object, BUFFER_POOL_NO_BUFFER indication if non is available.\n
193  */
bufferPool_allocateBuffer(TI_HANDLE hBufferPool)194 bufferPool_buffer_t bufferPool_allocateBuffer( TI_HANDLE hBufferPool )
195 {
196     bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
197     bufferPool_buffer_t buffer;
198 #ifdef TI_DBG
199 	UINT32 bufferIndex;
200 #endif
201 
202     /* check if a buffer is available */
203     if ( BUFFER_POOL_NO_BUFFER == pBufferPool->firstFreeBuffer )
204     {
205 #ifdef TI_DBG
206 		pBufferPool->bufferPoolDbg.NumberOfDeclinedAllocations++;
207 #endif /* TI_DBG */
208 		return BUFFER_POOL_NO_BUFFER;
209     }
210 
211     /* temporarily keep the first free buffer */
212     buffer = pBufferPool->firstFreeBuffer;
213 
214     /* advance the first free buffer to point to the next buffer in the list */
215     pBufferPool->firstFreeBuffer = *(bufferPool_buffer_t*)((pBufferPool->firstFreeBuffer));
216 
217 #ifdef TI_DBG
218 	/* increase the buffer in use count */
219 	pBufferPool->bufferPoolDbg.numberOfUsedBuffers++;
220 
221 	/* count the successful allocation */
222 	pBufferPool->bufferPoolDbg.NumberOfSuccessfulAllocations++;
223 
224 	/* mark the specific buffer as used */
225 	bufferIndex = ((UINT8*)buffer - (UINT8*)pBufferPool->firstBuffer) / pBufferPool->bufferSize;
226 	if ( bufferIndex < BUFFER_POOL_MAX_NUM_OF_BUFFERS_FOR_DBG )
227 	{
228 		pBufferPool->bufferPoolDbg.bAllocated[ bufferIndex ] = TRUE;
229 	}
230 #endif /* TI_DBG */
231 
232     return buffer;
233 }
234 
235 /**
236  * \author Ronen Kalish\n
237  * \date 05-December-2005\n
238  * \brief Returns a buffer to the pool.\n
239  *
240  * Function Scope \e Public.\n
241  * \param hbufferPool - handle to a buffer pool object.\n
242  * \param buffer - the buffer object to return to the pool.\n
243  */
bufferPool_releaseBuffer(TI_HANDLE hBufferPool,bufferPool_buffer_t buffer)244 void bufferPool_releaseBuffer( TI_HANDLE hBufferPool, bufferPool_buffer_t buffer )
245 {
246     bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
247 #ifdef TI_DBG
248 	UINT32 bufferIndex;
249 
250 	/* check if the buffer is currently allocated */
251 	bufferIndex = ((UINT8*)buffer - (UINT8*)pBufferPool->firstBuffer) / pBufferPool->bufferSize;
252 
253 	if ( (bufferIndex < BUFFER_POOL_MAX_NUM_OF_BUFFERS_FOR_DBG) &&
254 		 (FALSE == pBufferPool->bufferPoolDbg.bAllocated[ bufferIndex ]) )
255 	{
256 		/* count number of free attempts for already free buffers */
257 		pBufferPool->bufferPoolDbg.NumberOfFreeBufferRefreed++;
258 
259 		WLAN_OS_REPORT(("%s: Trying to re-free Buffer %d\n", __FUNCTION__, bufferIndex));
260 		return;
261 	}
262 	else
263 	{
264 		/* decrease the buffers in use count */
265 		pBufferPool->bufferPoolDbg.numberOfUsedBuffers--;
266 
267 		/* mark that the specific buffer is not in use */
268 		pBufferPool->bufferPoolDbg.bAllocated[ bufferIndex ] = FALSE;
269 	}
270 #endif /* TI_DBG */
271 
272     /* make the newly released buffer point to the current first free buffer */
273     *((bufferPool_buffer_t*)buffer) = pBufferPool->firstFreeBuffer;
274 
275     /* make the newly release buffer the first free buffer */
276     pBufferPool->firstFreeBuffer = buffer;
277 }
278 
279 #ifdef TI_DBG
280 /**
281  * \author Ronen Kalish\n
282  * \date 29-December-2005\n
283  * \brief Returns the buffer pool debug structure.\n
284  *
285  * Function Scope \e Public.\n
286  * \param hbufferPool - handle to a buffer pool object.\n
287  */
bufferPool_getDebugInformation(TI_HANDLE hBufferPool)288 bufferPoolDbg_t *bufferPool_getDebugInformation( TI_HANDLE hBufferPool )
289 {
290     bufferPool_t* pBufferPool = (bufferPool_t*)hBufferPool;
291 
292 	return &(pBufferPool->bufferPoolDbg);
293 }
294 #endif
295 
296