SCP: Fix asynchronous event queue updates without intrinsic instructions.
As discussed in #393
This commit is contained in:
parent
b41d10f189
commit
9d013e9b44
2 changed files with 38 additions and 38 deletions
68
scp.c
68
scp.c
|
@ -341,9 +341,9 @@ AIO_ILOCK;
|
|||
if (AIO_QUEUE_VAL != QUEUE_LIST_END) { /* List !Empty */
|
||||
UNIT *q, *uptr;
|
||||
int32 a_event_time;
|
||||
do
|
||||
do { /* Grab current queue */
|
||||
q = AIO_QUEUE_VAL;
|
||||
while (q != AIO_QUEUE_SET(QUEUE_LIST_END, q)); /* Grab current queue */
|
||||
} while (q != AIO_QUEUE_SET(QUEUE_LIST_END, q));
|
||||
while (q != QUEUE_LIST_END) { /* List !Empty */
|
||||
sim_debug (SIM_DBG_AIO_QUEUE, sim_dflt_dev, "Migrating Asynch event for %s after %d instructions\n", sim_uname(q), q->a_event_time);
|
||||
++migrated;
|
||||
|
@ -4524,46 +4524,46 @@ if (flag) {
|
|||
t_bool idle_capable;
|
||||
uint32 os_ms_sleep_1, os_tick_size;
|
||||
|
||||
fprintf (st, "\n\tSimulator Framework Capabilities:");
|
||||
fprintf (st, "\n\t\t%s", sim_si64);
|
||||
fprintf (st, "\n\t\t%s", sim_sa64);
|
||||
fprintf (st, "\n\t\t%s", eth_capabilities());
|
||||
fprintf (st, "\n Simulator Framework Capabilities:");
|
||||
fprintf (st, "\n %s", sim_si64);
|
||||
fprintf (st, "\n %s", sim_sa64);
|
||||
fprintf (st, "\n %s", eth_capabilities());
|
||||
idle_capable = sim_timer_idle_capable (&os_ms_sleep_1, &os_tick_size);
|
||||
fprintf (st, "\n\t\tIdle/Throttling support is %savailable", idle_capable ? "" : "NOT ");
|
||||
fprintf (st, "\n Idle/Throttling support is %savailable", idle_capable ? "" : "NOT ");
|
||||
if (sim_disk_vhd_support())
|
||||
fprintf (st, "\n\t\tVirtual Hard Disk (VHD) support");
|
||||
fprintf (st, "\n Virtual Hard Disk (VHD) support");
|
||||
if (sim_disk_raw_support())
|
||||
fprintf (st, "\n\t\tRAW disk and CD/DVD ROM support");
|
||||
fprintf (st, "\n RAW disk and CD/DVD ROM support");
|
||||
#if defined (SIM_ASYNCH_IO)
|
||||
fprintf (st, "\n\t\tAsynchronous I/O support");
|
||||
fprintf (st, "\n Asynchronous I/O support (%s)", AIO_QUEUE_MODE);
|
||||
#endif
|
||||
#if defined (SIM_ASYNCH_MUX)
|
||||
fprintf (st, "\n\t\tAsynchronous Multiplexer support");
|
||||
fprintf (st, "\n Asynchronous Multiplexer support");
|
||||
#endif
|
||||
#if defined (SIM_ASYNCH_CLOCKS)
|
||||
fprintf (st, "\n\t\tAsynchronous Clock support");
|
||||
fprintf (st, "\n Asynchronous Clock support");
|
||||
#endif
|
||||
#if defined (SIM_FRONTPANEL_VERSION)
|
||||
fprintf (st, "\n\t\tFrontPanel API Version %d", SIM_FRONTPANEL_VERSION);
|
||||
fprintf (st, "\n FrontPanel API Version %d", SIM_FRONTPANEL_VERSION);
|
||||
#endif
|
||||
fprintf (st, "\n\tHost Platform:");
|
||||
fprintf (st, "\n Host Platform:");
|
||||
#if defined (__GNUC__) && defined (__VERSION__)
|
||||
fprintf (st, "\n\t\tCompiler: GCC %s", __VERSION__);
|
||||
fprintf (st, "\n Compiler: GCC %s", __VERSION__);
|
||||
#elif defined (__clang_version__)
|
||||
fprintf (st, "\n\t\tCompiler: clang %s", __clang_version__);
|
||||
fprintf (st, "\n Compiler: clang %s", __clang_version__);
|
||||
#elif defined (_MSC_FULL_VER) && defined (_MSC_BUILD)
|
||||
fprintf (st, "\n\t\tCompiler: Microsoft Visual C++ %d.%02d.%05d.%02d", _MSC_FULL_VER/10000000, (_MSC_FULL_VER/100000)%100, _MSC_FULL_VER%100000, _MSC_BUILD);
|
||||
fprintf (st, "\n Compiler: Microsoft Visual C++ %d.%02d.%05d.%02d", _MSC_FULL_VER/10000000, (_MSC_FULL_VER/100000)%100, _MSC_FULL_VER%100000, _MSC_BUILD);
|
||||
#if defined(_DEBUG)
|
||||
build = " (Debug Build)";
|
||||
#else
|
||||
build = " (Release Build)";
|
||||
#endif
|
||||
#elif defined (__DECC_VER)
|
||||
fprintf (st, "\n\t\tCompiler: DEC C %c%d.%d-%03d", ("T SV")[((__DECC_VER/10000)%10)-6], __DECC_VER/10000000, (__DECC_VER/100000)%100, __DECC_VER%10000);
|
||||
fprintf (st, "\n Compiler: DEC C %c%d.%d-%03d", ("T SV")[((__DECC_VER/10000)%10)-6], __DECC_VER/10000000, (__DECC_VER/100000)%100, __DECC_VER%10000);
|
||||
#elif defined (SIM_COMPILER)
|
||||
#define S_xstr(a) S_str(a)
|
||||
#define S_str(a) #a
|
||||
fprintf (st, "\n\t\tCompiler: %s", S_xstr(SIM_COMPILER));
|
||||
fprintf (st, "\n Compiler: %s", S_xstr(SIM_COMPILER));
|
||||
#undef S_str
|
||||
#undef S_xstr
|
||||
#endif
|
||||
|
@ -4591,21 +4591,21 @@ if (flag) {
|
|||
#else
|
||||
cpp = "C";
|
||||
#endif
|
||||
fprintf (st, "\n\t\tSimulator Compiled as %s%s%s on %s at %s", cpp, arch, build, __DATE__, __TIME__);
|
||||
fprintf (st, "\n Simulator Compiled as %s%s%s on %s at %s", cpp, arch, build, __DATE__, __TIME__);
|
||||
#endif
|
||||
fprintf (st, "\n\t\tMemory Access: %s Endian", sim_end ? "Little" : "Big");
|
||||
fprintf (st, "\n\t\tMemory Pointer Size: %d bits", (int)sizeof(dptr)*8);
|
||||
fprintf (st, "\n\t\t%s", sim_toffset_64 ? "Large File (>2GB) support" : "No Large File support");
|
||||
fprintf (st, "\n\t\tSDL Video support: %s", vid_version());
|
||||
fprintf (st, "\n Memory Access: %s Endian", sim_end ? "Little" : "Big");
|
||||
fprintf (st, "\n Memory Pointer Size: %d bits", (int)sizeof(dptr)*8);
|
||||
fprintf (st, "\n %s", sim_toffset_64 ? "Large File (>2GB) support" : "No Large File support");
|
||||
fprintf (st, "\n SDL Video support: %s", vid_version());
|
||||
#if defined (HAVE_PCREPOSIX_H)
|
||||
fprintf (st, "\n\t\tPCRE RegEx support for EXPECT commands");
|
||||
fprintf (st, "\n PCRE RegEx support for EXPECT commands");
|
||||
#elif defined (HAVE_REGEX_H)
|
||||
fprintf (st, "\n\t\tRegEx support for EXPECT commands");
|
||||
fprintf (st, "\n RegEx support for EXPECT commands");
|
||||
#else
|
||||
fprintf (st, "\n\t\tNo RegEx support for EXPECT commands");
|
||||
fprintf (st, "\n No RegEx support for EXPECT commands");
|
||||
#endif
|
||||
fprintf (st, "\n\t\tOS clock resolution: %dms", os_tick_size);
|
||||
fprintf (st, "\n\t\tTime taken by msleep(1): %dms", os_ms_sleep_1);
|
||||
fprintf (st, "\n OS clock resolution: %dms", os_tick_size);
|
||||
fprintf (st, "\n Time taken by msleep(1): %dms", os_ms_sleep_1);
|
||||
#if defined(__VMS)
|
||||
if (1) {
|
||||
char *arch =
|
||||
|
@ -4616,7 +4616,7 @@ if (flag) {
|
|||
#else
|
||||
"VAX";
|
||||
#endif
|
||||
fprintf (st, "\n\t\tOS: OpenVMS %s %s", arch, __VMS_VERSION);
|
||||
fprintf (st, "\n OS: OpenVMS %s %s", arch, __VMS_VERSION);
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
if (1) {
|
||||
|
@ -4638,9 +4638,9 @@ if (flag) {
|
|||
} while (osversion[0] == '\0');
|
||||
_pclose (f);
|
||||
}
|
||||
fprintf (st, "\n\t\tOS: %s", osversion);
|
||||
fprintf (st, "\n\t\tArchitecture: %s%s%s, Processors: %s", arch, proc_arch3264 ? " on " : "", proc_arch3264 ? proc_arch3264 : "", procs);
|
||||
fprintf (st, "\n\t\tProcessor Id: %s, Level: %s, Revision: %s", proc_id ? proc_id : "", proc_level ? proc_level : "", proc_rev ? proc_rev : "");
|
||||
fprintf (st, "\n OS: %s", osversion);
|
||||
fprintf (st, "\n Architecture: %s%s%s, Processors: %s", arch, proc_arch3264 ? " on " : "", proc_arch3264 ? proc_arch3264 : "", procs);
|
||||
fprintf (st, "\n Processor Id: %s, Level: %s, Revision: %s", proc_id ? proc_id : "", proc_level ? proc_level : "", proc_rev ? proc_rev : "");
|
||||
}
|
||||
#else
|
||||
if (1) {
|
||||
|
@ -4656,7 +4656,7 @@ if (flag) {
|
|||
} while (osversion[0] == '\0');
|
||||
pclose (f);
|
||||
}
|
||||
fprintf (st, "\n\t\tOS: %s", osversion);
|
||||
fprintf (st, "\n OS: %s", osversion);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1050,7 +1050,7 @@ extern int32 sim_asynch_inst_latency;
|
|||
/* This approach uses intrinsics to manage access to the link list head */
|
||||
/* sim_asynch_queue. This implementation is a completely lock free design */
|
||||
/* which avoids the potential ABA issues. */
|
||||
#define AIO_QUEUE_MODE "Lock free asynchronous event queue access"
|
||||
#define AIO_QUEUE_MODE "Lock free asynchronous event queue"
|
||||
#define AIO_INIT \
|
||||
do { \
|
||||
int tmr; \
|
||||
|
@ -1082,7 +1082,7 @@ extern int32 sim_asynch_inst_latency;
|
|||
#define AIO_ILOCK AIO_LOCK
|
||||
#define AIO_IUNLOCK AIO_UNLOCK
|
||||
#define AIO_QUEUE_VAL (UNIT *)(InterlockedCompareExchangePointer((void * volatile *)&sim_asynch_queue, (void *)sim_asynch_queue, NULL))
|
||||
#define AIO_QUEUE_SET(val, queue) (UNIT *)(InterlockedCompareExchangePointer((void * volatile *)&sim_asynch_queue, (void *)val, queue))
|
||||
#define AIO_QUEUE_SET(newval, oldval) (UNIT *)(InterlockedCompareExchangePointer((void * volatile *)&sim_asynch_queue, (void *)newval, oldval))
|
||||
#define AIO_UPDATE_QUEUE sim_aio_update_queue ()
|
||||
#define AIO_ACTIVATE(caller, uptr, event_time) \
|
||||
if (!pthread_equal ( pthread_self(), sim_asynch_main_threadid )) { \
|
||||
|
@ -1093,7 +1093,7 @@ extern int32 sim_asynch_inst_latency;
|
|||
/* This approach uses a pthread mutex to manage access to the link list */
|
||||
/* head sim_asynch_queue. It will always work, but may be slower than the */
|
||||
/* lock free approach when using USE_AIO_INTRINSICS */
|
||||
#define AIO_QUEUE_MODE "Lock based asynchronous event queue access"
|
||||
#define AIO_QUEUE_MODE "Lock based asynchronous event queue"
|
||||
#define AIO_INIT \
|
||||
do { \
|
||||
int tmr; \
|
||||
|
@ -1123,7 +1123,7 @@ extern int32 sim_asynch_inst_latency;
|
|||
#define AIO_ILOCK AIO_LOCK
|
||||
#define AIO_IUNLOCK AIO_UNLOCK
|
||||
#define AIO_QUEUE_VAL sim_asynch_queue
|
||||
#define AIO_QUEUE_SET(val, queue) (sim_asynch_queue = val)
|
||||
#define AIO_QUEUE_SET(newval, oldval) ((sim_asynch_queue = newval),oldval)
|
||||
#define AIO_UPDATE_QUEUE sim_aio_update_queue ()
|
||||
#define AIO_ACTIVATE(caller, uptr, event_time) \
|
||||
if (!pthread_equal ( pthread_self(), sim_asynch_main_threadid )) { \
|
||||
|
|
Loading…
Add table
Reference in a new issue