コード例 #1
0
ファイル: work_osd.c プロジェクト: crazii/mameplus
osd_work_queue *osd_work_queue_alloc(int flags)
{
	int threadnum;
	int numprocs = effective_num_processors();
	osd_work_queue *queue;
	int osdthreadnum = 0;
	int allocthreadnum;
	char *osdworkqueuemaxthreads = osd_getenv(ENV_WORKQUEUEMAXTHREADS);

	// allocate a new queue
	queue = (osd_work_queue *)osd_malloc(sizeof(*queue));
	if (queue == NULL)
		goto error;
	memset(queue, 0, sizeof(*queue));

	// initialize basic queue members
	queue->tailptr = (osd_work_item **)&queue->list;
	queue->flags = flags;

	// allocate events for the queue
	queue->doneevent = osd_event_alloc(TRUE, TRUE);     // manual reset, signalled
	if (queue->doneevent == NULL)
		goto error;

	// initialize the critical section
	queue->lock = osd_scalable_lock_alloc();
	if (queue->lock == NULL)
		goto error;

	// determine how many threads to create...
	// on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else
	if (numprocs == 1)
		threadnum = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0;
	// on an n-CPU system, create n-1 threads for multi queues, and 1 thread for everything else
	else
		threadnum = (flags & WORK_QUEUE_FLAG_MULTI) ? (numprocs - 1) : 1;

	if (osdworkqueuemaxthreads != NULL && sscanf(osdworkqueuemaxthreads, "%d", &osdthreadnum) == 1 && threadnum > osdthreadnum)
		threadnum = osdthreadnum;

	// clamp to the maximum
	queue->threads = MIN(threadnum, WORK_MAX_THREADS);

	// allocate memory for thread array (+1 to count the calling thread if WORK_QUEUE_FLAG_MULTI)
	if (flags & WORK_QUEUE_FLAG_MULTI)
		allocthreadnum = queue->threads + 1;
	else
		allocthreadnum = queue->threads;

#if KEEP_STATISTICS
	printf("osdprocs: %d effecprocs: %d threads: %d allocthreads: %d osdthreads: %d maxthreads: %d queuethreads: %d\n", osd_num_processors, numprocs, threadnum, allocthreadnum, osdthreadnum, WORK_MAX_THREADS, queue->threads);
#endif

	queue->thread = (work_thread_info *)osd_malloc_array(allocthreadnum * sizeof(queue->thread[0]));
	if (queue->thread == NULL)
		goto error;
	memset(queue->thread, 0, allocthreadnum * sizeof(queue->thread[0]));

	// iterate over threads
	for (threadnum = 0; threadnum < queue->threads; threadnum++)
	{
		work_thread_info *thread = &queue->thread[threadnum];

		// set a pointer back to the queue
		thread->queue = queue;

		// create the per-thread wake event
		thread->wakeevent = osd_event_alloc(FALSE, FALSE);  // auto-reset, not signalled
		if (thread->wakeevent == NULL)
			goto error;

		// create the thread
		thread->handle = osd_thread_create(worker_thread_entry, thread);
		if (thread->handle == NULL)
			goto error;

		// set its priority: I/O threads get high priority because they are assumed to be
		// blocked most of the time; other threads just match the creator's priority
		if (flags & WORK_QUEUE_FLAG_IO)
			osd_thread_adjust_priority(thread->handle, 1);
		else
			osd_thread_adjust_priority(thread->handle, 0);
	}

	// start a timer going for "waittime" on the main thread
	if (flags & WORK_QUEUE_FLAG_MULTI)
	{
		begin_timing(queue->thread[queue->threads].waittime);
	}
	return queue;

error:
	osd_work_queue_free(queue);
	return NULL;
}
コード例 #2
0
ファイル: retrowork.c プロジェクト: Archlogic/libretro-mame
osd_work_queue *osd_work_queue_alloc(int flags)
{
	int numprocs = effective_num_processors();
	osd_work_queue *queue;
	int threadnum;

	// allocate a new queue
	queue = (osd_work_queue *)osd_malloc(sizeof(*queue));
	if (queue == NULL)
		goto error;
	memset(queue, 0, sizeof(*queue));

	// initialize basic queue members
	queue->tailptr = (osd_work_item **)&queue->list;
	queue->flags = flags;

	// allocate events for the queue
	queue->doneevent = osd_event_alloc(TRUE, TRUE);     // manual reset, signalled
	if (queue->doneevent == NULL)
		goto error;

	// initialize the critical section
	queue->lock = osd_scalable_lock_alloc();
	if (queue->lock == NULL)
		goto error;

	// determine how many threads to create...
	// on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else
	if (numprocs == 1)
		queue->threads = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0;

	// on an n-CPU system, create (n-1) threads for multi queues, and 1 thread for everything else
	else
		queue->threads = (flags & WORK_QUEUE_FLAG_MULTI) ? (numprocs - 1) : 1;

	// clamp to the maximum
	queue->threads = MIN(queue->threads, WORK_MAX_THREADS);

	// allocate memory for thread array (+1 to count the calling thread)
	queue->thread = (work_thread_info *)osd_malloc_array((queue->threads + 1) * sizeof(queue->thread[0]));
	if (queue->thread == NULL)
		goto error;
	memset(queue->thread, 0, (queue->threads + 1) * sizeof(queue->thread[0]));

	// iterate over threads
	for (threadnum = 0; threadnum < queue->threads; threadnum++)
	{
		work_thread_info *thread = &queue->thread[threadnum];

		// set a pointer back to the queue
		thread->queue = queue;

		// create the per-thread wake event
		thread->wakeevent = osd_event_alloc(FALSE, FALSE);  // auto-reset, not signalled
		if (thread->wakeevent == NULL)
			goto error;

		// create the thread
		thread->handle = osd_thread_create(worker_thread_entry, thread);
		if (thread->handle == NULL)
			goto error;

		// set its priority: I/O threads get high priority because they are assumed to be
		// blocked most of the time; other threads just match the creator's priority
		if (flags & WORK_QUEUE_FLAG_IO)
			osd_thread_adjust_priority(thread->handle, 1);
		else
			osd_thread_adjust_priority(thread->handle, 0);

		// Bind main thread to cpu 0
		osd_thread_cpu_affinity(NULL, effective_cpu_mask(0));

		if (flags & WORK_QUEUE_FLAG_IO)
			osd_thread_cpu_affinity(thread->handle, effective_cpu_mask(1));
		else
			osd_thread_cpu_affinity(thread->handle, effective_cpu_mask(2+threadnum) );
	}

	// start a timer going for "waittime" on the main thread
	begin_timing(queue->thread[queue->threads].waittime);
	return queue;

error:
	osd_work_queue_free(queue);
	return NULL;
}
コード例 #3
0
ファイル: winwork.c プロジェクト: cdenix/ps3-mame-0125
osd_work_queue *osd_work_queue_alloc(int flags)
{
	int numprocs = effective_num_processors();
	osd_work_queue *queue;
	int threadnum;

	// allocate a new queue
	queue = malloc(sizeof(*queue));
	if (queue == NULL)
		goto error;
	memset(queue, 0, sizeof(*queue));

	// initialize basic queue members
	queue->tailptr = (osd_work_item **)&queue->list;
	queue->flags = flags;

	// allocate events for the queue
	queue->doneevent = CreateEvent(NULL, TRUE, TRUE, NULL);		// manual reset, signalled
	if (queue->doneevent == NULL)
		goto error;

	// initialize the critical section
	scalable_lock_init(&queue->lock);

	// determine how many threads to create...
	// on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else
	if (numprocs == 1)
		queue->threads = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0;

	// on an n-CPU system, create (n-1) threads for multi queues, and 1 thread for everything else
	else
		queue->threads = (flags & WORK_QUEUE_FLAG_MULTI) ? (numprocs - 1) : 1;

	// clamp to the maximum
	queue->threads = MIN(queue->threads, WORK_MAX_THREADS);

	// allocate memory for thread array (+1 to count the calling thread)
	queue->thread = malloc((queue->threads + 1) * sizeof(queue->thread[0]));
	if (queue->thread == NULL)
		goto error;
	memset(queue->thread, 0, (queue->threads + 1) * sizeof(queue->thread[0]));

	// iterate over threads
	for (threadnum = 0; threadnum < queue->threads; threadnum++)
	{
		work_thread_info *thread = &queue->thread[threadnum];
		uintptr_t handle;

		// set a pointer back to the queue
		thread->queue = queue;

		// create the per-thread wake event
		thread->wakeevent = CreateEvent(NULL, FALSE, FALSE, NULL);	// auto-reset, not signalled
		if (thread->wakeevent == NULL)
			goto error;

		// create the thread
		handle = _beginthreadex(NULL, 0, worker_thread_entry, thread, 0, NULL);
		thread->handle = (HANDLE)handle;
		if (thread->handle == NULL)
			goto error;

		// set its priority: I/O threads get high priority because they are assumed to be
		// blocked most of the time; other threads just match the creator's priority
		if (flags & WORK_QUEUE_FLAG_IO)
			SetThreadPriority(thread->handle, THREAD_PRIORITY_ABOVE_NORMAL);
		else
			SetThreadPriority(thread->handle, GetThreadPriority(GetCurrentThread()));
	}

	// start a timer going for "waittime" on the main thread
	begin_timing(queue->thread[queue->threads].waittime);
	return queue;

error:
	osd_work_queue_free(queue);
	return NULL;
}
コード例 #4
0
ファイル: osdsync.cpp プロジェクト: chrisisonwildcode/mame
osd_work_queue *osd_work_queue_alloc(int flags)
{
	int threadnum;
	int numprocs = effective_num_processors();
	osd_work_queue *queue;
	int osdthreadnum = 0;
	int allocthreadnum;
	const char *osdworkqueuemaxthreads = osd_getenv(ENV_WORKQUEUEMAXTHREADS);

	// allocate a new queue
	queue = new osd_work_queue();

	// initialize basic queue members
	queue->tailptr = (osd_work_item **)&queue->list;
	queue->flags = flags;

	// determine how many threads to create...
	// on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else
	if (numprocs == 1)
		threadnum = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0;
	// on an n-CPU system, create n-1 threads for multi queues, and 1 thread for everything else
	else
		threadnum = (flags & WORK_QUEUE_FLAG_MULTI) ? (numprocs - 1) : 1;

	if (osdworkqueuemaxthreads != nullptr && sscanf(osdworkqueuemaxthreads, "%d", &osdthreadnum) == 1 && threadnum > osdthreadnum)
		threadnum = osdthreadnum;

	// clamp to the maximum
	queue->threads = MIN(threadnum, WORK_MAX_THREADS);

	// allocate memory for thread array (+1 to count the calling thread if WORK_QUEUE_FLAG_MULTI)
	if (flags & WORK_QUEUE_FLAG_MULTI)
		allocthreadnum = queue->threads + 1;
	else
		allocthreadnum = queue->threads;

#if KEEP_STATISTICS
	printf("osdprocs: %d effecprocs: %d threads: %d allocthreads: %d osdthreads: %d maxthreads: %d queuethreads: %d\n", osd_num_processors, numprocs, threadnum, allocthreadnum, osdthreadnum, WORK_MAX_THREADS, queue->threads);
#endif

	for (threadnum = 0; threadnum < allocthreadnum; threadnum++)
		queue->thread.push_back(new work_thread_info(threadnum, *queue));

	// iterate over threads
	for (threadnum = 0; threadnum < queue->threads; threadnum++)
	{
		work_thread_info *thread = queue->thread[threadnum];

		// create the thread
		thread->handle = new std::thread(worker_thread_entry, thread);
		if (thread->handle == nullptr)
			goto error;

		// set its priority: I/O threads get high priority because they are assumed to be
		// blocked most of the time; other threads just match the creator's priority
		if (flags & WORK_QUEUE_FLAG_IO)
			thread_adjust_priority(thread->handle, 1);
		else
			thread_adjust_priority(thread->handle, 0);
	}

	// start a timer going for "waittime" on the main thread
	if (flags & WORK_QUEUE_FLAG_MULTI)
	{
		begin_timing(queue->thread[queue->threads]->waittime);
	}
	return queue;

error:
	osd_work_queue_free(queue);
	return nullptr;
}