Пример #1
0
static void *watchdog_thread(void *param)
{
	watchdog *thiz = (watchdog *) param;

	while (TRUE)
	{
		if (osd_event_wait(thiz->event(), thiz->getTimeout()))
		{
			if (thiz->do_exit())
				break;
			else
			{
				osd_event_reset(thiz->event());
				continue;
			}
		}
		else
		{
			fprintf(stderr, "Terminating due to watchdog timeout\n");

			osd_process_kill();
		}
	}
	return NULL;
}
Пример #2
0
int osd_work_item_wait(osd_work_item *item, osd_ticks_t timeout)
{
	// if we're done already, just return
	if (item->done)
		return TRUE;

	// if we don't have an event, create one
	if (item->event == NULL)
	{
		INT32 lockslot = osd_scalable_lock_acquire(item->queue->lock);
		item->event = osd_event_alloc(TRUE, FALSE);     // manual reset, not signalled
		osd_scalable_lock_release(item->queue->lock, lockslot);
	}
	else
		osd_event_reset(item->event);

	// if we don't have an event, we need to spin (shouldn't ever really happen)
	if (item->event == NULL)
	{
		// TODO: do we need to measure the spin time here as well? and how can we do it?
        spin_while(&item->done, 0, timeout);
	}

	// otherwise, block on the event until done
	else if (!item->done)
		osd_event_wait(item->event, timeout);

	// return TRUE if the refcount actually hit 0
	return item->done;
}
Пример #3
0
int osd_work_item_wait(osd_work_item *item, osd_ticks_t timeout)
{
	// if we're done already, just return
	if (item->done)
		return TRUE;

	// if we don't have an event, create one
	if (item->event == NULL)
		item->event = osd_event_alloc(TRUE, FALSE);     // manual reset, not signalled
	else
			osd_event_reset(item->event);

	// if we don't have an event, we need to spin (shouldn't ever really happen)
	if (item->event == NULL)
	{
		osd_ticks_t stopspin = osd_ticks() + timeout;
		do {
			int spin = 10000;
			while (--spin && !item->done)
				osd_yield_processor();
		} while (!item->done && osd_ticks() < stopspin);
	}

	// otherwise, block on the event until done
	else if (!item->done)
		osd_event_wait(item->event, timeout);

	// return TRUE if the refcount actually hit 0
	return item->done;
}
Пример #4
0
static void *worker_thread_entry(void *param)
{
	work_thread_info *thread = (work_thread_info *)param;
	osd_work_queue *queue = thread->queue;

	// loop until we exit
	for ( ;; )
	{
		// block waiting for work or exit
		// bail on exit, and only wait if there are no pending items in queue
		if (!queue->exiting && queue->list == NULL)
		{
			begin_timing(thread->waittime);
			osd_event_wait(thread->wakeevent, INFINITE);
			end_timing(thread->waittime);
		}
		if (queue->exiting)
			break;

		// indicate that we are live
		atomic_exchange32(&thread->active, TRUE);
		atomic_increment32(&queue->livethreads);

		// process work items
		for ( ;; )
		{
			osd_ticks_t stopspin;

			// process as much as we can
			worker_thread_process(queue, thread);

			// if we're a high frequency queue, spin for a while before giving up
			if (queue->flags & WORK_QUEUE_FLAG_HIGH_FREQ && queue->list == NULL)
			{
				// spin for a while looking for more work
				begin_timing(thread->spintime);
				stopspin = osd_ticks() + SPIN_LOOP_TIME;
				
				do {
					int spin = 10000;
					while (--spin && queue->list == NULL)
						osd_yield_processor();
				} while (queue->list == NULL && osd_ticks() < stopspin);
				end_timing(thread->spintime);
			}

			// if nothing more, release the processor
			if (queue->list == NULL)
				break;
			add_to_stat(&queue->spinloops, 1);
		}

		// decrement the live thread count
		atomic_exchange32(&thread->active, FALSE);
		atomic_decrement32(&queue->livethreads);
	}
	return NULL;
}
Пример #5
0
void sdlwindow_video_window_update(running_machine &machine, sdl_window_info *window)
{

	osd_ticks_t     event_wait_ticks;
	ASSERT_MAIN_THREAD();

	// adjust the cursor state
	sdlwindow_update_cursor_state(machine, window);

	// if we're visible and running and not in the middle of a resize, draw
	if (window->target != NULL)
	{
		int tempwidth, tempheight;

		// see if the games video mode has changed
		window->target->compute_minimum_size(tempwidth, tempheight);
		if (tempwidth != window->minwidth || tempheight != window->minheight)
		{
			window->minwidth = tempwidth;
			window->minheight = tempheight;
			if (!window->fullscreen)
			{
				sdlwindow_blit_surface_size(window, window->width, window->height);
				sdlwindow_resize(window, window->blitwidth, window->blitheight);
			}
			else if (video_config.switchres)
			{
				pick_best_mode(window, &tempwidth, &tempheight);
				sdlwindow_resize(window, tempwidth, tempheight);
			}
		}

		if (video_config.waitvsync && video_config.syncrefresh)
			event_wait_ticks = osd_ticks_per_second(); // block at most a second
		else
			event_wait_ticks = 0;

		if (osd_event_wait(window->rendered_event, event_wait_ticks))
		{
			worker_param wp;
			render_primitive_list *primlist;

			clear_worker_param(&wp);

			// ensure the target bounds are up-to-date, and then get the primitives
			primlist = &window->get_primitives(window);

			// and redraw now

			wp.list = primlist;
			wp.window = window;
			wp.m_machine = &machine;

			execute_async(&draw_video_contents_wt, &wp);
		}
	}
}
Пример #6
0
void sdlwindow_video_window_update(running_machine *machine, sdl_window_info *window)
{

	ASSERT_MAIN_THREAD();

	// adjust the cursor state
	sdlwindow_update_cursor_state(machine, window);

	// if we're visible and running and not in the middle of a resize, draw
	if (window->target != NULL)
	{
		int tempwidth, tempheight;

		// see if the games video mode has changed
		render_target_get_minimum_size(window->target, &tempwidth, &tempheight);
		if (tempwidth != window->minwidth || tempheight != window->minheight)
		{
			window->minwidth = tempwidth;
			window->minheight = tempheight;
			if (!window->fullscreen)
			{
				sdlwindow_blit_surface_size(window, window->width, window->height);
				sdlwindow_resize(window, window->blitwidth, window->blitheight);
			}
			else if (video_config.switchres)
			{
				pick_best_mode(window, &tempwidth, &tempheight);
				sdlwindow_resize(window, tempwidth, tempheight);
			}
		}

		// only render if we have been signalled
		if (osd_event_wait(window->rendered_event, 0))
		{
			worker_param wp;
			const render_primitive_list *primlist;

			clear_worker_param(&wp);

			// ensure the target bounds are up-to-date, and then get the primitives
			primlist = window->get_primitives(window);

			// and redraw now

			wp.list = primlist;
			wp.window = window;
			wp.machine = machine;

			execute_async(&draw_video_contents_wt, &wp);
		}
	}
}
Пример #7
0
int osd_work_queue_wait(osd_work_queue *queue, osd_ticks_t timeout)
{
	// if no threads, no waiting
	if (queue->threads == 0)
		return TRUE;

	// if no items, we're done
	if (queue->items == 0)
		return TRUE;

	// if this is a multi queue, help out rather than doing nothing
	if (queue->flags & WORK_QUEUE_FLAG_MULTI)
	{
		work_thread_info *thread = &queue->thread[queue->threads];

		end_timing(thread->waittime);

		// process what we can as a worker thread
		worker_thread_process(queue, thread);

		// if we're a high frequency queue, spin until done
		if (queue->flags & WORK_QUEUE_FLAG_HIGH_FREQ && queue->items != 0)
		{
			osd_ticks_t stopspin = osd_ticks() + timeout;

			// spin until we're done
			begin_timing(thread->spintime);

			do {
				int spin = 10000;
				while (--spin && queue->items != 0)
					osd_yield_processor();
			} while (queue->items != 0 && osd_ticks() < stopspin);
			end_timing(thread->spintime);

			begin_timing(thread->waittime);
			return (queue->items == 0);
		}
		begin_timing(thread->waittime);
	}

	// reset our done event and double-check the items before waiting
	osd_event_reset(queue->doneevent);
	atomic_exchange32(&queue->waiting, TRUE);
	if (queue->items != 0)
		osd_event_wait(queue->doneevent, timeout);
	atomic_exchange32(&queue->waiting, FALSE);

	// return TRUE if we actually hit 0
	return (queue->items == 0);
}
Пример #8
0
void sdl_window_info::update()
{
	osd_ticks_t     event_wait_ticks;
	ASSERT_MAIN_THREAD();

	// adjust the cursor state
	//sdlwindow_update_cursor_state(machine, window);

	execute_async(&update_cursor_state_wt, worker_param(this));

	// if we're visible and running and not in the middle of a resize, draw
	if (m_target != NULL)
	{
		int tempwidth, tempheight;

		// see if the games video mode has changed
		m_target->compute_minimum_size(tempwidth, tempheight);
		if (osd_dim(tempwidth, tempheight) != m_minimum_dim)
		{
			m_minimum_dim = osd_dim(tempwidth, tempheight);

			if (!this->m_fullscreen)
			{
				//Don't resize window without user interaction;
				//window_resize(blitwidth, blitheight);
			}
			else if (video_config.switchres)
			{
				osd_dim tmp = this->pick_best_mode();
				resize(tmp.width(), tmp.height());
			}
		}

		if (video_config.waitvsync && video_config.syncrefresh)
			event_wait_ticks = osd_ticks_per_second(); // block at most a second
		else
			event_wait_ticks = 0;

		if (osd_event_wait(m_rendered_event, event_wait_ticks))
		{
			// ensure the target bounds are up-to-date, and then get the primitives

			render_primitive_list &primlist = *m_renderer->get_primitives();

			// and redraw now

			execute_async(&draw_video_contents_wt, worker_param(this, primlist));
		}
	}
}
Пример #9
0
static void *worker_thread_entry(void *param)
{
	work_thread_info *thread = (work_thread_info *)param;
	osd_work_queue *queue = thread->queue;

#if defined(SDLMAME_MACOSX)
	void *arp = NewAutoreleasePool();
#endif

	// loop until we exit
	for ( ;; )
	{
		// block waiting for work or exit
		// bail on exit, and only wait if there are no pending items in queue
		if (queue->exiting)
			break;

		if (!queue_has_list_items(queue))
		{
			begin_timing(thread->waittime);
			osd_event_wait(thread->wakeevent, OSD_EVENT_WAIT_INFINITE);
			end_timing(thread->waittime);
		}

		if (queue->exiting)
			break;

		// indicate that we are live
		atomic_exchange32(&thread->active, TRUE);
		atomic_increment32(&queue->livethreads);

		// process work items
		for ( ;; )
		{
			// process as much as we can
			worker_thread_process(queue, thread);

			// if we're a high frequency queue, spin for a while before giving up
			if (queue->flags & WORK_QUEUE_FLAG_HIGH_FREQ && queue->list == NULL)
			{
				// spin for a while looking for more work
				begin_timing(thread->spintime);
				spin_while(&queue->list, (osd_work_item *)NULL, SPIN_LOOP_TIME);
				end_timing(thread->spintime);
			}

			// if nothing more, release the processor
			if (!queue_has_list_items(queue))
				break;
			add_to_stat(&queue->spinloops, 1);
		}

		// decrement the live thread count
		atomic_exchange32(&thread->active, FALSE);
		atomic_decrement32(&queue->livethreads);
	}

#if defined(SDLMAME_MACOSX)
	ReleaseAutoreleasePool(arp);
#endif

	return NULL;
}
Пример #10
0
void sdl_window_info::update()
{
	osd_ticks_t     event_wait_ticks;
	ASSERT_MAIN_THREAD();

	// adjust the cursor state
	//sdlwindow_update_cursor_state(machine, window);

	execute_async(&update_cursor_state_wt, worker_param(this));

	// if we're visible and running and not in the middle of a resize, draw
	if (m_target != NULL)
	{
		int tempwidth, tempheight;

		// see if the games video mode has changed
		m_target->compute_minimum_size(tempwidth, tempheight);
		if (video_config.switchres && m_fullscreen && machine().options().changeres() && machine().switchres.game.changeres)
		{
			switchres_resolution_change(this);
			return;
		}
		else if (osd_dim(tempwidth, tempheight) != m_minimum_dim)
		{
			m_minimum_dim = osd_dim(tempwidth, tempheight);

			if (!this->m_fullscreen)
			{
				//Don't resize window without user interaction;
				//window_resize(blitwidth, blitheight);
			}
			else if (video_config.switchres)
			{
				osd_dim tmp = this->pick_best_mode();
				resize(tmp.width(), tmp.height());
			}
		}

		int got_lock = false;
		got_lock = osd_lock_try(m_render_lock);

		// only render if we were able to get the lock
		if (got_lock)
		{
			// don't hold the lock; we just used it to see if rendering was still happening
			osd_lock_release(m_render_lock);

			// ensure the target bounds are up-to-date, and then get the primitives

			render_primitive_list &primlist = *m_renderer->get_primitives();

			// and redraw now
			osd_event_reset(m_rendered_event);
			execute_async(&draw_video_contents_wt, worker_param(this, primlist));

			if (video_config.waitvsync && machine().video().throttled())
			{
				event_wait_ticks = osd_ticks_per_second(); // block at most a second
				osd_event_wait(m_rendered_event, event_wait_ticks);
			}
		}
	}
}