From 18c3f5f698bd675f007e9cc1dc41a84487bc4497 Mon Sep 17 00:00:00 2001 From: Aaron Culliney Date: Tue, 2 Jul 2013 01:10:57 -0700 Subject: [PATCH] we no longer use timers with setitimer and SIGVTALRM, that's so nineties... instead spin off a cpu_thread and have it ping the main render thread as needed --- src/keys.c | 2 -- src/keys.h | 2 -- src/misc.c | 54 ++++++++++++++++++++++++++++++---------------------- src/misc.h | 2 -- src/timing.c | 22 +++++++++++++++++++-- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/keys.c b/src/keys.c index aae40533..e6c662fa 100644 --- a/src/keys.c +++ b/src/keys.c @@ -352,9 +352,7 @@ void c_periodic_update(int dummysig) { */ void enter_debugger(void) { - setitimer(ITIMER_VIRTUAL,&timer_off,0); c_do_debugging(); - setitimer(ITIMER_VIRTUAL,&timer_on,0); } /* ------------------------------------------------------------------------- diff --git a/src/keys.h b/src/keys.h index aea89c41..f6988b22 100644 --- a/src/keys.h +++ b/src/keys.h @@ -73,8 +73,6 @@ #define kPGDN 164 #define kEND 165 -#define TIMER_DELAY 30000L - #ifdef PC_JOYSTICK extern int js_fd; diff --git a/src/misc.c b/src/misc.c index 9f87974e..b155950e 100644 --- a/src/misc.c +++ b/src/misc.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include #include @@ -32,9 +34,7 @@ #include "cpu.h" #include "glue.h" #include "prefs.h" - -const struct itimerval timer_off = {{0,0},{0,0}}; -const struct itimerval timer_on = {{0,TIMER_DELAY},{0,TIMER_DELAY}}; +#include "timing.h" /* ---------------------------------- internal apple2 variables @@ -45,6 +45,9 @@ static unsigned char apple_ii_rom[12288]; static unsigned char apple_iie_rom[32768]; /* //e */ #endif +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + /* in debugger.c */ extern int breakpoints[]; extern int watchpoints[]; @@ -704,10 +707,6 @@ static void c_initialize_firsttime() /* initialize the video system */ video_init(); - /* Enable periodic updates */ - signal(SIGVTALRM,c_periodic_update); - setitimer(ITIMER_VIRTUAL,&timer_on,0); - reinitialize(); } @@ -715,29 +714,38 @@ void c_read_random() { random_value = (unsigned char)(rand() >> 8); } +static void cpu_thread (void *dummyptr) { + + do { + cpu65_run(); + reinitialize(); + } while (1); +} + +static void main_thread (void *dummyptr) { + do { + // sleep waiting for the cpu thread to ping us that it's sleeping... + pthread_mutex_lock(&mutex); + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + + c_periodic_update(0); + } while (1); +} + int main(int sargc, char *sargv[]) { - int i; - argc = sargc; argv = sargv; - for (i = 1; i < argc; i++) - { -/* - if (strcmp(argv[i], "-vga") == 0) - force_vga_mode = 1; -*/ - } - load_settings(); /* user prefs */ c_initialize_firsttime(); /* init svga graphics and vm */ + timing_initialize(); - for (;;) { - /* execute the emulator */ - cpu65_run(); + // spin off cpu thread + pthread_t thread1; + pthread_create(&thread1, NULL, (void *) &cpu_thread, (void *)NULL); - reinitialize(); - } - /* never reached */ + // enter main render thread + main_thread(NULL); } diff --git a/src/misc.h b/src/misc.h index 37057f58..4517cb6b 100644 --- a/src/misc.h +++ b/src/misc.h @@ -39,8 +39,6 @@ #define SW_IOUDIS 0xC07E #endif -extern const struct itimerval timer_on,timer_off; - /* Text characters */ extern const unsigned char ucase_glyphs[0x200]; extern const unsigned char lcase_glyphs[0x100]; diff --git a/src/timing.c b/src/timing.c index 9b1cfe4c..e28e5389 100644 --- a/src/timing.c +++ b/src/timing.c @@ -15,8 +15,9 @@ #include #include #include +#include -#define DEFAULT_SLEEP 60 +#define DEFAULT_SLEEP 120 static unsigned int sleep_hz = DEFAULT_SLEEP; // sleep intervals per sec static unsigned long cpu_target_hz = APPLE2_HZ; // target clock speed @@ -28,6 +29,9 @@ static unsigned long cycle=0; static long sleep_adjust=0; static long sleep_adjust_inc=0; +extern pthread_mutex_t mutex; +extern pthread_cond_t cond; + // ----------------------------------------------------------------------------- // assuming end > start, returns end - start @@ -66,16 +70,30 @@ void timing_set_sleep_hz (unsigned int hz) { /* * Throttles the 65c02 CPU down to a target frequency of X. * Currently set to target the Apple //e @ 1.02MHz + * + * This is called from cpu65_run() on the cpu-thread */ void timing_throttle () { ++cycle; + static time_t severe_lag=0; + if ((cycle%cycles_interval) == 0) { + + // wake render thread as we go to sleep + pthread_mutex_lock(&mutex); + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + clock_gettime(CLOCK_MONOTONIC, &tj); deltat = timespec_diff(ti, tj); ti=tj; if (deltat.tv_sec != 0) { - // severely lagging ... + // severely lagging, don't bother sleeping ... + if (severe_lag < time(NULL)) { + severe_lag = time(NULL)+2; + fprintf(stderr, "Severe lag detected...\n"); + } } else { deltat.tv_nsec = processing_interval - deltat.tv_nsec + sleep_adjust_inc; nanosleep(&deltat, NULL); // NOTE: spec says will return right away if deltat.tv_nsec value < 0 ...