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
This commit is contained in:
Aaron Culliney 2013-07-02 01:10:57 -07:00
parent c51018a2bb
commit 18c3f5f698
5 changed files with 51 additions and 31 deletions

View File

@ -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);
}
/* -------------------------------------------------------------------------

View File

@ -73,8 +73,6 @@
#define kPGDN 164
#define kEND 165
#define TIMER_DELAY 30000L
#ifdef PC_JOYSTICK
extern int js_fd;

View File

@ -19,6 +19,8 @@
#include <ctype.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/io.h>
@ -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);
}

View File

@ -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];

View File

@ -15,8 +15,9 @@
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#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 ...