From: Brian J. J. <br...@fr...> - 2001-03-23 18:54:17
|
OK, hopefully this is the last of the patches for IRIX for a while (at least until I get around to writing an OpenGL video driver or optimizing the condition code handling in UAE CPU.) The patch to configure.in tests for the "-Ofast" option to the compiler, and uses it instead of "-g" if it exists. This turns on massive optimizations in the MIPSPro compilers, which do a pretty good job with the UAE CPU, video blitters, etc. The patch to main_unix.c uses pthread_cond_timedwait() instead of nanosleep() to work around a bug in SGI's pthreads library. With this fix, the annoying hangs I was experiencing (especially on uniprocessor machines) are gone. I've only enabled it for SGI platforms, but it should work with any pthreads implementation. Feel free to remove anything under "#ifdef DEBUG_SLEEP" if you don't like debugging code clogging up the official sources. With these changes, BasiliskII configures, builds, and runs very well on IRIX with no special hand-holding, hacks, or manual edits. Whew.... Except for one thing: the recent changes to configure.in to select among different FPU cores don't work for the "default" core on non-X86 systems. Perhaps step 1 under "Select appropriate FPU source" needs a non-X68 case which selects the UAE CPU. If I specify "--enable-fpe=uae" on the configure command line, it works fine. Anyway, here are the patches, and thanks again for a way-cool, portable (and actually useful!) emulator. -- Brian J. Johnson -------------------------------------------------------------------- "I have discovered that all human evil comes from this, man's being unable to sit still in a room." -- Blaise Pascal Index: main_unix.cpp =================================================================== RCS file: /cvs/BasiliskII/src/Unix/main_unix.cpp,v retrieving revision 1.30 diff -c -r1.30 main_unix.cpp *** main_unix.cpp 2001/02/02 20:52:57 1.30 --- main_unix.cpp 2001/03/23 18:09:40 *************** *** 869,891 **** // 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) #define USE_NANOSLEEP #endif void Delay_usec(uint32 usec) { int was_error; ! #ifdef USE_NANOSLEEP struct timespec elapsed, tv; #else struct timeval tv; #ifndef SELECT_SETS_REMAINING uint64 then, now, elapsed; #endif #endif // Set the timeout interval - Linux only needs to do this once #ifdef SELECT_SETS_REMAINING tv.tv_sec = 0; --- 869,912 ---- // 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__) #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 + #ifdef DEBUG_SLEEP + int sleeps = 0; + int early = 0; + #endif + void Delay_usec(uint32 usec) { int was_error; ! #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 uint64 then, now, elapsed; #endif #endif + #ifdef DEBUG_SLEEP + uint64 stop, end; + sleeps++; + stop = GetTicks_usec() + usec; // expected stop time + #endif + // Set the timeout interval - Linux only needs to do this once #ifdef SELECT_SETS_REMAINING tv.tv_sec = 0; *************** *** 893,898 **** --- 914,928 ---- #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; + #if defined(DEBUG_SLEEP) || 1 + if (usec > 1000000) { + printf(" delay for %u nsec\n", usec); + } + #endif #else then = GetTicks_usec(); #endif *************** *** 903,908 **** --- 933,965 ---- 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); + #ifdef DEBUG_SLEEP + if (was_error) { + // Just for debugging + printf("ERROR: pthread_mutex_lock error %d\n", was_error); + exit(1); + } + #endif + was_error = pthread_cond_timedwait(&delay_cond, + &delay_mutex, &elapsed); + #ifdef DEBUG_SLEEP + if (was_error != ETIMEDOUT) { + // Just for debugging + printf("ERROR: pthread_cond_timedwait error %d\n", was_error); + exit(1); + } + #endif + + was_error = pthread_mutex_unlock(&delay_mutex); + #ifdef DEBUG_SLEEP + if (was_error) { + // Just for debugging + printf("ERROR: pthread_mutex_unlock error %d\n", was_error); + exit(1); + } + #endif #else #ifndef SELECT_SETS_REMAINING // Calculate the time interval left (in case of interrupt) *************** *** 918,923 **** --- 975,988 ---- was_error = select(0, NULL, NULL, NULL, &tv); #endif } while (was_error && (errno == EINTR)); + + #ifdef DEBUG_SLEEP + end = GetTicks_usec(); // actual stop time + if (end < stop) { // we woke up early + printf("woke up %ld out of %u usec too early\n", stop - end, usec); + early++; + } + #endif } Index: configure.in =================================================================== RCS file: /cvs/BasiliskII/src/Unix/configure.in,v retrieving revision 1.35 diff -c -r1.35 configure.in *** configure.in 2001/03/20 18:05:35 1.35 --- configure.in 2001/03/23 18:09:40 *************** *** 279,284 **** --- 279,293 ---- 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 *************** *** 662,667 **** --- 671,684 ---- dnl gb-- Probably not the cleanest way to take CFLAGS=`echo $CFLAGS | sed -e 's/ -g / /;s/^-g / /;s/ -g$/ /;s/^-g$//'` 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. |