📄 tools.c
字号:
/* Update the number of packets that are in the window. */
wind->num_packets --;
}
else
{
/* If we don't have as much data as the user wants then give him what
* we have. */
if ((wind->contain) < (uint)nbytes)
nbytes = wind->contain;
/* because nbytes has its value changed below, actual_bytes is used
* to preserve the number that will be returned.
*/
actual_bytes = nbytes;
/* While there is more data to be moved and buffers exist from which to
* move it, continue.
*/
while ( (nbytes) && (wind->packet_list.head != NU_NULL) )
{
/* Check to see if the current packet buffer contains more than
* enough data. If it does, then simply move the data and update
* the data structures. If it doesn't then all data in the current
* buffer is moved, and that buffer is deallocated.
*/
if (wind->packet_list.head->data_len > nbytes)
{
/* Move the data into the buffer. */
memcpy((void *)(buffer + offset),
(const void *)wind->packet_list.head->data_ptr,
nbytes);
/* Point the data pointer at some fresh data. */
wind->packet_list.head->data_ptr += nbytes;
/* Update the number of bytes that this packet contains. */
wind->packet_list.head->data_len -= nbytes;
/* Update the number of bytes in the window. */
wind->contain -= nbytes;
/* Indicate that the caller's buffer has been filled. */
nbytes -= nbytes;
}
else
{
/* Move the data into the buffer. */
memcpy((void *)(buffer + offset),
(const void *)wind->packet_list.head->data_ptr,
wind->packet_list.head->data_len);
/* Update the number of bytes left before the caller's request
* has been filled. */
nbytes -= wind->packet_list.head->data_len;
/* Update the number of bytes in the window. */
wind->contain -= wind->packet_list.head->data_len;
/* Update the number of packets that are in the window. */
wind->num_packets --;
offset += wind->packet_list.head->data_len;
/* Move the now empty buffer back onto the free list. */
dll_update_lists(&wind->packet_list, &buffer_freelist);
}
}
}
return(actual_bytes);
} /* end dequeue */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* rmqueue */
/* */
/* DESCRIPTION */
/* */
/* Does the queue deallocation once an ack is received. */
/* rmqueue of WINDOWSIZE or greater bytes will empty the queue */
/* */
/* CALLED BY */
/* ackcheck */
/* */
/* CALLS */
/* NU_Deallocate_Partition */
/* NU_Deallocate_Memory */
/* dll_update_lists */
/* */
/*************************************************************************/
uint16 rmqueue (struct window *wind, int32 acked)
{
uint16 bytes_removed = 0;
BUFFER *buf_ptr;
buf_ptr = wind->packet_list.head;
while(buf_ptr)
{
/* If the current packet was acknowledged and the current packet is not
* the next one to be transmitted, then remove it. The sequence number
* for the next packet to be transmitted has not yet been filled in and
* there for contains an arbitrary number that maay be less than the
* received ack. */
if( (INT32_CMP(acked, (buf_ptr->seqnum+(int32)buf_ptr->data_len)) >= 0) &&
(buf_ptr != wind->nextPacket) )
{
/* Update the number of bytes removed so far. */
bytes_removed += buf_ptr->data_len;
/* Update the number of bytes contained in this window. */
wind->contain -= buf_ptr->data_len;
/* Update the number of packets contained in this window. */
wind->num_packets--;
/* Look at the next buffer. */
buf_ptr = (BUFFER *)buf_ptr->next;
/* Place the acknowledged buffer back on the free list. */
dll_update_lists(&wind->packet_list, &buffer_freelist);
}
else
break;
}
/* Return the number of bytes removed. */
return (bytes_removed);
} /* end rmqueue */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* netputevent */
/* */
/* DESCRIPTION */
/* */
/* Add an event to the queue. */
/* Will probably get the memory for the entry from the free list. */
/* Returns 0 if there was room, 1 if an event was lost. */
/* */
/* CALLED BY */
/* icmpinterpret */
/* udpinterpret */
/* tcpdo */
/* ackchk */
/* estab1986 */
/* checkfin */
/* udpinterpret */
/* udpinterpret */
/* Stask */
/* Stimerset */
/* */
/* CALLS */
/* */
/* NU_Obtain_Semaphore */
/* NU_Release_Semaphore */
/* NU_Send_To_Queue */
/* */
/*************************************************************************/
STATUS netputevent (UNSIGNED msg_class, UNSIGNED what, UNSIGNED dat)
{
#ifdef PLUS
STATUS status;
#else /* !PLUS */
int16 status; /* status of memory allocation */
#endif /* !PLUS */
int16 return_status;
/* Send_Message points to a single structure to be placed in the
* event queue. The index 3 signals that the structure is 3 words
* (or 6 bytes) long and is formatted as follows:
* struct
* {
* 8 bits: the msg_class
* 8 bits: the event
* 16 bits: pointer to the next event on the queue
* 16 bits: the data field
* };
*/
/* added 11/4/92 - during ATI mods */
#ifdef PLUS
UNSIGNED Send_Message[3];
/* Send a message to the event queue. Note that if
the queue is full this task suspends until space
becomes available. */
Send_Message[0] = msg_class << 8;
Send_Message[0] |= what;
Send_Message[1] = NU_NULL;
Send_Message[2] = dat;
NU_Release_Semaphore(&TCP_Resource);
status = NU_Send_To_Queue(&eQueue, &Send_Message[0], (UNSIGNED)3,
(UNSIGNED)NU_SUSPEND);
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
#else /* !PLUS */
unsigned int Send_Message[3];
/* Send a message to the event queue. Note that if
* the queue is full this task suspends until space
* becomes available. */
Send_Message[0] = (msg_class << 8);
Send_Message[0] |= what;
Send_Message[1] = NU_NULL;
Send_Message[2] = dat;
NU_Release_Resource(TCP_Resource);
status = NU_Send_Item (eQueue, (unsigned int *)Send_Message,
NU_WAIT_FOREVER);
NU_Request_Resource (TCP_Resource, NU_WAIT_FOREVER);
#endif /* !PLUS */
/* Determine if the message was sent successfully. */
if (status == NU_SUCCESS)
return_status = NU_SUCCESS;
else
return_status = 1;
return (return_status);
} /* end netputevent */
/*************************************************************************/
/* */
/* FUNCTION */
/* */
/* allocate_buffer */
/* */
/* DESCRIPTION */
/* */
/* This function will allocate a buffer if one is available. */
/* */
/* CALLED BY */
/* netwrite */
/* NU_Allocate_Buffer */
/* */
/* CALLS */
/* */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 03/13/95 Initial version. */
/* */
/*************************************************************************/
BUFFER *allocate_buffer(struct port *prt)
{
unsigned long max_bytes;
BUFFER *buf_ptr = NU_NULL;
/* Check to see how many buffers are free. If there are fewer
* than the specified value then return. This prevents the case
* where the application keeps all of the buffers full,
* preventing us from receiving any packets. There must be
* a buffer available when a packet comes in.
*/
if ((MAXBUFFERS - Buffers_Used) <= 3)
return((struct pqueue HUGE *)NU_NULL);
/* Make sure that if an allocated buffer is completly filled the contain
value will not be wrapped. */
max_bytes = (unsigned long) prt->out.contain + MAX_SEGMENT_LEN;
if (max_bytes < (unsigned long) USHORT_MAX)
{
/* Allocate a packet buffer into which the data will be placed. */
buf_ptr = dll_update_lists(&buffer_freelist, &prt->out.packet_list);
if (buf_ptr == NU_NULL)
NU_Tcp_Log_Error (TCP_PARTITION_ERROR, TCP_RECOVERABLE,
__FILE__, __LINE__);
}
return(buf_ptr);
} /* end allocate_buffer */
void *normalize_ptr(void *ptr)
{
#ifdef NORM_PTR
unsigned long temp_address;
temp_address = FP_SEG(ptr);
temp_address = (temp_address << 4) + FP_OFF(ptr);
FP_SEG(ptr) = temp_address >> 4;
FP_OFF(ptr) = temp_address & 0xf;
#endif /* NORM_PTR */
return (ptr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -