📄 mem.c
字号:
/*************************************************************************
*
* Copyright (c) 1993 - 2001 Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the
* subject matter of this material. All manufacturing, reproduction,
* use, and sales rights pertaining to this subject matter are governed
* by the license agreement. The recipient of this software implicitly
* accepts the terms of the license.
*
*************************************************************************/
/*************************************************************************
*
* FILE NAME VERSION
*
* MEM.C 4.4
*
* COMPONENT
*
* Net Stack Buffer Management
*
* DESCRIPTION
*
* Buffer management routines used by the network stack.
*
* DATA STRUCTURES
*
* MEM_Buffer_List
* MEM_Buffer_Freelist
* MEM_Buffer_Suspension_List
* MEM_Buffers_Used
* NET_Buffer_Suspension_HISR
* *MEM_Non_Cached
*
* FUNCTIONS
*
* MEM_Init
* MEM_Buffer_Dequeue
* MEM_Buffer_Enqueue
* MEM_Buffer_Chain_Dequeue
* MEM_Update_Buffer_Lists
* MEM_Buffer_Chain_Free
* MEM_One_Buffer_Chain_Free
* MEM_Cat
* MEM_Trim
* MEM_Chain_Copy
* MEM_Buffer_Remove
* MEM_Buffer_Cleanup
* MEM_Buffer_Insert
* MEM_Buffer_Suspension_HISR
*
* DEPENDENCIES
*
* nucleus.h
* externs.h
* tcpdefs.h
* nerrs.h
*
*************************************************************************/
#include "plus/nucleus.h"
#include "net/inc/externs.h"
#include "net/inc/tcpdefs.h"
#include "net/inc/socketd.h"
#include "net/inc/nerrs.h"
/* Declare the NET pointers for holding incoming, and empty packet buffers.
Also declare the buffer suspension list to hold tasks waiting for
buffers. */
NET_BUFFER_HEADER MEM_Buffer_List;
NET_BUFFER_HEADER MEM_Buffer_Freelist;
NET_BUFFER_SUSPENSION_LIST MEM_Buffer_Suspension_List;
/* Declare the suspension hisr. When buffers become available this HISR
will wake up tasks that are suspended waiting for buffers. */
NU_HISR NET_Buffer_Suspension_HISR;
/* A global counter of the number of buffers that are currently allocated.
* Initialized in MEM_Init. */
UINT16 MEM_Buffers_Used;
/* This is a pointer to the memory pool from which Nucleus NET will
allocate frame buffers. Note that one platforms where both NET and the MAC
layer hardware can write to the buffers this memory pool should be in
non-cached memory. Otherwise it can be in cached memory. */
NU_MEMORY_POOL *MEM_Non_Cached;
/*************************************************************************
*
* FUNCTION
*
* MEM_Init
*
* DESCRIPTION
*
* This function initializes the Memory buffer component of
* Nucleus NET.
*
* INPUTS
*
* None
*
* OUTPUTS
*
* NU_SUCCESS
* -1
*
*************************************************************************/
STATUS MEM_Init(VOID)
{
static INT16 i;
CHAR HUGE *ptr;
STATUS ret_status;
/* Initialize the global buffer pointers. */
MEM_Buffer_List.head = NU_NULL;
MEM_Buffer_List.tail = NU_NULL;
MEM_Buffer_Freelist.head = NU_NULL;
MEM_Buffer_Freelist.tail = NU_NULL;
MEM_Buffer_Suspension_List.head = NU_NULL;
MEM_Buffer_Suspension_List.tail = NU_NULL;
/* Break the block of memory up and place each block into the
* buffer_freelist.
*/
for (i = 0; i < MAX_BUFFERS; i++)
{
/* Allocate the memory for a single packet buffer. The size of one
buffer is allocated plus an extra chunck in the case that a memory
alignment other than 4 bytes is required. Nucleus PLUS always
allocates memory on 4 byte boundaries. Hence the subtraction of 4
from the REQ_ALIGNMENT VALUE. */
ret_status = NU_Allocate_Memory(MEM_Non_Cached, (VOID **)&ptr,
(UNSIGNED)(sizeof(NET_BUFFER) + REQ_ALIGNMENT - 4),
(UNSIGNED)NU_NO_SUSPEND);
if (ret_status != NU_SUCCESS)
{
NERRS_Log_Error (NERR_FATAL, __FILE__, __LINE__);
return (NU_MEM_ALLOC);
}
ptr = (CHAR *)TLS_Normalize_Ptr(ptr);
/* If necessary, align the start of this buffer on the correct boundary. */
if ((UINT32)ptr % REQ_ALIGNMENT)
ptr += REQ_ALIGNMENT - ((UINT32)ptr % REQ_ALIGNMENT);
MEM_Buffer_Enqueue(&MEM_Buffer_Freelist, (NET_BUFFER *)ptr);
}
/* Initialize the number of buffers that are currently allocated. */
MEM_Buffers_Used = 0;
/* Allocate memory for the buffer suspension HISR. */
ret_status = NU_Allocate_Memory (&System_Memory, (VOID **)&ptr,
1000, NU_NO_SUSPEND);
/* Did we get the memory? */
if (ret_status == NU_SUCCESS)
{
/* Create the HISR. */
ret_status = NU_Create_HISR (&NET_Buffer_Suspension_HISR, "buf_susp",
MEM_Buffer_Suspension_HISR, 2, ptr, 1000);
}
return (ret_status);
} /* MEM_Init */
/*************************************************************************
*
* FUNCTION
*
* MEM_Buffer_Dequeue
*
* DESCRIPTION
*
* Remove and return the first node in a linked list.
*
* INPUTS
*
* *hdr
*
* UTPUTS
*
* *NET_BUFFER
*
*************************************************************************/
NET_BUFFER *MEM_Buffer_Dequeue(NET_BUFFER_HEADER *hdr)
{
UNSIGNED zero = 0; /* causes most compilers to place this */
/* value in a register only once */
struct _me_bufhdr* headerP;
NET_BUFFER *node;
INT old_level;
/* Make sure we were not passed a null pointer. */
if (!hdr)
return NU_NULL;
/* Temporarily lockout interrupts to protect global buffer variables. */
old_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* If there is a node in the list we want to remove it. */
if (hdr->head)
{
/* Get the node to be removed */
node = hdr->head;
/* Make the hdr point the second node in the list */
hdr->head = node->next;
/* If this is the last node the headers tail pointer needs to be nulled
We do not need to clear the node's next since it is already null */
if (!(hdr->head))
hdr->tail = NU_NULL;
/* Is a buffer being removed from the buffer_freelist. If so increment
the buffers_used counter and clear the buffer header. */
if (hdr == &MEM_Buffer_Freelist)
{
/* Zero the header info. */
headerP = &(node->me_data.me_pkthdr.me_buf_hdr);
headerP->seqnum = zero;
headerP->dlist = (NET_BUFFER_HEADER*)(zero);
headerP->buf_device = (struct _DV_DEVICE_ENTRY*)(zero);
headerP->option_len = (UINT16)zero;
headerP->retransmits = (INT16)zero;
headerP->flags = (UINT16)zero;
headerP->tcp_data_len = (UINT16)zero;
headerP->total_data_len = zero;
headerP->port_index = -1;
/* Zero the pointers. */
node->next = (NET_BUFFER*)(zero);
node->next_buffer = (NET_BUFFER*)(zero);
node->data_ptr = (UINT8 HUGE*)(zero);
node->data_len = zero;
/* Bump the number of buffers that have been pulled from the
freelist. */
MEM_Buffers_Used++;
}
}
else
node = NU_NULL;
/* Restore the previous interrupt lockout level. */
NU_Local_Control_Interrupts(old_level);
/* Return a pointer to the removed node */
return(node);
} /* end MEM_Buffer_Dequeue */
/*************************************************************************
*
* FUNCTION
*
* MEM_Buffer_Enqueue
*
* DESCRIPTION
*
* Insert an item at the end of a linked list.
*
* INPUTS
*
* *hdr
* *item
*
* OUTPUTS
*
* *NET_BUFFER
*
*************************************************************************/
NET_BUFFER *MEM_Buffer_Enqueue(NET_BUFFER_HEADER *hdr, NET_BUFFER *item)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -