📄 mem.c
字号:
{
INT old_level;
if (!hdr)
return NU_NULL;
if(item != NU_NULL)
{
/* Temporarily lockout interrupts to protect global buffer variables. */
old_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* Set node's next to point at NULL */
item->next = NU_NULL;
/* If there is currently a node in the linked list, we want to add the
new node to the end. */
if (hdr->head)
{
/* Make the last node's next point to the new node. */
hdr->tail->next = item;
/* Make the roots tail point to the new node */
hdr->tail = item;
}
/* If the linked list was empty, we want both the root's head and
tial to point to the new node. */
else
{
hdr->head = item;
hdr->tail = item;
}
/* If a buffer is being moved back onto the buffer free list, then
decrement the the number of buffers that are currently used. */
if (hdr == &MEM_Buffer_Freelist)
{
--MEM_Buffers_Used;
}
/* Restore the previous interrupt lockout level. */
NU_Local_Control_Interrupts(old_level);
}
return(item);
} /* end MEM_Bufffer_Enqueue */
/*************************************************************************
*
* FUNCTION
*
* MEM_Buffer_Chain_Dequeue
*
* DESCRIPTION
*
* Dequeue a linked chain of buffer(s) large enough to hold the
* number of bytes of packet data.
*
* INPUTS
*
* *header
* nbytes
*
* OUTPUTS
*
* *NET_BUFFER
*
*************************************************************************/
NET_BUFFER *MEM_Buffer_Chain_Dequeue (NET_BUFFER_HEADER *header, INT32 nbytes)
{
NET_BUFFER *ret_buf_ptr, *work_buf_ptr;
INT32 x, num_bufs;
INT old_level;
if ( (!header) || (nbytes <= 0) )
return NU_NULL;
/* Temporarily lockout interrupts to protect the global buffer variables. */
old_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* Go ahead and dequeue the parent buffer of the chain. */
ret_buf_ptr = MEM_Buffer_Dequeue (header);
/* Make sure we got a buffer. */
if (ret_buf_ptr != NU_NULL)
{
/* NULL the pointer */
ret_buf_ptr->next = NU_NULL;
ret_buf_ptr->next_buffer = NU_NULL;
/* Check to see if we need to chain some buffers together. */
num_bufs = (nbytes + (sizeof(struct _me_bufhdr) - 1))/ NET_MAX_BUFFER_SIZE;
/* If we need more get the first one */
if (num_bufs)
{
ret_buf_ptr->next_buffer = work_buf_ptr = MEM_Buffer_Dequeue (header);
/* Make sure we got a buffer. If not, the ones we did get will be put
back on the buffer freelist and NULL returned to caller. */
if (work_buf_ptr != NU_NULL)
{
/* Now get the rest and link them together. */
for (x = 1; x < num_bufs; x++)
{
/* Dequeue a buffer and link it to the buffer chain. */
work_buf_ptr->next_buffer = MEM_Buffer_Dequeue (header);
/* Make sure we got a buffer. If not, the ones we did get will be put
back on the buffer freelist and NULL returned to caller. */
if (work_buf_ptr->next_buffer != NU_NULL)
{
work_buf_ptr->next = NU_NULL;
/* Move the work pointer to the next buffer. */
work_buf_ptr = work_buf_ptr->next_buffer;
}
else
{
/* Give the buffers back. */
MEM_One_Buffer_Chain_Free (ret_buf_ptr, &MEM_Buffer_Freelist);
/* Null the return pointer. */
ret_buf_ptr = NU_NULL;
/* Get out of the for loop */
x = num_bufs;
}
}
/* Make sure we are not falling through because of lack of buffers. */
if (ret_buf_ptr != NU_NULL)
{
/* Null the end of the chain. */
work_buf_ptr->next_buffer = NU_NULL;
work_buf_ptr->next = NU_NULL;
}
}
else
{
/* Give the buffers back. */
MEM_One_Buffer_Chain_Free (ret_buf_ptr, &MEM_Buffer_Freelist);
/* Null the return pointer. */
ret_buf_ptr = NU_NULL;
}
}
}
/* Restore the previous interrupt lockout level. */
NU_Local_Control_Interrupts(old_level);
/* Return the head off the buffer chain. */
return (ret_buf_ptr);
}
/*************************************************************************
*
* FUNCTION
*
* MEM_Update_Buffer_Lists
*
* DESCRIPTION
*
* This function removes the first node from the source list and
* places it at the tail of the destination list. Then returns a
* pointer to the moved node.
*
* INPUTS
*
* *source Pointer to the list from which the node will be
* removed.
* *dest Pointer to the list to which the node will be
* placed.
*
* OUTPUTS
*
* *NET_BUFFER pointer to the node that was moved.
*
*************************************************************************/
NET_BUFFER *MEM_Update_Buffer_Lists (NET_BUFFER_HEADER *source,
NET_BUFFER_HEADER *dest)
{
NET_BUFFER *tmp_ptr;
INT old_level;
/* Temporarily lockout interrupts to protect the global buffer variables. */
old_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* Get a pointer to the lists. */
tmp_ptr = MEM_Buffer_Dequeue(source);
/* Make sure there was a node to move. */
if (tmp_ptr != NU_NULL)
MEM_Buffer_Enqueue(dest, tmp_ptr);
/* Restore the previous interrupt lockout level. */
NU_Local_Control_Interrupts(old_level);
return(tmp_ptr);
} /* end MEM_Update_Buffer_Lists routine */
/*************************************************************************
*
* FUNCTION
*
* MEM_Buffer_Chain_Free
*
* DESCRIPTION
*
* This function removes the first node and each one in the chain
* from the source list and places them at the tail of the
* destination list as individual nodes, not a chain.
*
* INPUTS
*
* *source Pointer to the list from which the node will be
* removed.
* *dest Pointer to the list to which the node will be
* placed.
*
* OUTPUTS
*
* None
*
*************************************************************************/
VOID MEM_Buffer_Chain_Free (NET_BUFFER_HEADER *source, NET_BUFFER_HEADER *dest)
{
NET_BUFFER *tmp_ptr;
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);
tmp_ptr = MEM_Buffer_Dequeue(source);
/* Go through the entire buffer chain moving each buffer to the
destination list */
while (tmp_ptr != NU_NULL)
{
/* Put one part of the chain onto the destination list */
MEM_Buffer_Enqueue(dest, tmp_ptr);
/* Move to the next buffer in the chain */
tmp_ptr = tmp_ptr->next_buffer;
}
/* 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_Buffer_Chain_Free routine */
/*************************************************************************
*
* FUNCTION
*
* MEM_One_Buffer_Chain_Free
*
* DESCRIPTION
*
* This function removes all nodes in the source chain and puts them
* at the end of the destination list, if the destination list is
* the buffer freelist. Otherwise it just puts the source node to
* the end of the dest list.
*
* INPUTS
*
* *source Pointer to the buffer chain that will be removed.
* *dest Pointer to the list to which the node(s) will be
* placed
*
* OUTPUTS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -