📄 mem.c
字号:
*
* None
*
*************************************************************************/
VOID MEM_One_Buffer_Chain_Free (NET_BUFFER *source, NET_BUFFER_HEADER *dest)
{
INT old_level;
if ( (!source) || (!dest) )
return;
/* Temporarily lockout interrupts to protect the global buffer variables. */
old_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* Only deallocate all the buffers in the chain if the destination list
is the buffer free list. Otherwise just move the parent buffer to
the end of the dest list. */
if (dest == &MEM_Buffer_Freelist)
{
/* Go through the entire buffer chain moving each buffer to the
destination list */
while (source != NU_NULL)
{
/* Put one part of the chain onto the destination list */
MEM_Buffer_Enqueue(dest, source);
/* Move to the next buffer in the chain */
source = source->next_buffer;
}
}
else
MEM_Buffer_Enqueue(dest, source);
/* Restore the previous interrupt lockout level. */
NU_Local_Control_Interrupts(old_level);
/* If there are enough free buffers and a task is waiting for
buffers then activate a HISR to resume the task. */
if (MEM_Buffer_Suspension_List.head &&
((MAX_BUFFERS - MEM_Buffers_Used) > NET_FREE_BUFFER_THRESHOLD))
NU_Activate_HISR (&NET_Buffer_Suspension_HISR);
} /* end MEM_One_Buffer_Chain_Free routine */
/* The next two functions are only used by the IP reassembly code. */
#if INCLUDE_IP_REASSEMBLY
/*************************************************************************
*
* FUNCTION
*
* MEM_Cat
*
* DESCRIPTION
*
* This function concatenates the source buffer chain and the
* destination buffer chain.
*
* INPUTS
*
* *dest The destination chain.
* *src The source chain. will be added to the end of
* the destination chain.
*
* OUTPUTS
*
* None
*
*************************************************************************/
VOID MEM_Cat (NET_BUFFER *dest, NET_BUFFER *src)
{
NET_BUFFER *dest_work;
if ( (!src) || (!dest) )
return;
/* Get work pointers */
dest_work = dest;
/* Find the last buffer in the chain. */
while (dest_work->next_buffer)
dest_work = dest_work->next_buffer;
/* Add the src chain to the destination chain. */
dest_work->next_buffer = src;
} /* MEM_Cat */
#endif /* INCLUDE_IP_REASSEMBLY */
/*************************************************************************
*
* FUNCTION
*
* MEM_Trim
*
* DESCRIPTION
*
* This function trims data from the start of an buffer chain.
*
* INPUTS
*
* *buf_ptr
* length
*
* OUTPUTS
*
* None
*
*************************************************************************/
VOID MEM_Trim (NET_BUFFER *buf_ptr, INT32 length)
{
INT32 t_len = length;
NET_BUFFER *m;
INT32 count;
INT old_level;
/* Perform some basic error checking. */
if ( ((m = buf_ptr) == NU_NULL))
return;
/* Temporarily lockout interrupts to protect the global buffer variables. */
old_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* If length is greater than 0 then trim data from the start. */
if (t_len >= 0)
{
/* Start with the first buffer in the chain and remove data as necessary. */
while (m != NU_NULL && t_len > 0)
{
if (m->data_len <= (UINT32)t_len)
{
t_len -= m->data_len;
m->data_len = 0;
m = m->next_buffer;
}
else
{
m->data_len -= t_len;
m->data_ptr += t_len;
t_len = 0;
}
}
/* Update the total number of bytes in this packet. */
buf_ptr->mem_total_data_len -= (length - t_len);
}
else
{
t_len = -t_len;
count = 0;
/* Get a count of the total number of bytes in this chain. */
for(;;)
{
count += m->data_len;
if(m->next_buffer == NU_NULL)
break;
m = m->next_buffer;
}
/* If the adjustment only affects the last buffer in the chain, make the
adjustment and return. */
if (m->data_len >= (UINT32)t_len)
{
m->data_len -= t_len;
buf_ptr->mem_total_data_len -= t_len;
/* Restore the previous interrupt lockout level. */
NU_Local_Control_Interrupts(old_level);
return;
}
count -= t_len;
if (count < 0)
count = 0;
/* The correct length for the chain is "count". */
m = buf_ptr;
m->mem_total_data_len = count;
/* Find the buffer with the last data. Adjust its length. */
for(; m ; m = m->next_buffer)
{
if (m->data_len >= (UINT32)count)
{
m->data_len = count;
break;
}
count -= m->data_len;
}
/* Toss out the data from the remaining buffers. */
while ((m = m->next_buffer) != NU_NULL)
m->data_len = 0;
}
/* Restore the previous interrupt lockout level. */
NU_Local_Control_Interrupts(old_level);
} /* MEM_Trim */
/*************************************************************************
*
* FUNCTION
*
* MEM_Chain_Copy
*
* DESCRIPTION
*
* This function copies a memory chain.
*
* INPUTS
*
* *dest
* *src
* off
* len
*
* OUTPUTS
*
* None
*
*************************************************************************/
VOID MEM_Chain_Copy(NET_BUFFER *dest, NET_BUFFER *src, INT32 off, INT32 len)
{
NET_BUFFER *s = src;
NET_BUFFER *d = dest;
INT first_buffer = 0;
INT32 bytes_to_copy;
INT32 data_off = 0;
INT32 max_buf_size;
if ((off < 0) || (len < 0) || (d == NU_NULL) || (s == NU_NULL))
return;
/* First we need to find the buffer within the chain where the first byte
specified by offset is found. */
while (off > 0)
{
/* Is this the one. */
if (off < (INT)s->data_len)
break;
/* Now check the next one. */
off -= s->data_len;
s = s->next_buffer;
}
while ((len > 0) && d && s)
{
/* Choose the min of the data in the source and the total data length
we wish to copy. */
if (len < (INT)s->data_len - off)
{
/* Set the maximum buffer size */
if(first_buffer == 0)
{
max_buf_size = NET_PARENT_BUFFER_SIZE;
}
else
{
max_buf_size = NET_MAX_BUFFER_SIZE;
}
/* Check to see if data is already in buffer */
if(d->data_len > 0)
{
/* Set the offset past the data already in the buffer */
data_off = d->data_len;
/* Ensure that the data being copied in does not exceed */
/* the max buffer size */
if((d->data_len + len) > (UINT32)max_buf_size)
{
/* Set the bytes to copy and the data_len */
bytes_to_copy = max_buf_size - d->data_len;
d->data_len = max_buf_size;
}
else
{
/* Set the bytes to copy and the data_len */
d->data_len = d->data_len + len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -