SCP: Fix asynchronous event queue updates without intrinsic instructions.

As discussed in #393
This commit is contained in:
Mark Pizzolato 2017-03-09 07:55:21 -08:00
parent b41d10f189
commit 9d013e9b44
2 changed files with 38 additions and 38 deletions

68
scp.c
View file

@ -341,9 +341,9 @@ AIO_ILOCK;
if (AIO_QUEUE_VAL != QUEUE_LIST_END) { /* List !Empty */ if (AIO_QUEUE_VAL != QUEUE_LIST_END) { /* List !Empty */
UNIT *q, *uptr; UNIT *q, *uptr;
int32 a_event_time; int32 a_event_time;
do do { /* Grab current queue */
q = AIO_QUEUE_VAL; 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 */ 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); 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; ++migrated;
@ -4524,46 +4524,46 @@ if (flag) {
t_bool idle_capable; t_bool idle_capable;
uint32 os_ms_sleep_1, os_tick_size; uint32 os_ms_sleep_1, os_tick_size;
fprintf (st, "\n\tSimulator Framework Capabilities:"); fprintf (st, "\n Simulator Framework Capabilities:");
fprintf (st, "\n\t\t%s", sim_si64); fprintf (st, "\n %s", sim_si64);
fprintf (st, "\n\t\t%s", sim_sa64); fprintf (st, "\n %s", sim_sa64);
fprintf (st, "\n\t\t%s", eth_capabilities()); fprintf (st, "\n %s", eth_capabilities());
idle_capable = sim_timer_idle_capable (&os_ms_sleep_1, &os_tick_size); 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()) 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()) 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) #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 #endif
#if defined (SIM_ASYNCH_MUX) #if defined (SIM_ASYNCH_MUX)
fprintf (st, "\n\t\tAsynchronous Multiplexer support"); fprintf (st, "\n Asynchronous Multiplexer support");
#endif #endif
#if defined (SIM_ASYNCH_CLOCKS) #if defined (SIM_ASYNCH_CLOCKS)
fprintf (st, "\n\t\tAsynchronous Clock support"); fprintf (st, "\n Asynchronous Clock support");
#endif #endif
#if defined (SIM_FRONTPANEL_VERSION) #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 #endif
fprintf (st, "\n\tHost Platform:"); fprintf (st, "\n Host Platform:");
#if defined (__GNUC__) && defined (__VERSION__) #if defined (__GNUC__) && defined (__VERSION__)
fprintf (st, "\n\t\tCompiler: GCC %s", __VERSION__); fprintf (st, "\n Compiler: GCC %s", __VERSION__);
#elif defined (__clang_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) #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) #if defined(_DEBUG)
build = " (Debug Build)"; build = " (Debug Build)";
#else #else
build = " (Release Build)"; build = " (Release Build)";
#endif #endif
#elif defined (__DECC_VER) #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) #elif defined (SIM_COMPILER)
#define S_xstr(a) S_str(a) #define S_xstr(a) S_str(a)
#define S_str(a) #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_str
#undef S_xstr #undef S_xstr
#endif #endif
@ -4591,21 +4591,21 @@ if (flag) {
#else #else
cpp = "C"; cpp = "C";
#endif #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 #endif
fprintf (st, "\n\t\tMemory Access: %s Endian", sim_end ? "Little" : "Big"); fprintf (st, "\n Memory Access: %s Endian", sim_end ? "Little" : "Big");
fprintf (st, "\n\t\tMemory Pointer Size: %d bits", (int)sizeof(dptr)*8); fprintf (st, "\n Memory 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 %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 SDL Video support: %s", vid_version());
#if defined (HAVE_PCREPOSIX_H) #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) #elif defined (HAVE_REGEX_H)
fprintf (st, "\n\t\tRegEx support for EXPECT commands"); fprintf (st, "\n RegEx support for EXPECT commands");
#else #else
fprintf (st, "\n\t\tNo RegEx support for EXPECT commands"); fprintf (st, "\n No RegEx support for EXPECT commands");
#endif #endif
fprintf (st, "\n\t\tOS clock resolution: %dms", os_tick_size); fprintf (st, "\n OS clock resolution: %dms", os_tick_size);
fprintf (st, "\n\t\tTime taken by msleep(1): %dms", os_ms_sleep_1); fprintf (st, "\n Time taken by msleep(1): %dms", os_ms_sleep_1);
#if defined(__VMS) #if defined(__VMS)
if (1) { if (1) {
char *arch = char *arch =
@ -4616,7 +4616,7 @@ if (flag) {
#else #else
"VAX"; "VAX";
#endif #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) #elif defined(_WIN32)
if (1) { if (1) {
@ -4638,9 +4638,9 @@ if (flag) {
} while (osversion[0] == '\0'); } while (osversion[0] == '\0');
_pclose (f); _pclose (f);
} }
fprintf (st, "\n\t\tOS: %s", osversion); fprintf (st, "\n OS: %s", osversion);
fprintf (st, "\n\t\tArchitecture: %s%s%s, Processors: %s", arch, proc_arch3264 ? " on " : "", proc_arch3264 ? proc_arch3264 : "", procs); fprintf (st, "\n Architecture: %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 Processor Id: %s, Level: %s, Revision: %s", proc_id ? proc_id : "", proc_level ? proc_level : "", proc_rev ? proc_rev : "");
} }
#else #else
if (1) { if (1) {
@ -4656,7 +4656,7 @@ if (flag) {
} while (osversion[0] == '\0'); } while (osversion[0] == '\0');
pclose (f); pclose (f);
} }
fprintf (st, "\n\t\tOS: %s", osversion); fprintf (st, "\n OS: %s", osversion);
} }
#endif #endif
} }

View file

@ -1050,7 +1050,7 @@ extern int32 sim_asynch_inst_latency;
/* This approach uses intrinsics to manage access to the link list head */ /* This approach uses intrinsics to manage access to the link list head */
/* sim_asynch_queue. This implementation is a completely lock free design */ /* sim_asynch_queue. This implementation is a completely lock free design */
/* which avoids the potential ABA issues. */ /* 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 \ #define AIO_INIT \
do { \ do { \
int tmr; \ int tmr; \
@ -1082,7 +1082,7 @@ extern int32 sim_asynch_inst_latency;
#define AIO_ILOCK AIO_LOCK #define AIO_ILOCK AIO_LOCK
#define AIO_IUNLOCK AIO_UNLOCK #define AIO_IUNLOCK AIO_UNLOCK
#define AIO_QUEUE_VAL (UNIT *)(InterlockedCompareExchangePointer((void * volatile *)&sim_asynch_queue, (void *)sim_asynch_queue, NULL)) #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_UPDATE_QUEUE sim_aio_update_queue ()
#define AIO_ACTIVATE(caller, uptr, event_time) \ #define AIO_ACTIVATE(caller, uptr, event_time) \
if (!pthread_equal ( pthread_self(), sim_asynch_main_threadid )) { \ 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 */ /* 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 */ /* head sim_asynch_queue. It will always work, but may be slower than the */
/* lock free approach when using USE_AIO_INTRINSICS */ /* 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 \ #define AIO_INIT \
do { \ do { \
int tmr; \ int tmr; \
@ -1123,7 +1123,7 @@ extern int32 sim_asynch_inst_latency;
#define AIO_ILOCK AIO_LOCK #define AIO_ILOCK AIO_LOCK
#define AIO_IUNLOCK AIO_UNLOCK #define AIO_IUNLOCK AIO_UNLOCK
#define AIO_QUEUE_VAL sim_asynch_queue #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_UPDATE_QUEUE sim_aio_update_queue ()
#define AIO_ACTIVATE(caller, uptr, event_time) \ #define AIO_ACTIVATE(caller, uptr, event_time) \
if (!pthread_equal ( pthread_self(), sim_asynch_main_threadid )) { \ if (!pthread_equal ( pthread_self(), sim_asynch_main_threadid )) { \