示例#1
0
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

	// Set the timeout interval - Linux only needs to do this once
#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;
#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)
		now = GetTicks_usec();
		elapsed = now - then;
		then = now;
		if (elapsed >= usec)
			break;
		usec -= elapsed;
		tv.tv_sec = 0;
		tv.tv_usec = usec;
#endif
		was_error = select(0, NULL, NULL, NULL, &tv);
#endif
	} while (was_error && (errno == EINTR));
}
示例#2
0
static DWORD WINAPI tick_func(void *arg)
{
	int tick_counter = 0;
	uint64 start = GetTicks_usec();
	int64 ticks = 0;
	uint64 next = GetTicks_usec();

	while (!tick_thread_cancel) {

		// Wait
		next += 16625;
		int64 delay = next - GetTicks_usec();
		if (delay > 0)
			Delay_usec(delay);
		else if (delay < -16625)
			next = GetTicks_usec();
		ticks++;

		// Pseudo Mac 1Hz interrupt, update local time
		if (++tick_counter > 60) {
			tick_counter = 0;
			WriteMacInt32(0x20c, TimerDateTime());
		}

		// Trigger 60Hz interrupt
		if (ReadMacInt32(XLM_IRQ_NEST) == 0) {
			SetInterruptFlag(INTFLAG_VIA);
			TriggerInterrupt();
		}
	}

	uint64 end = GetTicks_usec();
	D(bug("%lu ticks in %lu usec = %f ticks/sec\n", (unsigned long)ticks, (unsigned long)(end - start), ticks * 1000000.0 / (end - start)));
	return 0;
}
示例#3
0
void Delay_usec(uint32 usec)
{
#ifdef __unix__
    int was_error;
#ifndef __linux__    /* Non-Linux implementations need to calculate time left */
    uint64 then, now, elapsed;
#endif
    struct timeval tv;

    /* Set the timeout interval - Linux only needs to do this once */
#ifdef __linux__
    tv.tv_sec = 0;
    tv.tv_usec = usec;
#else
    then = GetTicks_usec();
#endif
    do {
        errno = 0;
#ifndef __linux__
        /* Calculate the time interval left (in case of interrupt) */
        now = GetTicks_usec();
        elapsed = (now-then);
        then = now;
        if ( elapsed >= usec ) {
            break;
        }
        usec -= elapsed;
        tv.tv_sec = 0;
        tv.tv_usec = usec;
#endif
        was_error = select(0, NULL, NULL, NULL, &tv);
    } while (was_error && (errno == EINTR));
#else
    SDL_Delay(usec / 1000);
#endif
}