diff --git a/BasiliskII/ChangeLog b/BasiliskII/ChangeLog index 26bf8f05..81c56df8 100644 --- a/BasiliskII/ChangeLog +++ b/BasiliskII/ChangeLog @@ -1,6 +1,7 @@ V1.0 (snapshot) - - fixed the problem with Ticks getting incremented on every interrupt, not just 60Hz (e.g. moving the mouse made the caret blink faster) + - Unix: cleaned up pthread attributes [Brian Johnson] V1.0 (snapshot) - 15.Jan.2002 - added support for on-the-fly video resolution and depth switching, and diff --git a/BasiliskII/src/Unix/Irix/audio_irix.cpp b/BasiliskII/src/Unix/Irix/audio_irix.cpp index 64b20eff..991ae34b 100644 --- a/BasiliskII/src/Unix/Irix/audio_irix.cpp +++ b/BasiliskII/src/Unix/Irix/audio_irix.cpp @@ -182,16 +182,7 @@ void AudioInit(void) sem_inited = true; // Start streaming thread - pthread_attr_init(&stream_thread_attr); -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - if (geteuid() == 0) { - pthread_attr_setinheritsched(&stream_thread_attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(&stream_thread_attr, SCHED_FIFO); - struct sched_param fifo_param; - fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2; - pthread_attr_setschedparam(&stream_thread_attr, &fifo_param); - } -#endif + Set_pthread_attr(&stream_thread_attr, 0); stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); // Everything OK diff --git a/BasiliskII/src/Unix/Solaris/audio_solaris.cpp b/BasiliskII/src/Unix/Solaris/audio_solaris.cpp index c638a4ab..d1efe458 100644 --- a/BasiliskII/src/Unix/Solaris/audio_solaris.cpp +++ b/BasiliskII/src/Unix/Solaris/audio_solaris.cpp @@ -115,14 +115,7 @@ void AudioInit(void) sound_buffer_size = (AudioStatus.sample_size>>3) * AudioStatus.channels * audio_frames_per_block; // Start audio thread - pthread_attr_init(&stream_thread_attr); -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - pthread_attr_setinheritsched(&stream_thread_attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(&stream_thread_attr, SCHED_FIFO); - struct sched_param fifo_param; - fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2; - pthread_attr_setschedparam(&stream_thread_attr, &fifo_param); -#endif + Set_pthread_attr(&stream_thread_attr, 0); stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); // Everything OK diff --git a/BasiliskII/src/Unix/audio_oss_esd.cpp b/BasiliskII/src/Unix/audio_oss_esd.cpp index 6b4cd723..092aa86f 100644 --- a/BasiliskII/src/Unix/audio_oss_esd.cpp +++ b/BasiliskII/src/Unix/audio_oss_esd.cpp @@ -267,17 +267,7 @@ dev_opened: set_audio_status_format(); // Start streaming thread - pthread_attr_init(&stream_thread_attr); -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - if (geteuid() == 0) { - pthread_attr_setinheritsched(&stream_thread_attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(&stream_thread_attr, SCHED_FIFO); - struct sched_param fifo_param; - fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2; - pthread_attr_setschedparam(&stream_thread_attr, &fifo_param); - } -#endif - stream_thread_cancel = false; + Set_pthread_attr(&stream_thread_attr, 0); stream_thread_active = (pthread_create(&stream_thread, &stream_thread_attr, stream_func, NULL) == 0); // Everything went fine diff --git a/BasiliskII/src/Unix/configure.in b/BasiliskII/src/Unix/configure.in index 30a49ce2..f2ab150e 100644 --- a/BasiliskII/src/Unix/configure.in +++ b/BasiliskII/src/Unix/configure.in @@ -129,6 +129,8 @@ if [[ "x$HAVE_PTHREADS" = "xyes" ]]; then AC_DEFINE(HAVE_PTHREADS) fi AC_CHECK_FUNCS(pthread_cancel) +AC_CHECK_FUNCS(pthread_mutexattr_setprotocol) +AC_CHECK_FUNCS(pthread_mutexattr_settype) dnl If POSIX.4 semaphores are not available, we emulate them with pthread mutexes. SEMSRC= @@ -671,9 +673,11 @@ AC_EGREP_CPP(yes, ], [AC_MSG_RESULT(yes); HAVE_GCC30=yes], AC_MSG_RESULT(no)) dnl Set "-fomit-frame-pointer" on i386 GCC 2.7 or higher. +dnl Also set "-fno-exceptions" for C++ because exception handling requires +dnl the frame pointer. if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_I386" = "xyes" ]]; then CFLAGS="$CFLAGS -fomit-frame-pointer" - CXXFLAGS="$CXXFLAGS -fomit-frame-pointer" + CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -fno-exceptions" fi dnl (gb) Do not merge constants since it breaks fpu/fpu_x86.cpp. diff --git a/BasiliskII/src/Unix/ether_unix.cpp b/BasiliskII/src/Unix/ether_unix.cpp index 06c34d34..ace1f23f 100644 --- a/BasiliskII/src/Unix/ether_unix.cpp +++ b/BasiliskII/src/Unix/ether_unix.cpp @@ -79,17 +79,7 @@ static bool start_thread(void) return false; } - pthread_attr_init(ðer_thread_attr); -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - if (geteuid() == 0) { - pthread_attr_setinheritsched(ðer_thread_attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(ðer_thread_attr, SCHED_FIFO); - struct sched_param fifo_param; - fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2 + 1; - pthread_attr_setschedparam(ðer_thread_attr, &fifo_param); - } -#endif - + Set_pthread_attr(ðer_thread_attr, 1); thread_active = (pthread_create(ðer_thread, ðer_thread_attr, receive_func, NULL) == 0); if (!thread_active) { printf("WARNING: Cannot start Ethernet thread"); diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index 8b25d66c..f204ce2e 100644 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -488,16 +488,7 @@ int main(int argc, char **argv) #if defined(HAVE_PTHREADS) // POSIX threads available, start 60Hz thread - pthread_attr_init(&tick_thread_attr); -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - if (geteuid() == 0) { - pthread_attr_setinheritsched(&tick_thread_attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(&tick_thread_attr, SCHED_FIFO); - struct sched_param fifo_param; - fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2; - pthread_attr_setschedparam(&tick_thread_attr, &fifo_param); - } -#endif + Set_pthread_attr(&tick_thread_attr, 0); tick_thread_active = (pthread_create(&tick_thread, &tick_thread_attr, tick_func, NULL) == 0); if (!tick_thread_active) { sprintf(str, GetString(STR_TICK_THREAD_ERR), strerror(errno)); @@ -692,6 +683,39 @@ static void sigint_handler(...) #endif +#ifdef HAVE_PTHREADS +/* + * Pthread configuration + */ +void +Set_pthread_attr(pthread_attr_t *attr, int priority) +{ + pthread_attr_init(attr); +#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) + // Some of these only work for superuser + if (geteuid() == 0) { + pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED); + pthread_attr_setschedpolicy(attr, SCHED_FIFO); + struct sched_param fifo_param; + fifo_param.sched_priority = ((sched_get_priority_min(SCHED_FIFO) + + sched_get_priority_max(SCHED_FIFO)) / 2 + + priority); + pthread_attr_setschedparam(attr, &fifo_param); + } + if (pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM) != 0) { +#ifdef PTHREAD_SCOPE_BOUND_NP + // If system scope is not available (eg. we're not running + // with CAP_SCHED_MGT capability on an SGI box), try bound + // scope. It exposes pthread scheduling to the kernel, + // without setting realtime priority. + pthread_attr_setscope(attr, PTHREAD_SCOPE_BOUND_NP); +#endif + } +#endif +} +#endif // HAVE_PTHREADS + + /* * Mutexes */ @@ -699,7 +723,21 @@ static void sigint_handler(...) #ifdef HAVE_PTHREADS struct B2_mutex { - B2_mutex() { pthread_mutex_init(&m, NULL); } + B2_mutex() { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + // Initialize the mutex for priority inheritance -- + // required for accurate timing. +#ifdef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL + pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); +#endif +#if defined(HAVE_PTHREAD_MUTEXATTR_SETTYPE) && defined(PTHREAD_MUTEX_NORMAL) + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); +#endif + pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE); + pthread_mutex_init(&m, &attr); + pthread_mutexattr_destroy(&attr); + } ~B2_mutex() { pthread_mutex_unlock(&m); pthread_mutex_destroy(&m); } pthread_mutex_t m; }; diff --git a/BasiliskII/src/Unix/serial_unix.cpp b/BasiliskII/src/Unix/serial_unix.cpp index 9ca0286f..0d378a73 100644 --- a/BasiliskII/src/Unix/serial_unix.cpp +++ b/BasiliskII/src/Unix/serial_unix.cpp @@ -67,16 +67,7 @@ public: fd = -1; input_thread_active = output_thread_active = false; - pthread_attr_init(&thread_attr); -#if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) - if (geteuid() == 0) { - pthread_attr_setinheritsched(&thread_attr, PTHREAD_EXPLICIT_SCHED); - pthread_attr_setschedpolicy(&thread_attr, SCHED_FIFO); - struct sched_param fifo_param; - fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2 + 2; - pthread_attr_setschedparam(&thread_attr, &fifo_param); - } -#endif + Set_pthread_attr(&thread_attr, 2); } virtual ~XSERDPort() diff --git a/BasiliskII/src/Unix/sys_unix.cpp b/BasiliskII/src/Unix/sys_unix.cpp index e638260a..1fc2ddff 100644 --- a/BasiliskII/src/Unix/sys_unix.cpp +++ b/BasiliskII/src/Unix/sys_unix.cpp @@ -33,9 +33,9 @@ #include #ifdef __NR__llseek -_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh); +_syscall5(int, _llseek, unsigned int, fd, unsigned long, hi, unsigned long, lo, loff_t *, res, unsigned int, wh); #else -static int _llseek(uint fd, ulong hi, ulong lo, loff_t *res, uint wh) +static int _llseek(unsigned int fd, unsigned long hi, unsigned long lo, loff_t *res, unsigned int wh) { if (hi) return -1; diff --git a/BasiliskII/src/Unix/sysdeps.h b/BasiliskII/src/Unix/sysdeps.h index 730f5dcf..be537a27 100644 --- a/BasiliskII/src/Unix/sysdeps.h +++ b/BasiliskII/src/Unix/sysdeps.h @@ -178,6 +178,11 @@ typedef uae_u32 uaecptr; extern uint64 GetTicks_usec(void); extern void Delay_usec(uint32 usec); +#ifdef HAVE_PTHREADS +/* Centralized pthread attribute setup */ +void Set_pthread_attr(pthread_attr_t *attr, int priority); +#endif + /* UAE CPU defines */ #ifdef WORDS_BIGENDIAN diff --git a/BasiliskII/src/Unix/video_x.cpp b/BasiliskII/src/Unix/video_x.cpp index 31f1352c..40628dc4 100644 --- a/BasiliskII/src/Unix/video_x.cpp +++ b/BasiliskII/src/Unix/video_x.cpp @@ -97,6 +97,7 @@ static uint32 the_buffer_size; // Size of allocated the_buffer static bool redraw_thread_active = false; // Flag: Redraw thread installed #ifdef HAVE_PTHREADS +static pthread_attr_t redraw_thread_attr; // Redraw thread attributes static volatile bool redraw_thread_cancel; // Flag: Cancel Redraw thread static pthread_t redraw_thread; // Redraw thread #endif @@ -1448,7 +1449,8 @@ static bool video_open(const video_mode &mode) // Start redraw/input thread #ifdef HAVE_PTHREADS redraw_thread_cancel = false; - redraw_thread_active = (pthread_create(&redraw_thread, NULL, redraw_func, NULL) == 0); + Set_pthread_attr(&redraw_thread_attr, 0); + redraw_thread_active = (pthread_create(&redraw_thread, &redraw_thread_attr, redraw_func, NULL) == 0); if (!redraw_thread_active) { printf("FATAL: cannot create redraw thread\n"); return false; diff --git a/BasiliskII/src/cdrom.cpp b/BasiliskII/src/cdrom.cpp index 9a447f76..9523a92a 100644 --- a/BasiliskII/src/cdrom.cpp +++ b/BasiliskII/src/cdrom.cpp @@ -193,8 +193,9 @@ static void find_hfs_partition(cdrom_drive_info &info) // Partition map block found, Apple HFS partition? if (strcmp((char *)(map + 48), "Apple_HFS") == 0) { - info.start_byte = ntohl(((uint32 *)map)[2]) << 9; - D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, ntohl(((uint32 *)map)[3]))); + info.start_byte = (loff_t)((map[8] << 24) | (map[9] << 16) | (map[10] << 8) | map[11]) << 9; + uint32 num_blocks = (map[12] << 24) | (map[13] << 16) | (map[14] << 8) | map[15]; + D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, num_blocks)); break; } } diff --git a/BasiliskII/src/disk.cpp b/BasiliskII/src/disk.cpp index 4c180845..58ffa0a8 100644 --- a/BasiliskII/src/disk.cpp +++ b/BasiliskII/src/disk.cpp @@ -135,8 +135,8 @@ static void find_hfs_partition(disk_drive_info &info) // Partition map block found, Apple HFS partition? if (strcmp((char *)(map + 48), "Apple_HFS") == 0) { - info.start_byte = ntohl(((uint32 *)map)[2]) << 9; - info.num_blocks = ntohl(((uint32 *)map)[3]); + info.start_byte = (loff_t)((map[8] << 24) | (map[9] << 16) | (map[10] << 8) | map[11]) << 9; + info.num_blocks = (map[12] << 24) | (map[13] << 16) | (map[14] << 8) | map[15]; D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, info.num_blocks)); break; } diff --git a/BasiliskII/src/ether.cpp b/BasiliskII/src/ether.cpp index ab9ca102..844fd2e4 100644 --- a/BasiliskII/src/ether.cpp +++ b/BasiliskII/src/ether.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #endif