コード例 #1
0
ファイル: timer.cpp プロジェクト: lewellyn/CockatriceIII
int16 PrimeTime(uint32 tm, int32 time)
{
	D(bug("PrimeTime %08lx, time %ld\n", tm, time));

	// Find descriptor
	int i = find_desc(tm);
	if (i < 0) {
		printf("FATAL: PrimeTime(): Descriptor not found\n");
		return 0;
	}

	// Extended task?
	if (ReadMacInt16(tm + qType) & 0x4000) {

		// Convert delay time
		tm_time_t delay;
		timer_mac2host_time(delay, time);

		// Yes, tmWakeUp set?
		if (ReadMacInt32(tm + tmWakeUp)) {

			//!! PrimeTime(0) means continue previous delay
			// (save wakeup time in RmvTime?)
			if (time == 0) {
				printf("FATAL: Unsupported PrimeTime(0)\n");
				return 0;
			}

			// Yes, calculate wakeup time relative to last scheduled time
			tm_time_t wakeup;
			timer_add_time(wakeup, desc[i].wakeup, delay);
			desc[i].wakeup = wakeup;

		} else {

			// No, calculate wakeup time relative to current time
			tm_time_t now;
			timer_current_time(now);
			timer_add_time(desc[i].wakeup, now, delay);
		}

		// Set tmWakeUp to indicate that task was scheduled
		WriteMacInt32(tm + tmWakeUp, 0x12345678);

	} else {

		// Not extended task, calculate wakeup time relative to current time
		tm_time_t delay;
		timer_mac2host_time(delay, time);
		timer_current_time(desc[i].wakeup);
		timer_add_time(desc[i].wakeup, desc[i].wakeup, delay);
	}

	// Make task active and enqueue it in the Time Manager queue
	WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000);
	enqueue_tm(tm);
	return 0;
}
コード例 #2
0
ファイル: timer.cpp プロジェクト: amade/SheepShaver_oldstuff
int16 PrimeTime(uint32 tm, int32 time)
{
	D(bug("PrimeTime %08lx, time %ld\n", tm, time));

	// Find descriptor
	TMDesc *desc = find_desc(tm);
	if (!desc) {
		printf("FATAL: PrimeTime(%08lx): Descriptor not found\n", (long unsigned int)tm);
		return 0;
	}

	// Convert delay time
	tm_time_t delay;
	timer_mac2host_time(delay, time);

	// Extended task?
	if (ReadMacInt16(tm + qType) & 0x4000) {

		// Yes, tmWakeUp set?
		if (ReadMacInt32(tm + tmWakeUp)) {

			// PrimeTime(0) can either mean (a) "the task runs as soon as interrupts are enabled"
			// or (b) "continue previous delay" if an expired task was stopped via RmvTime() and
			// then re-installed using InsXTime(). Since tmWakeUp was set, this is case (b).
			// The remaining time was saved in tmCount by RmvTime().
			if (time == 0) {
				timer_mac2host_time(delay, ReadMacInt16(tm + tmCount));
			}

			// Yes, calculate wakeup time relative to last scheduled time
			tm_time_t wakeup;
			timer_add_time(wakeup, desc->wakeup, delay);
			desc->wakeup = wakeup;

		} else {

			// No, calculate wakeup time relative to current time
			tm_time_t now;
			timer_current_time(now);
			timer_add_time(desc->wakeup, now, delay);
		}

		// Set tmWakeUp to indicate that task was scheduled
		WriteMacInt32(tm + tmWakeUp, 0x12345678);

	} else {

		// Not extended task, calculate wakeup time relative to current time
		tm_time_t now;
		timer_current_time(now);
		timer_add_time(desc->wakeup, now, delay);
	}

	// Make task active and enqueue it in the Time Manager queue
#if PRECISE_TIMING_BEOS
	while (acquire_sem(wakeup_time_sem) == B_INTERRUPTED) ;
	suspend_thread(timer_thread);
#endif
#ifdef PRECISE_TIMING_MACH
	semaphore_wait(wakeup_time_sem);
	thread_suspend(timer_thread);
#endif
#if PRECISE_TIMING_POSIX
	timer_thread_suspend();
	pthread_mutex_lock(&wakeup_time_lock);
#endif
	WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000);
	enqueue_tm(tm);
#if PRECISE_TIMING
	// Look for next task to be called and set wakeup_time
	wakeup_time = wakeup_time_max;
	for (TMDesc *d = tmDescList; d; d = d->next)
		if ((ReadMacInt16(d->task + qType) & 0x8000))
			if (timer_cmp_time(d->wakeup, wakeup_time) < 0)
				wakeup_time = d->wakeup;
#ifdef PRECISE_TIMING_BEOS
	release_sem(wakeup_time_sem);
	thread_info info;
	do {
		resume_thread(timer_thread);			// This will unblock the thread
		get_thread_info(timer_thread, &info);
	} while (info.state == B_THREAD_SUSPENDED);	// Sometimes, resume_thread() doesn't work (BeOS bug?)
#endif
#ifdef PRECISE_TIMING_MACH
	semaphore_signal(wakeup_time_sem);
	thread_abort(timer_thread);
	thread_resume(timer_thread);
#endif
#ifdef PRECISE_TIMING_POSIX
	pthread_mutex_unlock(&wakeup_time_lock);
	timer_thread_resume();
	assert(suspend_count == 0);
#endif
#endif
	return 0;
}