mirror of
https://github.com/simh/simh.git
synced 2026-01-11 23:52:58 +00:00
TMXR: Remove all SIM_ASYNCH_MUX dependent code
Asynchronous MUX functionality was added long ago and never completely tested and thus never completed and never actually used. All of what it was supposed to achieve was independently achieved when bit rate speed functionality was added.
This commit is contained in:
parent
a4360bc492
commit
a79c583053
10
scp.c
10
scp.c
@ -5952,7 +5952,6 @@ if (cptr && (*cptr != 0)) /* now eol? */
|
||||
if (flag == sim_asynch_enabled) /* already set correctly? */
|
||||
return SCPE_OK;
|
||||
sim_asynch_enabled = flag;
|
||||
tmxr_change_async ();
|
||||
sim_timer_change_asynch ();
|
||||
if (1) {
|
||||
uint32 i, j;
|
||||
@ -5991,9 +5990,6 @@ if (cptr && (*cptr != 0))
|
||||
return SCPE_2MARG;
|
||||
#ifdef SIM_ASYNCH_IO
|
||||
fprintf (st, "Asynchronous I/O is %sabled, %s\n", (sim_asynch_enabled) ? "en" : "dis", AIO_QUEUE_MODE);
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
fprintf (st, "Asynchronous Multiplexer support is available\n");
|
||||
#endif
|
||||
#if defined(SIM_ASYNCH_CLOCKS)
|
||||
fprintf (st, "Asynchronous Clock is %sabled\n", (sim_asynch_timer) ? "en" : "dis");
|
||||
#endif
|
||||
@ -6883,9 +6879,6 @@ if (flag) {
|
||||
#if defined (SIM_ASYNCH_IO)
|
||||
fprintf (st, "\n Asynchronous I/O support (%s)", AIO_QUEUE_MODE);
|
||||
#endif
|
||||
#if defined (SIM_ASYNCH_MUX)
|
||||
fprintf (st, "\n Asynchronous Multiplexer support");
|
||||
#endif
|
||||
#if defined (SIM_ASYNCH_CLOCKS)
|
||||
fprintf (st, "\n Asynchronous Clock support");
|
||||
#endif
|
||||
@ -12382,7 +12375,6 @@ do {
|
||||
}
|
||||
else
|
||||
sim_interval = noqueue_time = NOQUEUE_WAIT;
|
||||
AIO_EVENT_BEGIN(uptr);
|
||||
if (uptr->usecs_remaining) {
|
||||
sim_debug (SIM_DBG_EVENT, &sim_scp_dev, "Requeueing %s after %.0f usecs\n", sim_uname (uptr), uptr->usecs_remaining);
|
||||
reason = sim_timer_activate_after (uptr, uptr->usecs_remaining);
|
||||
@ -12394,7 +12386,6 @@ do {
|
||||
else
|
||||
reason = SCPE_OK;
|
||||
}
|
||||
AIO_EVENT_COMPLETE(uptr, reason);
|
||||
if (sim_interval_catchup < -1) {
|
||||
sim_interval_catchup += sim_clock_queue->time;
|
||||
sim_time += sim_clock_queue->time;
|
||||
@ -12599,7 +12590,6 @@ if ((uptr->cancel) && uptr->cancel (uptr))
|
||||
return SCPE_OK;
|
||||
if (uptr->dynflags & UNIT_TMR_UNIT)
|
||||
sim_timer_cancel (uptr);
|
||||
AIO_CANCEL(uptr);
|
||||
AIO_UPDATE_QUEUE;
|
||||
if (sim_clock_queue == QUEUE_LIST_END)
|
||||
return SCPE_OK;
|
||||
|
||||
123
sim_console.c
123
sim_console.c
@ -210,7 +210,6 @@ UNIT sim_con_units[2] = {{ UDATA (&sim_con_poll_svc, UNIT_ATTABLE, 0)}}; /* cons
|
||||
#define DBG_XMT TMXR_DBG_XMT /* display Transmitted Data */
|
||||
#define DBG_RCV TMXR_DBG_RCV /* display Received Data */
|
||||
#define DBG_RET TMXR_DBG_RET /* display Returned Received Data */
|
||||
#define DBG_ASY TMXR_DBG_ASY /* asynchronous thread activity */
|
||||
#define DBG_CON TMXR_DBG_CON /* display connection activity */
|
||||
#define DBG_EXP 0x00000001 /* Expect match activity */
|
||||
#define DBG_SND 0x00000002 /* Send (Inject) data activity */
|
||||
@ -220,7 +219,6 @@ static DEBTAB sim_con_debug[] = {
|
||||
{"XMT", DBG_XMT, "Transmitted Data"},
|
||||
{"RCV", DBG_RCV, "Received Data"},
|
||||
{"RET", DBG_RET, "Returned Received Data"},
|
||||
{"ASY", DBG_ASY, "asynchronous activity"},
|
||||
{"CON", DBG_CON, "connection activity"},
|
||||
{"EXP", DBG_EXP, "Expect match activity"},
|
||||
{"SND", DBG_SND, "Send (Inject) data activity"},
|
||||
@ -3154,86 +3152,6 @@ return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
#if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX)
|
||||
extern pthread_mutex_t sim_tmxr_poll_lock;
|
||||
extern pthread_cond_t sim_tmxr_poll_cond;
|
||||
extern int32 sim_tmxr_poll_count;
|
||||
extern t_bool sim_tmxr_poll_running;
|
||||
|
||||
pthread_t sim_console_poll_thread; /* Keyboard Polling Thread Id */
|
||||
t_bool sim_console_poll_running = FALSE;
|
||||
pthread_cond_t sim_console_startup_cond;
|
||||
|
||||
static void *
|
||||
_console_poll(void *arg)
|
||||
{
|
||||
int wait_count = 0;
|
||||
DEVICE *d;
|
||||
|
||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||
thread which, in general, won't be readily yielding the processor when
|
||||
this thread needs to run */
|
||||
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
sim_debug (DBG_ASY, &sim_con_telnet, "_console_poll() - starting\n");
|
||||
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
pthread_cond_signal (&sim_console_startup_cond); /* Signal we're ready to go */
|
||||
while (sim_asynch_enabled) {
|
||||
|
||||
if (!sim_is_running) {
|
||||
if (wait_count) {
|
||||
sim_debug (DBG_ASY, d, "_console_poll() - Removing interest in %s. Other interest: %d\n", d->name, sim_con_ldsc.uptr->a_poll_waiter_count);
|
||||
--sim_con_ldsc.uptr->a_poll_waiter_count;
|
||||
--sim_tmxr_poll_count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we started something, let it finish before polling again */
|
||||
if (wait_count) {
|
||||
sim_debug (DBG_ASY, &sim_con_telnet, "_console_poll() - waiting for %d units\n", wait_count);
|
||||
pthread_cond_wait (&sim_tmxr_poll_cond, &sim_tmxr_poll_lock);
|
||||
sim_debug (DBG_ASY, &sim_con_telnet, "_console_poll() - continuing with after wait\n");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
wait_count = 0;
|
||||
if (sim_os_poll_kbd_ready (1000)) {
|
||||
sim_debug (DBG_ASY, &sim_con_telnet, "_console_poll() - Keyboard Data available\n");
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
++wait_count;
|
||||
if (!sim_con_ldsc.uptr->a_polling_now) {
|
||||
sim_con_ldsc.uptr->a_polling_now = TRUE;
|
||||
sim_con_ldsc.uptr->a_poll_waiter_count = 1;
|
||||
d = find_dev_from_unit(sim_con_ldsc.uptr);
|
||||
sim_debug (DBG_ASY, &sim_con_telnet, "_console_poll() - Activating %s\n", d->name);
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
_sim_activate (sim_con_ldsc.uptr, 0);
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
}
|
||||
else {
|
||||
d = find_dev_from_unit(sim_con_ldsc.uptr);
|
||||
sim_debug (DBG_ASY, &sim_con_telnet, "_console_poll() - Already Activated %s %d times\n", d->name, sim_con_ldsc.uptr->a_poll_waiter_count);
|
||||
++sim_con_ldsc.uptr->a_poll_waiter_count;
|
||||
}
|
||||
}
|
||||
else
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
|
||||
sim_tmxr_poll_count += wait_count;
|
||||
}
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
|
||||
sim_debug (DBG_ASY, &sim_con_telnet, "_console_poll() - exiting\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif /* defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX) */
|
||||
|
||||
|
||||
t_stat sim_ttinit (void)
|
||||
{
|
||||
sim_con_tmxr.ldsc->mp = &sim_con_tmxr;
|
||||
@ -3244,52 +3162,13 @@ return sim_os_ttinit ();
|
||||
|
||||
t_stat sim_ttrun (void)
|
||||
{
|
||||
if (!sim_con_tmxr.ldsc->uptr) { /* If simulator didn't declare its input polling unit */
|
||||
if (!sim_con_tmxr.ldsc->uptr) /* If simulator didn't declare its input polling unit */
|
||||
sim_con_unit.dynflags &= ~UNIT_TM_POLL; /* we can't poll asynchronously */
|
||||
sim_con_unit.dynflags |= TMUF_NOASYNCH; /* disable asynchronous behavior */
|
||||
}
|
||||
else {
|
||||
#if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX)
|
||||
if (sim_asynch_enabled) {
|
||||
sim_con_tmxr.ldsc->uptr->dynflags |= UNIT_TM_POLL;/* flag console input device as a polling unit */
|
||||
sim_con_unit.dynflags |= UNIT_TM_POLL; /* flag as polling unit */
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX)
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
if (sim_asynch_enabled) {
|
||||
pthread_attr_t attr;
|
||||
|
||||
pthread_cond_init (&sim_console_startup_cond, NULL);
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
|
||||
pthread_create (&sim_console_poll_thread, &attr, _console_poll, NULL);
|
||||
pthread_attr_destroy( &attr);
|
||||
pthread_cond_wait (&sim_console_startup_cond, &sim_tmxr_poll_lock); /* Wait for thread to stabilize */
|
||||
pthread_cond_destroy (&sim_console_startup_cond);
|
||||
sim_console_poll_running = TRUE;
|
||||
}
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
#endif
|
||||
tmxr_start_poll ();
|
||||
return sim_os_ttrun ();
|
||||
}
|
||||
|
||||
t_stat sim_ttcmd (void)
|
||||
{
|
||||
#if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX)
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
if (sim_console_poll_running) {
|
||||
pthread_cond_signal (&sim_tmxr_poll_cond);
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
pthread_join (sim_console_poll_thread, NULL);
|
||||
sim_console_poll_running = FALSE;
|
||||
}
|
||||
else
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
#endif
|
||||
tmxr_stop_poll ();
|
||||
return sim_os_ttcmd ();
|
||||
}
|
||||
|
||||
|
||||
41
sim_defs.h
41
sim_defs.h
@ -616,11 +616,6 @@ struct UNIT {
|
||||
UNIT *a_next; /* next asynch active */
|
||||
int32 a_event_time;
|
||||
ACTIVATE_API a_activate_call;
|
||||
/* Asynchronous Polling control */
|
||||
/* These fields should only be referenced when holding the sim_tmxr_poll_lock */
|
||||
t_bool a_polling_now; /* polling active flag */
|
||||
int32 a_poll_waiter_count; /* count of polling threads */
|
||||
/* waiting for this unit */
|
||||
/* Asynchronous Timer control */
|
||||
double a_due_time; /* due time for timer event */
|
||||
double a_due_gtime; /* due time (in instructions) for timer event */
|
||||
@ -670,7 +665,7 @@ struct UNIT {
|
||||
/* These flags are only set dynamically */
|
||||
|
||||
#define UNIT_ATTMULT 0000001 /* Allow multiple attach commands */
|
||||
#define UNIT_TM_POLL 0000002 /* TMXR Polling unit */
|
||||
#define UNIT_TM_POLL 0000002 /* TMXR Polling unit (connect, transmit or receive) */
|
||||
#define UNIT_NO_FIO 0000004 /* fileref is NOT a FILE * */
|
||||
#define UNIT_DISK_CHK 0000010 /* disk data debug checking (sim_disk) */
|
||||
#define UNIT_TMR_UNIT 0000200 /* Unit registered as a calibrated timer */
|
||||
@ -916,7 +911,7 @@ struct MEMFILE {
|
||||
|
||||
#ifdef SIM_ASYNCH_IO
|
||||
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0,NULL,NULL,0,0,NULL,NULL,NULL,0,0,0,NULL,0,NULL,NULL,0,NULL,\
|
||||
NULL,NULL,NULL,0,NULL,0,0,0,0,0
|
||||
NULL,NULL,NULL,0,NULL,0,0,0
|
||||
#else
|
||||
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0,NULL,NULL,0,0,NULL,NULL,NULL,0,0,0,NULL,0,NULL,NULL,0,NULL
|
||||
#endif
|
||||
@ -1220,35 +1215,6 @@ extern int32 sim_asynch_inst_latency;
|
||||
#define AIO_UNLOCK \
|
||||
pthread_mutex_unlock(&sim_asynch_lock)
|
||||
#define AIO_IS_ACTIVE(uptr) (((uptr)->a_is_active ? (uptr)->a_is_active (uptr) : FALSE) || ((uptr)->a_next))
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
#define AIO_CANCEL(uptr) \
|
||||
if (((uptr)->dynflags & UNIT_TM_POLL) && \
|
||||
!((uptr)->next) && !((uptr)->a_next)) { \
|
||||
(uptr)->a_polling_now = FALSE; \
|
||||
sim_tmxr_poll_count -= (uptr)->a_poll_waiter_count; \
|
||||
(uptr)->a_poll_waiter_count = 0; \
|
||||
}
|
||||
#endif /* defined(SIM_ASYNCH_MUX) */
|
||||
#if !defined(AIO_CANCEL)
|
||||
#define AIO_CANCEL(uptr)
|
||||
#endif /* !defined(AIO_CANCEL) */
|
||||
#define AIO_EVENT_BEGIN(uptr) \
|
||||
do { \
|
||||
int __was_poll = uptr->dynflags & UNIT_TM_POLL
|
||||
#define AIO_EVENT_COMPLETE(uptr, reason) \
|
||||
if (__was_poll) { \
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock); \
|
||||
uptr->a_polling_now = FALSE; \
|
||||
if (uptr->a_poll_waiter_count) { \
|
||||
sim_tmxr_poll_count -= uptr->a_poll_waiter_count; \
|
||||
uptr->a_poll_waiter_count = 0; \
|
||||
if (0 == sim_tmxr_poll_count) \
|
||||
pthread_cond_broadcast (&sim_tmxr_poll_cond); \
|
||||
} \
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock); \
|
||||
} \
|
||||
AIO_UPDATE_QUEUE; \
|
||||
} while (0)
|
||||
|
||||
#if defined(__DECC_VER)
|
||||
#include <builtins>
|
||||
@ -1388,10 +1354,7 @@ extern int32 sim_asynch_inst_latency;
|
||||
#define AIO_LOCK
|
||||
#define AIO_UNLOCK
|
||||
#define AIO_CLEANUP
|
||||
#define AIO_EVENT_BEGIN(uptr)
|
||||
#define AIO_EVENT_COMPLETE(uptr, reason)
|
||||
#define AIO_IS_ACTIVE(uptr) FALSE
|
||||
#define AIO_CANCEL(uptr)
|
||||
#define AIO_SET_INTERRUPT_LATENCY(instpersec)
|
||||
#define AIO_TLS
|
||||
#endif /* SIM_ASYNCH_IO */
|
||||
|
||||
633
sim_tmxr.c
633
sim_tmxr.c
@ -1087,9 +1087,6 @@ if (mp->last_poll_time == 0) { /* first poll initializa
|
||||
if (mp->poll_interval == 0) /* Assure reasonable polling interval */
|
||||
mp->poll_interval = TMXR_DEFAULT_CONNECT_POLL_INTERVAL;
|
||||
|
||||
if (!(uptr->dynflags & TMUF_NOASYNCH)) /* if asynch not disabled */
|
||||
sim_cancel (uptr);
|
||||
|
||||
for (i=0; i < mp->lines; i++) {
|
||||
if (mp->ldsc[i].uptr) {
|
||||
mp->ldsc[i].uptr->tmxr = (void *)mp; /* Connect UNIT to TMXR */
|
||||
@ -1103,12 +1100,6 @@ if (mp->last_poll_time == 0) { /* first poll initializa
|
||||
}
|
||||
else
|
||||
mp->ldsc[i].o_uptr = uptr; /* default line output polling to primary poll unit */
|
||||
if (!(mp->uptr->dynflags & TMUF_NOASYNCH)) { /* if asynch not disabled */
|
||||
if (mp->ldsc[i].uptr)
|
||||
sim_cancel (mp->ldsc[i].uptr);
|
||||
if (mp->ldsc[i].o_uptr)
|
||||
sim_cancel (mp->ldsc[i].o_uptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2585,13 +2576,6 @@ for (i = 0; i < mp->lines; i++) { /* loop thru lines */
|
||||
continue;
|
||||
nbytes = tmxr_send_buffered_data (lp); /* buffered bytes */
|
||||
if (nbytes == 0) { /* buf empty? enab line */
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
UNIT *ruptr = lp->uptr ? lp->uptr : lp->mp->uptr;
|
||||
if ((ruptr->dynflags & UNIT_TM_POLL) &&
|
||||
sim_asynch_enabled &&
|
||||
tmxr_rqln (lp))
|
||||
_sim_activate (ruptr, 0);
|
||||
#endif
|
||||
if ((lp->xmte == 0) &&
|
||||
((lp->txbps == 0) ||
|
||||
(lp->txnexttime <= sim_gtime_now)))
|
||||
@ -3720,568 +3704,11 @@ return SCPE_OK;
|
||||
static TMXR **tmxr_open_devices = NULL;
|
||||
static int tmxr_open_device_count = 0;
|
||||
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
pthread_t sim_tmxr_poll_thread; /* Polling Thread Id */
|
||||
#if defined(_WIN32) || defined(VMS)
|
||||
pthread_t sim_tmxr_serial_poll_thread; /* Serial Polling Thread Id */
|
||||
pthread_cond_t sim_tmxr_serial_startup_cond;
|
||||
#endif
|
||||
pthread_mutex_t sim_tmxr_poll_lock;
|
||||
pthread_cond_t sim_tmxr_poll_cond;
|
||||
pthread_cond_t sim_tmxr_startup_cond;
|
||||
int32 sim_tmxr_poll_count = 0;
|
||||
t_bool sim_tmxr_poll_running = FALSE;
|
||||
|
||||
static void *
|
||||
_tmxr_poll(void *arg)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int timeout_usec;
|
||||
DEVICE *dptr = tmxr_open_devices[0]->dptr;
|
||||
UNIT **units = NULL;
|
||||
UNIT **activated = NULL;
|
||||
SOCKET *sockets = NULL;
|
||||
int wait_count = 0;
|
||||
|
||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||
thread which, in general, won't be readily yielding the processor when
|
||||
this thread needs to run */
|
||||
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_poll() - starting\n");
|
||||
|
||||
units = (UNIT **)calloc(FD_SETSIZE, sizeof(*units));
|
||||
activated = (UNIT **)calloc(FD_SETSIZE, sizeof(*activated));
|
||||
sockets = (SOCKET *)calloc(FD_SETSIZE, sizeof(*sockets));
|
||||
timeout_usec = 1000000;
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
pthread_cond_signal (&sim_tmxr_startup_cond); /* Signal we're ready to go */
|
||||
while (sim_asynch_enabled) {
|
||||
int i, j, status, select_errno;
|
||||
fd_set readfds, errorfds;
|
||||
int socket_count;
|
||||
SOCKET max_socket_fd;
|
||||
TMXR *mp;
|
||||
DEVICE *d;
|
||||
|
||||
if ((tmxr_open_device_count == 0) || (!sim_is_running)) {
|
||||
for (j=0; j<wait_count; ++j) {
|
||||
d = find_dev_from_unit(activated[j]);
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_poll() - Removing interest in %s. Other interest: %d\n", sim_uname(activated[j]), activated[j]->a_poll_waiter_count);
|
||||
--activated[j]->a_poll_waiter_count;
|
||||
--sim_tmxr_poll_count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* If we started something we should wait for, let it finish before polling again */
|
||||
if (wait_count) {
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_poll() - waiting for %d units\n", wait_count);
|
||||
pthread_cond_wait (&sim_tmxr_poll_cond, &sim_tmxr_poll_lock);
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_poll() - continuing with timeout of %dms\n", timeout_usec/1000);
|
||||
}
|
||||
FD_ZERO (&readfds);
|
||||
FD_ZERO (&errorfds);
|
||||
for (i=max_socket_fd=socket_count=0; i<tmxr_open_device_count; ++i) {
|
||||
mp = tmxr_open_devices[i];
|
||||
if ((mp->master) && (mp->uptr->dynflags&UNIT_TM_POLL)) {
|
||||
units[socket_count] = mp->uptr;
|
||||
sockets[socket_count] = mp->master;
|
||||
FD_SET (mp->master, &readfds);
|
||||
FD_SET (mp->master, &errorfds);
|
||||
if (mp->master > max_socket_fd)
|
||||
max_socket_fd = mp->master;
|
||||
++socket_count;
|
||||
}
|
||||
for (j=0; j<mp->lines; ++j) {
|
||||
if (mp->ldsc[j].sock) {
|
||||
units[socket_count] = mp->ldsc[j].uptr;
|
||||
if (units[socket_count] == NULL)
|
||||
units[socket_count] = mp->uptr;
|
||||
sockets[socket_count] = mp->ldsc[j].sock;
|
||||
FD_SET (mp->ldsc[j].sock, &readfds);
|
||||
FD_SET (mp->ldsc[j].sock, &errorfds);
|
||||
if (mp->ldsc[j].sock > max_socket_fd)
|
||||
max_socket_fd = mp->ldsc[j].sock;
|
||||
++socket_count;
|
||||
}
|
||||
#if !defined(_WIN32) && !defined(VMS)
|
||||
if (mp->ldsc[j].serport) {
|
||||
units[socket_count] = mp->ldsc[j].uptr;
|
||||
if (units[socket_count] == NULL)
|
||||
units[socket_count] = mp->uptr;
|
||||
sockets[socket_count] = mp->ldsc[j].serport;
|
||||
FD_SET (mp->ldsc[j].serport, &readfds);
|
||||
FD_SET (mp->ldsc[j].serport, &errorfds);
|
||||
if (mp->ldsc[j].serport > max_socket_fd)
|
||||
max_socket_fd = mp->ldsc[j].serport;
|
||||
++socket_count;
|
||||
}
|
||||
#endif
|
||||
if (mp->ldsc[j].connecting) {
|
||||
units[socket_count] = mp->uptr;
|
||||
sockets[socket_count] = mp->ldsc[j].connecting;
|
||||
FD_SET (mp->ldsc[j].connecting, &readfds);
|
||||
FD_SET (mp->ldsc[j].connecting, &errorfds);
|
||||
if (mp->ldsc[j].connecting > max_socket_fd)
|
||||
max_socket_fd = mp->ldsc[j].connecting;
|
||||
++socket_count;
|
||||
}
|
||||
if (mp->ldsc[j].master) {
|
||||
units[socket_count] = mp->uptr;
|
||||
sockets[socket_count] = mp->ldsc[j].master;
|
||||
FD_SET (mp->ldsc[j].master, &readfds);
|
||||
FD_SET (mp->ldsc[j].master, &errorfds);
|
||||
if (mp->ldsc[j].master > max_socket_fd)
|
||||
max_socket_fd = mp->ldsc[j].master;
|
||||
++socket_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
if (timeout_usec > 1000000)
|
||||
timeout_usec = 1000000;
|
||||
timeout.tv_sec = timeout_usec/1000000;
|
||||
timeout.tv_usec = timeout_usec%1000000;
|
||||
select_errno = 0;
|
||||
if (socket_count == 0) {
|
||||
sim_os_ms_sleep (timeout_usec/1000);
|
||||
status = 0;
|
||||
}
|
||||
else
|
||||
status = select (1+(int)max_socket_fd, &readfds, NULL, &errorfds, &timeout);
|
||||
select_errno = errno;
|
||||
wait_count=0;
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
switch (status) {
|
||||
case 0: /* timeout */
|
||||
for (i=max_socket_fd=socket_count=0; i<tmxr_open_device_count; ++i) {
|
||||
mp = tmxr_open_devices[i];
|
||||
if (mp->master) {
|
||||
if (!mp->uptr->a_polling_now) {
|
||||
mp->uptr->a_polling_now = TRUE;
|
||||
mp->uptr->a_poll_waiter_count = 0;
|
||||
d = find_dev_from_unit(mp->uptr);
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_poll() - Activating %s to poll connect\n", sim_uname(mp->uptr));
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
_sim_activate (mp->uptr, 0);
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
}
|
||||
if (mp->txcount) {
|
||||
timeout_usec = 10000; /* Wait 10ms next time (this gets doubled below) */
|
||||
mp->txcount = 0;
|
||||
}
|
||||
}
|
||||
for (j=0; j<mp->lines; ++j) {
|
||||
if ((mp->ldsc[j].conn) && (mp->ldsc[j].uptr)) {
|
||||
if (tmxr_tqln(&mp->ldsc[j]) || tmxr_rqln (&mp->ldsc[j])) {
|
||||
timeout_usec = 10000; /* Wait 10ms next time (this gets doubled below) */
|
||||
/* More than one socket can be associated with the
|
||||
same unit. Make sure to only activate it one time */
|
||||
if (!mp->ldsc[j].uptr->a_polling_now) {
|
||||
mp->ldsc[j].uptr->a_polling_now = TRUE;
|
||||
mp->ldsc[j].uptr->a_poll_waiter_count = 0;
|
||||
d = find_dev_from_unit(mp->ldsc[j].uptr);
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_poll() - Line %d Activating %s to poll data: %d/%d\n",
|
||||
j, sim_uname(mp->ldsc[j].uptr), tmxr_tqln(&mp->ldsc[j]), tmxr_rqln (&mp->ldsc[j]));
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
_sim_activate (mp->ldsc[j].uptr, 0);
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_poll() - Poll Timeout - %dms\n", timeout_usec/1000);
|
||||
timeout_usec *= 2; /* Double timeout time */
|
||||
break;
|
||||
case SOCKET_ERROR:
|
||||
wait_count = 0;
|
||||
if (select_errno == EINTR)
|
||||
break;
|
||||
sim_printf ("select() returned -1, errno=%d - %s\r\n", select_errno, strerror(select_errno));
|
||||
SIM_SCP_ABORT ("");
|
||||
break;
|
||||
default:
|
||||
wait_count = 0;
|
||||
for (i=0; i<socket_count; ++i) {
|
||||
if (FD_ISSET(sockets[i], &readfds) ||
|
||||
FD_ISSET(sockets[i], &errorfds)) {
|
||||
/* More than one socket can be associated with the
|
||||
same unit. Only activate one time */
|
||||
for (j=0; j<wait_count; ++j)
|
||||
if (activated[j] == units[i])
|
||||
break;
|
||||
if (j == wait_count) {
|
||||
activated[j] = units[i];
|
||||
++wait_count;
|
||||
if (!activated[j]->a_polling_now) {
|
||||
activated[j]->a_polling_now = TRUE;
|
||||
activated[j]->a_poll_waiter_count = 1;
|
||||
d = find_dev_from_unit(activated[j]);
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_poll() - Activating for data %s\n", sim_uname(activated[j]));
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
_sim_activate (activated[j], 0);
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
}
|
||||
else {
|
||||
d = find_dev_from_unit(activated[j]);
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_poll() - Already Activated %s%d %d times\n", sim_uname(activated[j]), activated[j]->a_poll_waiter_count);
|
||||
++activated[j]->a_poll_waiter_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wait_count)
|
||||
timeout_usec = 10000; /* Wait 10ms next time */
|
||||
break;
|
||||
}
|
||||
sim_tmxr_poll_count += wait_count;
|
||||
}
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
free(units);
|
||||
free(activated);
|
||||
free(sockets);
|
||||
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_poll() - exiting\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
static void *
|
||||
_tmxr_serial_poll(void *arg)
|
||||
{
|
||||
int timeout_usec;
|
||||
DEVICE *dptr = tmxr_open_devices[0]->dptr;
|
||||
UNIT **units = NULL;
|
||||
UNIT **activated = NULL;
|
||||
SERHANDLE *serports = NULL;
|
||||
int wait_count = 0;
|
||||
|
||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||
thread which, in general, won't be readily yielding the processor when
|
||||
this thread needs to run */
|
||||
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_poll() - starting\n");
|
||||
|
||||
units = (UNIT **)calloc(MAXIMUM_WAIT_OBJECTS, sizeof(*units));
|
||||
activated = (UNIT **)calloc(MAXIMUM_WAIT_OBJECTS, sizeof(*activated));
|
||||
serports = (SERHANDLE *)calloc(MAXIMUM_WAIT_OBJECTS, sizeof(*serports));
|
||||
timeout_usec = 1000000;
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
pthread_cond_signal (&sim_tmxr_serial_startup_cond); /* Signal we're ready to go */
|
||||
while (sim_asynch_enabled) {
|
||||
int i, j;
|
||||
DWORD status;
|
||||
int serport_count;
|
||||
TMXR *mp;
|
||||
DEVICE *d;
|
||||
|
||||
if ((tmxr_open_device_count == 0) || (!sim_is_running)) {
|
||||
for (j=0; j<wait_count; ++j) {
|
||||
d = find_dev_from_unit(activated[j]);
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_serial_poll() - Removing interest in %s. Other interest: %d\n", sim_uname(activated[j]), activated[j]->a_poll_waiter_count);
|
||||
--activated[j]->a_poll_waiter_count;
|
||||
--sim_tmxr_poll_count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* If we started something we should wait for, let it finish before polling again */
|
||||
if (wait_count) {
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_poll() - waiting for %d units\n", wait_count);
|
||||
pthread_cond_wait (&sim_tmxr_poll_cond, &sim_tmxr_poll_lock);
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_poll() - continuing with timeout of %dms\n", timeout_usec/1000);
|
||||
}
|
||||
for (i=serport_count=0; i<tmxr_open_device_count; ++i) {
|
||||
mp = tmxr_open_devices[i];
|
||||
for (j=0; j<mp->lines; ++j) {
|
||||
if (mp->ldsc[j].serport) {
|
||||
units[serport_count] = mp->ldsc[j].uptr;
|
||||
if (units[serport_count] == NULL)
|
||||
units[serport_count] = mp->uptr;
|
||||
serports[serport_count] = mp->ldsc[j].serport;
|
||||
++serport_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (serport_count == 0) /* No open serial ports? */
|
||||
break; /* We're done */
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
if (timeout_usec > 1000000)
|
||||
timeout_usec = 1000000;
|
||||
status = WaitForMultipleObjects (serport_count, serports, FALSE, timeout_usec/1000);
|
||||
wait_count=0;
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
switch (status) {
|
||||
case WAIT_FAILED:
|
||||
sim_printf ("WaitForMultipleObjects() Failed, LastError=%d\r\n", GetLastError());
|
||||
SIM_SCP_ABORT ("");
|
||||
break;
|
||||
case WAIT_TIMEOUT:
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_poll() - Poll Timeout - %dms\n", timeout_usec/1000);
|
||||
timeout_usec *= 2; /* Double timeout time */
|
||||
break;
|
||||
default:
|
||||
i = status - WAIT_OBJECT_0;
|
||||
wait_count = 0;
|
||||
j = wait_count;
|
||||
activated[j] = units[i];
|
||||
++wait_count;
|
||||
if (!activated[j]->a_polling_now) {
|
||||
activated[j]->a_polling_now = TRUE;
|
||||
activated[j]->a_poll_waiter_count = 1;
|
||||
d = find_dev_from_unit(activated[j]);
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_serial_poll() - Activating for data %s\n", sim_uname(activated[j]));
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
_sim_activate (activated[j], 0);
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
}
|
||||
else {
|
||||
d = find_dev_from_unit(activated[j]);
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_serial_poll() - Already Activated %s%d %d times\n", sim_uname(activated[j]), activated[j]->a_poll_waiter_count);
|
||||
++activated[j]->a_poll_waiter_count;
|
||||
}
|
||||
if (wait_count)
|
||||
timeout_usec = 10000; /* Wait 10ms next time */
|
||||
break;
|
||||
}
|
||||
sim_tmxr_poll_count += wait_count;
|
||||
}
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
free(units);
|
||||
free(activated);
|
||||
free(serports);
|
||||
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_poll() - exiting\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if defined(VMS)
|
||||
|
||||
#include <descrip.h>
|
||||
#include <ttdef.h>
|
||||
#include <tt2def.h>
|
||||
#include <iodef.h>
|
||||
#include <ssdef.h>
|
||||
#include <starlet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned short status;
|
||||
unsigned short count;
|
||||
unsigned int dev_status; } IOSB;
|
||||
|
||||
#define MAXIMUM_WAIT_OBJECTS 64 /* Number of possible concurrently opened serial ports */
|
||||
|
||||
pthread_cond_t sim_serial_line_startup_cond;
|
||||
|
||||
|
||||
static void *
|
||||
_tmxr_serial_line_poll(void *arg)
|
||||
{
|
||||
TMLN *lp = (TMLN *)arg;
|
||||
DEVICE *dptr = tmxr_open_devices[0]->dptr;
|
||||
UNIT *uptr = (lp->uptr ? lp->uptr : lp->mp->uptr);
|
||||
DEVICE *d = find_dev_from_unit(uptr);
|
||||
int wait_count = 0;
|
||||
|
||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||
thread which, in general, won't be readily yielding the processor when
|
||||
this thread needs to run */
|
||||
sim_os_set_thread_priority (PRIORITY_ABOVE_NORMAL);
|
||||
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_line_poll() - starting\n");
|
||||
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
pthread_cond_signal (&sim_serial_line_startup_cond); /* Signal we're ready to go */
|
||||
while (sim_asynch_enabled) {
|
||||
int i, j;
|
||||
int serport_count;
|
||||
TMXR *mp = lp->mp;
|
||||
unsigned int status, term[2];
|
||||
unsigned char buf[4];
|
||||
IOSB iosb;
|
||||
|
||||
if ((tmxr_open_device_count == 0) || (!sim_is_running)) {
|
||||
if (wait_count) {
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_serial_line_poll() - Removing interest in %s. Other interest: %d\n", sim_uname(uptr), uptr->a_poll_waiter_count);
|
||||
--uptr->a_poll_waiter_count;
|
||||
--sim_tmxr_poll_count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* If we started something we should wait for, let it finish before polling again */
|
||||
if (wait_count) {
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_line_poll() - waiting for %d units\n", wait_count);
|
||||
pthread_cond_wait (&sim_tmxr_poll_cond, &sim_tmxr_poll_lock);
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_line_poll() - continuing with timeout of 1 sec\n");
|
||||
}
|
||||
lp->a_active = TRUE;
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
term[0] = term[1] = 0;
|
||||
status = sys$qiow (0, lp->serport,
|
||||
IO$_READLBLK | IO$M_NOECHO | IO$M_NOFILTR | IO$M_TIMED | IO$M_TRMNOECHO,
|
||||
&iosb, 0, 0, buf, 1, 1, term, 0, 0);
|
||||
if (status != SS$_NORMAL) {
|
||||
sim_printf ("_tmxr_serial_line_poll() - QIO Failed, Status=%d\r\n", status);
|
||||
SIM_SCP_ABORT ("");
|
||||
}
|
||||
wait_count = 0;
|
||||
sys$synch (0, &iosb);
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
lp->a_active = FALSE;
|
||||
if (iosb.count == 1) {
|
||||
lp->a_buffered_character = buf[0] | SCPE_KFLAG;
|
||||
wait_count = 1;
|
||||
if (!uptr->a_polling_now) {
|
||||
uptr->a_polling_now = TRUE;
|
||||
uptr->a_poll_waiter_count = 1;
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_serial_line_poll() - Activating for data %s\n", sim_uname(uptr));
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
_sim_activate (uptr, 0);
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
}
|
||||
else {
|
||||
sim_debug (TMXR_DBG_ASY, d, "_tmxr_serial_line_poll() - Already Activated %s%d %d times\n", sim_uname(uptr), uptr->a_poll_waiter_count);
|
||||
++uptr->a_poll_waiter_count;
|
||||
}
|
||||
}
|
||||
sim_tmxr_poll_count += wait_count;
|
||||
}
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_line_poll() - exiting\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
_tmxr_serial_poll(void *arg)
|
||||
{
|
||||
int timeout_usec;
|
||||
DEVICE *dptr = tmxr_open_devices[0]->dptr;
|
||||
TMLN **lines = NULL;
|
||||
pthread_t *threads = NULL;
|
||||
|
||||
/* Boost Priority for this I/O thread vs the CPU instruction execution
|
||||
thread which, in general, won't be readily yielding the processor when
|
||||
this thread needs to run */
|
||||
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_poll() - starting\n");
|
||||
|
||||
lines = (TMLN **)calloc(MAXIMUM_WAIT_OBJECTS, sizeof(*lines));
|
||||
threads = (pthread_t *)calloc(MAXIMUM_WAIT_OBJECTS, sizeof(*threads));
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
pthread_cond_signal (&sim_tmxr_serial_startup_cond); /* Signal we're ready to go */
|
||||
pthread_cond_init (&sim_serial_line_startup_cond, NULL);
|
||||
while (sim_asynch_enabled) {
|
||||
pthread_attr_t attr;
|
||||
int i, j;
|
||||
int serport_count;
|
||||
TMXR *mp;
|
||||
DEVICE *d;
|
||||
|
||||
if ((tmxr_open_device_count == 0) || (!sim_is_running))
|
||||
break;
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
|
||||
for (i=serport_count=0; i<tmxr_open_device_count; ++i) {
|
||||
mp = tmxr_open_devices[i];
|
||||
for (j=0; j<mp->lines; ++j) {
|
||||
if (mp->ldsc[j].serport) {
|
||||
lines[serport_count] = &mp->ldsc[j];
|
||||
pthread_create (&threads[serport_count], &attr, _tmxr_serial_line_poll, (void *)&mp->ldsc[j]);
|
||||
pthread_cond_wait (&sim_serial_line_startup_cond, &sim_tmxr_poll_lock); /* Wait for thread to stabilize */
|
||||
++serport_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_attr_destroy( &attr);
|
||||
if (serport_count == 0) /* No open serial ports? */
|
||||
break; /* We're done */
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
for (i=0; i<serport_count; i++)
|
||||
pthread_join (threads[i], NULL);
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
}
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
pthread_cond_destroy (&sim_serial_line_startup_cond);
|
||||
free(lines);
|
||||
free(threads);
|
||||
|
||||
sim_debug (TMXR_DBG_ASY, dptr, "_tmxr_serial_poll() - exiting\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* VMS */
|
||||
|
||||
#endif /* defined(SIM_ASYNCH_MUX) */
|
||||
|
||||
t_stat tmxr_start_poll (void)
|
||||
{
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
if ((tmxr_open_device_count > 0) &&
|
||||
sim_asynch_enabled &&
|
||||
sim_is_running &&
|
||||
!sim_tmxr_poll_running) {
|
||||
pthread_attr_t attr;
|
||||
|
||||
pthread_cond_init (&sim_tmxr_startup_cond, NULL);
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
|
||||
pthread_create (&sim_tmxr_poll_thread, &attr, _tmxr_poll, NULL);
|
||||
pthread_attr_destroy( &attr);
|
||||
pthread_cond_wait (&sim_tmxr_startup_cond, &sim_tmxr_poll_lock); /* Wait for thread to stabilize */
|
||||
pthread_cond_destroy (&sim_tmxr_startup_cond);
|
||||
sim_tmxr_poll_running = TRUE;
|
||||
}
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
#endif
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat tmxr_stop_poll (void)
|
||||
{
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
if (sim_tmxr_poll_running) {
|
||||
pthread_cond_signal (&sim_tmxr_poll_cond);
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
pthread_join (sim_tmxr_poll_thread, NULL);
|
||||
sim_tmxr_poll_running = FALSE;
|
||||
/* Transitioning from asynch mode so kick all polling units onto the event queue */
|
||||
if (tmxr_open_device_count) {
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<tmxr_open_device_count; ++i) {
|
||||
TMXR *mp = tmxr_open_devices[i];
|
||||
|
||||
if (mp->uptr)
|
||||
_sim_activate (mp->uptr, 0);
|
||||
for (j = 0; j < mp->lines; ++j)
|
||||
if (mp->ldsc[j].uptr)
|
||||
_sim_activate (mp->ldsc[j].uptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
#endif
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static void tmxr_add_to_open_list (TMXR* mux)
|
||||
{
|
||||
int i;
|
||||
t_bool found = FALSE;
|
||||
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
#endif
|
||||
for (i=0; i<tmxr_open_device_count; ++i)
|
||||
if (tmxr_open_devices[i] == mux) {
|
||||
found = TRUE;
|
||||
@ -4293,21 +3720,12 @@ if (!found) {
|
||||
for (i=0; i<mux->lines; i++)
|
||||
mux->ldsc[i].send.after = mux->ldsc[i].send.delay = 0;
|
||||
}
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
if ((tmxr_open_device_count == 1) && (sim_asynch_enabled))
|
||||
tmxr_start_poll ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _tmxr_remove_from_open_list (TMXR* mux)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
tmxr_stop_poll ();
|
||||
pthread_mutex_lock (&sim_tmxr_poll_lock);
|
||||
#endif
|
||||
for (i=0; i<tmxr_open_device_count; ++i)
|
||||
if (tmxr_open_devices[i] == mux) {
|
||||
for (j=i+1; j<tmxr_open_device_count; ++j)
|
||||
@ -4315,9 +3733,6 @@ for (i=0; i<tmxr_open_device_count; ++i)
|
||||
--tmxr_open_device_count;
|
||||
break;
|
||||
}
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
pthread_mutex_unlock (&sim_tmxr_poll_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static t_stat _tmxr_locate_line_send_expect (const char *cptr, TMLN **lp, SEND **snd, EXPECT **exp)
|
||||
@ -4402,24 +3817,12 @@ else
|
||||
return _tmxr_send_expect_line_name (NULL, exp);
|
||||
}
|
||||
|
||||
t_stat tmxr_change_async (void)
|
||||
{
|
||||
#if defined(SIM_ASYNCH_IO)
|
||||
if (sim_asynch_enabled)
|
||||
tmxr_start_poll ();
|
||||
else
|
||||
tmxr_stop_poll ();
|
||||
#endif
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static DEBTAB tmxr_debug[] = {
|
||||
{"XMT", TMXR_DBG_XMT, "Transmit Data"},
|
||||
{"RCV", TMXR_DBG_RCV, "Received Data"},
|
||||
{"RET", TMXR_DBG_RET, "Returned Received Data"},
|
||||
{"MODEM", TMXR_DBG_MDM, "Modem Signals"},
|
||||
{"CONNECT", TMXR_DBG_CON, "Connection Activities"},
|
||||
{"ASYNC", TMXR_DBG_ASY, "Asynchronous Activities"},
|
||||
{"TRACE", TMXR_DBG_TRC, "trace routine calls"},
|
||||
{"XMTPKT", TMXR_DBG_PXMT, "Transmit Packet Data"},
|
||||
{"RCVPKT", TMXR_DBG_PRCV, "Received Packet Data"},
|
||||
@ -4437,7 +3840,7 @@ return sim_add_debug_flags (dptr, tmxr_debug);
|
||||
|
||||
/* Attach unit to master socket */
|
||||
|
||||
t_stat tmxr_attach_ex (TMXR *mp, UNIT *uptr, CONST char *cptr, t_bool async)
|
||||
t_stat tmxr_attach (TMXR *mp, UNIT *uptr, CONST char *cptr)
|
||||
{
|
||||
t_stat r;
|
||||
int32 i;
|
||||
@ -4461,12 +3864,6 @@ if ((mp->lines > 1) ||
|
||||
(mp->ldsc[0].serport == 0)))
|
||||
uptr->dynflags = uptr->dynflags | UNIT_ATTMULT; /* allow multiple attach commands */
|
||||
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
if (!async || (uptr->flags & TMUF_NOASYNCH)) /* if asynch disabled */
|
||||
uptr->dynflags |= TMUF_NOASYNCH; /* tag as no asynch */
|
||||
#else
|
||||
uptr->dynflags |= TMUF_NOASYNCH; /* tag as no asynch */
|
||||
#endif
|
||||
uptr->dynflags |= UNIT_TM_POLL; /* tag as polling unit */
|
||||
if (mp->dptr) {
|
||||
for (i=0; i<mp->lines; i++) {
|
||||
@ -4759,7 +4156,7 @@ uptr->filename = NULL;
|
||||
uptr->tmxr = NULL;
|
||||
mp->last_poll_time = 0;
|
||||
uptr->flags &= ~(UNIT_ATT); /* not attached */
|
||||
uptr->dynflags &= ~(UNIT_TM_POLL|TMUF_NOASYNCH); /* no polling, not asynch disabled */
|
||||
uptr->dynflags &= ~UNIT_TM_POLL; /* no polling */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@ -4822,17 +4219,8 @@ if (sooner != interval) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate() - scheduling %s after %d instructions rather than %d instructions\n", sim_uname (uptr), sooner, interval);
|
||||
return _sim_activate (uptr, sooner); /* Handle the busy case */
|
||||
}
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
if (!sim_asynch_enabled) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate() - scheduling %s after %d instructions\n", sim_uname (uptr), interval);
|
||||
return _sim_activate (uptr, interval);
|
||||
}
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate() - scheduling %s asynchronously instead of %d instructions\n", sim_uname (uptr), interval);
|
||||
return SCPE_OK;
|
||||
#else
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate() - scheduling %s after %d instructions\n", sim_uname (uptr), interval);
|
||||
return _sim_activate (uptr, interval);
|
||||
#endif
|
||||
}
|
||||
|
||||
t_stat tmxr_activate_abs (UNIT *uptr, int32 interval)
|
||||
@ -4859,17 +4247,8 @@ if (sooner != 0x7FFFFFFF) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s after %d instructions rather than %u usecs\n", sim_uname (uptr), sooner, usecs_walltime);
|
||||
return _sim_activate (uptr, sooner); /* Handle the busy case directly */
|
||||
}
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
if (!sim_asynch_enabled) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s after %u usecs\n", sim_uname (uptr), usecs_walltime);
|
||||
return _sim_activate_after (uptr, (double)usecs_walltime);
|
||||
}
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s asynchronously instead of %u usecs\n", sim_uname (uptr), usecs_walltime);
|
||||
return SCPE_OK;
|
||||
#else
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s after %.0f usecs\n", sim_uname (uptr), (double)usecs_walltime);
|
||||
return _sim_activate_after (uptr, (double)usecs_walltime);
|
||||
#endif
|
||||
}
|
||||
|
||||
t_stat tmxr_activate_after_abs (UNIT *uptr, uint32 usecs_walltime)
|
||||
@ -4906,16 +4285,8 @@ if (sooner != interval) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_clock_coschedule_tmr(tmr=%d) - scheduling %s after %d instructions rather than %d ticks (%d instructions)\n", tmr, sim_uname (uptr), sooner, ticks, interval);
|
||||
return _sim_activate (uptr, sooner); /* Handle the busy case directly */
|
||||
}
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
if (!sim_asynch_enabled) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_clock_coschedule_tmr(tmr=%d) - coscheduling %s after interval %d ticks\n", tmr, sim_uname (uptr), ticks);
|
||||
return sim_clock_coschedule (uptr, tmr, ticks);
|
||||
}
|
||||
return SCPE_OK;
|
||||
#else
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_clock_coschedule_tmr(tmr=%d) - coscheduling %s after interval %d ticks\n", tmr, sim_uname (uptr), ticks);
|
||||
return sim_clock_coschedule_tmr (uptr, tmr, ticks);
|
||||
#endif
|
||||
}
|
||||
|
||||
t_stat tmxr_clock_coschedule_tmr_abs (UNIT *uptr, int32 tmr, int32 ticks)
|
||||
|
||||
24
sim_tmxr.h
24
sim_tmxr.h
@ -72,7 +72,7 @@ typedef struct SERPORT *SERHANDLE;
|
||||
#define TMXR_DBG_MDM 0x00800000 /* Debug Modem Signals */
|
||||
#define TMXR_DBG_CFG 0x01000000 /* Debug Line Configuration Activities */
|
||||
#define TMXR_DBG_CON 0x02000000 /* Debug Connection Activities */
|
||||
#define TMXR_DBG_ASY 0x04000000 /* Debug Asynchronous Activities */
|
||||
#define TMXR_DBG_ASY 0x04000000 /* Debug Asynchronous Activities - unused */
|
||||
#define TMXR_DBG_TRC 0x08000000 /* Debug trace routine calls */
|
||||
#define TMXR_DBG_PXMT 0x10000000 /* Debug Transmit Packet Data */
|
||||
#define TMXR_DBG_PRCV 0x20000000 /* Debug Received Packet Data */
|
||||
@ -90,13 +90,6 @@ typedef struct SERPORT *SERHANDLE;
|
||||
#define TMXR_MDM_INCOMING (TMXR_MDM_DCD|TMXR_MDM_RNG|TMXR_MDM_CTS|TMXR_MDM_DSR) /* Settable Modem Bits */
|
||||
#define TMXR_MDM_OUTGOING (TMXR_MDM_DTR|TMXR_MDM_RTS) /* Settable Modem Bits */
|
||||
|
||||
/* Unit flags */
|
||||
|
||||
#define TMUF_V_NOASYNCH (UNIT_V_UF + 12) /* Asynch Disabled unit */
|
||||
#define TMUF_NOASYNCH (1u << TMUF_V_NOASYNCH) /* This flag can be defined */
|
||||
/* statically in a unit's flag field */
|
||||
/* This will disable the unit from */
|
||||
/* supporting asynchronmous mux behaviors */
|
||||
/* Receive line speed limits */
|
||||
|
||||
#define TMLN_SPD_50_BPS 200000 /* usec per character */
|
||||
@ -258,7 +251,8 @@ int32 tmxr_send_buffered_data (TMLN *lp);
|
||||
t_stat tmxr_open_master (TMXR *mp, CONST char *cptr);
|
||||
t_stat tmxr_close_master (TMXR *mp);
|
||||
t_stat tmxr_connection_poll_interval (TMXR *mp, uint32 seconds);
|
||||
t_stat tmxr_attach_ex (TMXR *mp, UNIT *uptr, CONST char *cptr, t_bool async);
|
||||
t_stat tmxr_attach (TMXR *mp, UNIT *uptr, CONST char *cptr);
|
||||
#define tmxr_attach_ex(mp, uptr, cptr, async) tmxr_attach (mp, uptr, cptr)
|
||||
t_stat tmxr_detach (TMXR *mp, UNIT *uptr);
|
||||
t_stat tmxr_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
char *tmxr_line_attach_string(TMLN *lp);
|
||||
@ -317,7 +311,6 @@ t_stat tmxr_clock_coschedule (UNIT *uptr, int32 interval);
|
||||
t_stat tmxr_clock_coschedule_abs (UNIT *uptr, int32 interval);
|
||||
t_stat tmxr_clock_coschedule_tmr (UNIT *uptr, int32 tmr, int32 ticks);
|
||||
t_stat tmxr_clock_coschedule_tmr_abs (UNIT *uptr, int32 tmr, int32 ticks);
|
||||
t_stat tmxr_change_async (void);
|
||||
t_stat tmxr_locate_line_send (const char *dev_line, SEND **snd);
|
||||
t_stat tmxr_locate_line_expect (const char *dev_line, EXPECT **exp);
|
||||
t_stat tmxr_locate_line (const char *dev_line, TMLN **lp);
|
||||
@ -326,8 +319,6 @@ const char *tmxr_expect_line_name (const EXPECT *exp);
|
||||
t_stat tmxr_startup (void);
|
||||
t_stat tmxr_shutdown (void);
|
||||
t_stat tmxr_sock_test (DEVICE *dptr, const char *cptr);
|
||||
t_stat tmxr_start_poll (void);
|
||||
t_stat tmxr_stop_poll (void);
|
||||
/* Framer support. These are a NOP if called on a non-framer line. */
|
||||
void tmxr_start_framer (TMLN *line, int dmc_mode);
|
||||
void tmxr_stop_framer (TMLN *line);
|
||||
@ -342,15 +333,6 @@ void _tmxr_debug (uint32 dbits, TMLN *lp, const char *msg, char *buf, int bufsiz
|
||||
#define tmxr_debug_connect_line(lp, msg) do {if (sim_deb && (lp)->mp && (lp)->mp->dptr && (TMXR_DBG_CON & (lp)->mp->dptr->dctrl)) sim_debug (TMXR_DBG_CON, (lp)->mp->dptr, "Ln%d:%s\n", (int)((lp)-(lp)->mp->ldsc), (msg)); } while (0)
|
||||
t_stat tmxr_add_debug (DEVICE *dptr);
|
||||
|
||||
#if defined(SIM_ASYNCH_MUX) && !defined(SIM_ASYNCH_IO)
|
||||
#undef SIM_ASYNCH_MUX
|
||||
#endif /* defined(SIM_ASYNCH_MUX) && !defined(SIM_ASYNCH_IO) */
|
||||
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
#define tmxr_attach(mp, uptr, cptr) tmxr_attach_ex(mp, uptr, cptr, TRUE)
|
||||
#else
|
||||
#define tmxr_attach(mp, uptr, cptr) tmxr_attach_ex(mp, uptr, cptr, FALSE)
|
||||
#endif
|
||||
#if (!defined(NOT_MUX_USING_CODE))
|
||||
#define sim_activate tmxr_activate
|
||||
#define sim_activate_abs tmxr_activate_abs
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user