void vReleaseNetworkBufferAndDescriptor( xNetworkBufferDescriptor_t * const pxNetworkBuffer ) { BaseType_t xListItemAlreadyInFreeList; #if( ipconfigIP_TASK_KEEPS_MESSAGE_BUFFER != 0 ) if( pxNetworkBuffer == pxIpTaskMessageBuffer ) return; #endif if( !bIsValidNetworkDescriptor ( pxNetworkBuffer ) ) { FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) ); return ; } /* Ensure the buffer is returned to the list of free buffers before the counting semaphore is 'given' to say a buffer is available. */ /* taskENTER_CRITICAL(); */ ipconfigBUFFER_ALLOC_LOCK(); { { xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); if( xListItemAlreadyInFreeList == pdFALSE ) { vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); } } /* configASSERT( xListItemAlreadyInFreeList == pdFALSE ); */ } ipconfigBUFFER_ALLOC_UNLOCK(); /* taskEXIT_CRITICAL(); */ if( xListItemAlreadyInFreeList ) { FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n", pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) ); } if( !xListItemAlreadyInFreeList ) { xSemaphoreGive( xNetworkBufferSemaphore ); showWarnings(); if( xTCPWindowLoggingLevel > 3 ) FreeRTOS_debug_printf( ( "BUF_PUT[%ld]: %p (%p) (now %lu)\n", bIsValidNetworkDescriptor( pxNetworkBuffer ), pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) ); } iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer ); }
void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer ) { BaseType_t xListItemAlreadyInFreeList; if( bIsValidNetworkDescriptor( pxNetworkBuffer ) == pdFALSE_UNSIGNED ) { FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) ); return ; } /* Ensure the buffer is returned to the list of free buffers before the counting semaphore is 'given' to say a buffer is available. */ ipconfigBUFFER_ALLOC_LOCK(); { { xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); if( xListItemAlreadyInFreeList == pdFALSE ) { vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) ); } } } ipconfigBUFFER_ALLOC_UNLOCK(); if( xListItemAlreadyInFreeList ) { FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n", pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) ); } if( xListItemAlreadyInFreeList == pdFALSE ) { xSemaphoreGive( xNetworkBufferSemaphore ); prvShowWarnings(); if( xTCPWindowLoggingLevel > 3 ) FreeRTOS_debug_printf( ( "BUF_PUT[%ld]: %p (%p) (now %lu)\n", bIsValidNetworkDescriptor( pxNetworkBuffer ), pxNetworkBuffer, pxNetworkBuffer->pucEthernetBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) ); } iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer ); }
NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks ) { NetworkBufferDescriptor_t *pxReturn = NULL; BaseType_t xInvalid = pdFALSE; size_t uxCount; /* The current implementation only has a single size memory block, so the requested size parameter is not used (yet). */ ( void ) xRequestedSizeBytes; if( xNetworkBufferSemaphore != NULL ) { /* If there is a semaphore available, there is a network buffer available. */ if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS ) { /* Protect the structure as it is accessed from tasks and interrupts. */ ipconfigBUFFER_ALLOC_LOCK(); { pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList ); if( bIsValidNetworkDescriptor(pxReturn) && listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxReturn->xBufferListItem ) ) ) { uxListRemove( &( pxReturn->xBufferListItem ) ); } else { xInvalid = pdTRUE; } } ipconfigBUFFER_ALLOC_UNLOCK(); if( xInvalid ) { FreeRTOS_debug_printf( ( "pxGetNetworkBufferWithDescriptor: INVALID BUFFER: %p (valid %lu)\n", pxReturn, bIsValidNetworkDescriptor( pxReturn ) ) ); pxReturn = NULL; } else { { /* Reading UBaseType_t, no critical section needed. */ uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList ); if( uxMinimumFreeNetworkBuffers > uxCount ) { uxMinimumFreeNetworkBuffers = uxCount; } } pxReturn->xDataLength = xRequestedSizeBytes; #if( ipconfigTCP_IP_SANITY != 0 ) { showWarnings(); } #endif /* ipconfigTCP_IP_SANITY */ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 ) { /* make sure the buffer is not linked */ pxReturn->pxNextBuffer = NULL; } #endif /* ipconfigUSE_LINKED_RX_MESSAGES */ if( xTCPWindowLoggingLevel > 3 ) { FreeRTOS_debug_printf( ( "BUF_GET[%ld]: %p (%p)\n", bIsValidNetworkDescriptor( pxReturn ), pxReturn, pxReturn->pucEthernetBuffer ) ); } } iptraceNETWORK_BUFFER_OBTAINED( pxReturn ); } else { iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER(); } } return pxReturn; }