📄 equeue.c
字号:
/****************************************************************************/
/* */
/* CopyrIght (c) 1993 - 1996 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 implicity accepts the terms */
/* of the license. */
/* */
/****************************************************************************/
/******************************************************************************/
/* */
/* FILENAME VERSION */
/* */
/* equeue.c 3.2 */
/* */
/* DESCRIPTION */
/* */
/* Event queue manager */
/* */
/* AUTHOR */
/* */
/* */
/* DATA STRUCTURES */
/* */
/* */
/* FUNCTIONS */
/* */
/* NU_EventsDispatcher */
/* */
/* DEPENDENCIES */
/* */
/* No other file dependencies */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Barbara Harwell 10/14/92 Created initial version. */
/* Barbara Harwell 10/26/92 Modified to include queue services. */
/* Glen Johnson 04/30/96 Made some changes based on */
/* recommendations of K. Goto */
/* of Hitachi. */
/* */
/******************************************************************************/
#ifdef PLUS
#include "nucleus.h"
#else /* !PLUS */
#include "nu_defs.h" /* added during ATI mods - 10/20/92, bgh */
#include "nu_extr.h"
#endif /* !PLUS */
#include "netevent.h"
#include "protocol.h"
#include "socketd.h"
#include "externs.h" /* include prototypes */
#include "data.h"
#include "target.h"
#include "tcpdefs.h"
extern unsigned short syntimes;
extern unsigned short syntimes_add;
char buffer[40];
#ifndef PLUS
void NU_EventsDispatcher(void);
#endif
/********************************************************************
* void NU_EventsDispatcher(void)
*
* This function is responsible for dispatching events from the
* event queue to the appropriate handling routines.
*
* History:
* created - 10/14/92, bgh
* modified - 10/26/92, bgh - to include Nucleus queue services
*********************************************************************/
#ifdef PLUS
VOID NU_EventsDispatcher(UNSIGNED argc, VOID *argv)
#else /* !PLUS */
VOID NU_EventsDispatcher(VOID)
#endif /* !PLUS */
{
uint8 * pc; /* holds the hardware address of the
destination pc */
struct uport *uprt;
struct port *prt,
**q; /* port pointers */
uint16 u; /* port list index */
UNSIGNED sw;
#ifdef PLUS
STATUS status;
UNSIGNED waittime;
#else /* !PLUS */
int16 status,
waittime;
#endif /* !PLUS */
int16 tmoflag;
UNSIGNED event = 0,
msg_class = 0,
dat = 0;
tqe_t *duptqe,
*tqe_wait; /* Timer queue entry */
/*******************************************************************
Receive_Message points to a single occurence 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
}
*******************************************************************/
#ifdef PLUS
UNSIGNED Receive_Message[3] = {0, 0, 0};
UNSIGNED actual_size;
#else /* !PLUS */
unsigned int Receive_Message[3];
#endif /* !PLUS */
tqe_wait = (tqe_t *)0;
#ifdef PLUS
/* Remove compilation warnings for unused parameters. */
status = (STATUS) argc + (STATUS) argv;
#endif
while (1)
{
/* Retrieve a message from the event queue. Note that if the source
queue is empty this task suspends until something becomes
available. */
#ifdef PLUS
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
#else /* !PLUS */
NU_Request_Resource(TCP_Resource, NU_WAIT_FOREVER);
#endif /* !PLUS */
/* If someone is waiting on the timer list, then we need to
calculate the next hit time for that timer. */
if (!tqe_wait)
tqe_wait = tcp_timerlist.flink;
if (tqe_wait) {
#ifdef PLUS
if (tqe_wait->duetime > NU_Retrieve_Clock())
waittime = ((UNSIGNED) tqe_wait->duetime - NU_Retrieve_Clock());
else
waittime = NU_NO_SUSPEND;
#else /* !PLUS */
waittime = (tqe_wait->duetime - NU_Read_Time());
if (waittime <= 0)
waittime = (-1);
#endif /* !PLUS */
}
else {
tqe_wait = (tqe_t *)0;
#ifdef PLUS
waittime = NU_SUSPEND;
#else /* !PLUS */
waittime = NU_WAIT_FOREVER;
#endif /* !PLUS */
}
#ifdef PLUS
/* If waittime is not NU_SUSPEND then there is a timeout value. */
if (waittime != NU_NO_SUSPEND) {
NU_Release_Semaphore(&TCP_Resource);
#else /* !PLUS */
if (waittime >= 0) {
NU_Release_Resource(TCP_Resource);
#endif /* !PLUS */
#ifdef PLUS
status = NU_Receive_From_Queue(&eQueue, &Receive_Message[0],
(UNSIGNED)3, &actual_size, waittime);
#else /* !PLUS */
status = NU_Retrieve_Item(eQueue, Receive_Message, waittime);
#endif /* !PLUS */
#ifdef PLUS
NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
#else /* !PLUS */
NU_Request_Resource(TCP_Resource, NU_WAIT_FOREVER);
#endif /* !PLUS */
}
else
#ifdef PLUS
status = NU_TIMEOUT;
#else /* !PLUS */
status = NU_QUEUE_TIMEOUT;
#endif /* !PLUS */
#ifndef INTERRUPT
netsleep(0);
#endif /* !INTERRUPT */
/* Determine if the message was received successfully. */
#ifdef PLUS
if (status == NU_TIMEOUT)
#else /* !PLUS */
if (status == NU_QUEUE_TIMEOUT)
#endif /* !PLUS */
{
if (tqe_wait == tcp_timerlist.flink) {
/* Take off the head of the list. */
dll_dequeue((tqe_t *) &tcp_timerlist);
/* Place any duplicate entries on to the timer list. */
duptqe = dll_dequeue((tqe_t *) &tqe_wait->duplist);
while (duptqe)
{
tqpost((tqe_t *) &tcp_timerlist, duptqe);
duptqe = dll_dequeue((tqe_t *) &tqe_wait->duplist);
}
/* Place the dequeued entry on the free list. */
dll_enqueue((tqe_t *) &tcptimer_freelist, tqe_wait);
tmoflag = 1;
/* Take care of event TCPRETRANS here...other events are
handled by the CASE statement below... */
if (tqe_wait->tqe_event == TCPRETRANS)
{
/* Get a pointer to the porlist entry. */
prt = portlist[tqe_wait->tqe_data];
/* If there is still data to be transmitted and we
still have a connection, update the retransmission
timeout value. */
if ((prt->out.num_packets > 0) || (prt->state > SEST))
{
/* If a retransmission timeout occurs, exponential
* back-off. This number returns toward the correct
* value by the RTT measurement code in ackcheck. */
if (prt->rto < MAXRTO)
prt->rto <<= 1; /* double it */
}
tcp_retransmit (prt, tqe_wait->tqe_ext_data);
tqe_wait = (tqe_t *)0;
#ifdef PLUS
NU_Release_Semaphore(&TCP_Resource);
#else /* !PLUS */
NU_Release_Resource(TCP_Resource);
#endif /* !PLUS */
continue;
}
else
{
msg_class = tqe_wait->tqe_class;
event = tqe_wait->tqe_event;
dat = tqe_wait->tqe_data;
status = NU_SUCCESS;
}
}
else
{
tqe_wait = (tqe_t *)0;
#ifdef PLUS
NU_Release_Semaphore(&TCP_Resource);
#else /* !PLUS */
NU_Release_Resource(TCP_Resource);
#endif /* !PLUS */
continue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -