diff --git a/BasiliskII/ChangeLog b/BasiliskII/ChangeLog index 8bb8f9fc..8f619123 100644 --- a/BasiliskII/ChangeLog +++ b/BasiliskII/ChangeLog @@ -1,6 +1,9 @@ V0.9 - - Unix: some performance improvements to VOSF screen update code [Brian J. Johnson] + - Unix: -Ofast option is supplied to MIPSPro compiler [Brian J. Johnson] + - Unix: workaround for IRIX pthreads bug in Delay_usec() + [Brian J. Johnson] V0.9 (snapshot) - 17.Feb.2001 - adapted for mon V3.0 which is now the required minimum diff --git a/BasiliskII/src/Unix/configure.in b/BasiliskII/src/Unix/configure.in index 67ca7e74..55264bb6 100644 --- a/BasiliskII/src/Unix/configure.in +++ b/BasiliskII/src/Unix/configure.in @@ -279,6 +279,16 @@ irix*) dnl IRIX headers work fine, but somehow don't define or use "STDC_HEADERS" DEFINES="$DEFINES -DCRTSCTS=CNEW_RTSCTS -DB230400=B115200 -DSTDC_HEADERS" LIBS="$LIBS -laudio" + + dnl Check if our compiler supports -Ofast (MIPSPro) + HAVE_OFAST=no + ocflags="$CFLAGS" + CFLAGS=`echo $CFLAGS | sed -e 's/ -g / -Ofast /;s/^-g /-Ofast /;s/-g$/ -Ofast/;s/^-g$/-Ofast/'` + AC_MSG_CHECKING(if "-Ofast" works) + dnl Do a test compile of an empty function + AC_TRY_COMPILE(,, [AC_MSG_RESULT(yes); HAVE_OFAST=yes], AC_MSG_RESULT(no)) + CFLAGS="$ocflags" + ;; esac @@ -666,6 +676,14 @@ if [[ "x$HAVE_GCC27" = "xyes" ]]; then CXXFLAGS=`echo $CXXFLAGS | sed -e 's/ -g / /;s/^-g / /;s/ -g$/ /;s/^-g$//'` fi +dnl Or if we have -Ofast +if [[ "x$HAVE_OFAST" = "xyes" ]]; then + CFLAGS=`echo $CFLAGS | sed -e 's/ -g / -Ofast /;s/^-g /-Ofast /;s/-g$/ -Ofast/;s/^-g$/-Ofast/'` + CXXFLAGS=`echo $CXXFLAGS | sed -e 's/ -g / -Ofast /;s/^-g /-Ofast/;s/ -g$/ -Ofast/;s/^-g$/-Ofast/'` + CXXFLAGS="-LANG:std $CXXFLAGS" + LDFLAGS="$LDFLAGS -Ofast" +fi + dnl Generate Makefile. AC_SUBST(DEFINES) AC_SUBST(SYSSRCS) diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index 7e765996..701bf7e9 100644 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -869,16 +869,26 @@ uint64 GetTicks_usec(void) // Linux select() changes its timeout parameter upon return to contain // the remaining time. Most other unixen leave it unchanged or undefined. #define SELECT_SETS_REMAINING -#elif defined(__FreeBSD__) || defined(__sun__) || defined(sgi) +#elif defined(__FreeBSD__) || defined(__sun__) #define USE_NANOSLEEP +#elif defined(HAVE_PTHREADS) && defined(sgi) +// SGI pthreads has a bug when using pthreads+signals+nanosleep, +// so instead of using nanosleep, wait on a CV which is never signalled. +#define USE_COND_TIMEDWAIT #endif void Delay_usec(uint32 usec) { int was_error; -#ifdef USE_NANOSLEEP +#if defined(USE_NANOSLEEP) struct timespec elapsed, tv; +#elif defined(USE_COND_TIMEDWAIT) + // Use a local mutex and cv, so threads remain independent + pthread_cond_t delay_cond = PTHREAD_COND_INITIALIZER; + pthread_mutex_t delay_mutex = PTHREAD_MUTEX_INITIALIZER; + struct timespec elapsed; + uint64 future; #else struct timeval tv; #ifndef SELECT_SETS_REMAINING @@ -887,22 +897,30 @@ void Delay_usec(uint32 usec) #endif // Set the timeout interval - Linux only needs to do this once -#ifdef SELECT_SETS_REMAINING +#if defined(SELECT_SETS_REMAINING) tv.tv_sec = 0; tv.tv_usec = usec; #elif defined(USE_NANOSLEEP) elapsed.tv_sec = 0; elapsed.tv_nsec = usec * 1000; +#elif defined(USE_COND_TIMEDWAIT) + future = GetTicks_usec() + usec; + elapsed.tv_sec = future / 1000000; + elapsed.tv_nsec = (future % 1000000) * 1000; #else then = GetTicks_usec(); #endif do { errno = 0; -#ifdef USE_NANOSLEEP +#if defined(USE_NANOSLEEP) tv.tv_sec = elapsed.tv_sec; tv.tv_nsec = elapsed.tv_nsec; was_error = nanosleep(&tv, &elapsed); +#elif defined(USE_COND_TIMEDWAIT) + was_error = pthread_mutex_lock(&delay_mutex); + was_error = pthread_cond_timedwait(&delay_cond, &delay_mutex, &elapsed); + was_error = pthread_mutex_unlock(&delay_mutex); #else #ifndef SELECT_SETS_REMAINING // Calculate the time interval left (in case of interrupt)