mirror of
https://github.com/holub/mame
synced 2025-05-28 16:43:04 +03:00
more work to make sdlwork.c and winwork.c match (nw)
This commit is contained in:
parent
f176a45d35
commit
6232bc0e50
@ -36,6 +36,11 @@ struct osd_lock
|
||||
CRITICAL_SECTION critsect;
|
||||
};
|
||||
|
||||
struct osd_event
|
||||
{
|
||||
void * ptr;
|
||||
};
|
||||
|
||||
struct osd_scalable_lock
|
||||
{
|
||||
#if USE_SCALABLE_LOCKS
|
||||
@ -184,6 +189,52 @@ INT32 win_atomic_add32(INT32 volatile *ptr, INT32 delta)
|
||||
return InterlockedExchangeAdd((LONG *) ptr, delta) + delta;
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// osd_event_alloc
|
||||
//============================================================
|
||||
|
||||
osd_event *osd_event_alloc(int manualreset, int initialstate)
|
||||
{
|
||||
return (osd_event *) CreateEvent(NULL, manualreset, initialstate, NULL);
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// osd_event_free
|
||||
//============================================================
|
||||
|
||||
void osd_event_free(osd_event *event)
|
||||
{
|
||||
CloseHandle((HANDLE) event);
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// osd_event_set
|
||||
//============================================================
|
||||
|
||||
void osd_event_set(osd_event *event)
|
||||
{
|
||||
SetEvent((HANDLE) event);
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// osd_event_reset
|
||||
//============================================================
|
||||
|
||||
void osd_event_reset(osd_event *event)
|
||||
{
|
||||
ResetEvent((HANDLE) event);
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// osd_event_wait
|
||||
//============================================================
|
||||
|
||||
int osd_event_wait(osd_event *event, osd_ticks_t timeout)
|
||||
{
|
||||
int ret = WaitForSingleObject((HANDLE) event, timeout * 1000 / osd_ticks_per_second());
|
||||
return ( ret == WAIT_OBJECT_0);
|
||||
}
|
||||
|
||||
//============================================================
|
||||
// Scalable Locks
|
||||
//============================================================
|
||||
|
@ -10,6 +10,95 @@
|
||||
#ifndef __WINSYNC__
|
||||
#define __WINSYNC__
|
||||
|
||||
/***************************************************************************
|
||||
SYNCHRONIZATION INTERFACES - Events
|
||||
***************************************************************************/
|
||||
|
||||
/* osd_event is an opaque type which represents a setable/resetable event */
|
||||
|
||||
struct osd_event;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
osd_lock_event_alloc: allocate a new event
|
||||
|
||||
Parameters:
|
||||
|
||||
manualreset - boolean. If true, the event will be automatically set
|
||||
to non-signalled after a thread successfully waited for
|
||||
it.
|
||||
initialstate - boolean. If true, the event is signalled initially.
|
||||
|
||||
Return value:
|
||||
|
||||
A pointer to the allocated event.
|
||||
-----------------------------------------------------------------------------*/
|
||||
osd_event *osd_event_alloc(int manualreset, int initialstate);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
osd_event_wait: wait for an event to be signalled
|
||||
|
||||
Parameters:
|
||||
|
||||
event - The event to wait for. If the event is in signalled state, the
|
||||
function returns immediately. If not it will wait for the event
|
||||
to become signalled.
|
||||
timeout - timeout in osd_ticks
|
||||
|
||||
Return value:
|
||||
|
||||
TRUE: The event was signalled
|
||||
FALSE: A timeout occurred
|
||||
-----------------------------------------------------------------------------*/
|
||||
int osd_event_wait(osd_event *event, osd_ticks_t timeout);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
osd_event_reset: reset an event to non-signalled state
|
||||
|
||||
Parameters:
|
||||
|
||||
event - The event to set to non-signalled state
|
||||
|
||||
Return value:
|
||||
|
||||
None
|
||||
-----------------------------------------------------------------------------*/
|
||||
void osd_event_reset(osd_event *event);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
osd_event_set: set an event to signalled state
|
||||
|
||||
Parameters:
|
||||
|
||||
event - The event to set to signalled state
|
||||
|
||||
Return value:
|
||||
|
||||
None
|
||||
|
||||
Notes:
|
||||
|
||||
All threads waiting for the event will be signalled.
|
||||
-----------------------------------------------------------------------------*/
|
||||
void osd_event_set(osd_event *event);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
osd_event_free: free the memory and resources associated with an osd_event
|
||||
|
||||
Parameters:
|
||||
|
||||
event - a pointer to a previously allocated osd_event.
|
||||
|
||||
Return value:
|
||||
|
||||
None.
|
||||
-----------------------------------------------------------------------------*/
|
||||
void osd_event_free(osd_event *event);
|
||||
|
||||
//============================================================
|
||||
// Scalable Locks
|
||||
//============================================================
|
||||
|
@ -83,7 +83,7 @@ struct work_thread_info
|
||||
{
|
||||
osd_work_queue * queue; // pointer back to the queue
|
||||
HANDLE handle; // handle to the thread
|
||||
HANDLE wakeevent; // wake event for the thread
|
||||
osd_event * wakeevent; // wake event for the thread
|
||||
volatile INT32 active; // are we actively processing work?
|
||||
|
||||
#if KEEP_STATISTICS
|
||||
@ -109,7 +109,7 @@ struct osd_work_queue
|
||||
UINT32 threads; // number of threads in this queue
|
||||
UINT32 flags; // creation flags
|
||||
work_thread_info * thread; // array of thread information
|
||||
HANDLE doneevent; // event signalled when work is complete
|
||||
osd_event * doneevent; // event signalled when work is complete
|
||||
|
||||
#if KEEP_STATISTICS
|
||||
volatile INT32 itemsqueued; // total items queued
|
||||
@ -127,7 +127,7 @@ struct osd_work_item
|
||||
osd_work_callback callback; // callback function
|
||||
void * param; // callback parameter
|
||||
void * result; // callback result
|
||||
HANDLE event; // event signalled when complete
|
||||
osd_event * event; // event signalled when complete
|
||||
UINT32 flags; // creation flags
|
||||
volatile INT32 done; // is the item done?
|
||||
};
|
||||
@ -169,7 +169,7 @@ osd_work_queue *osd_work_queue_alloc(int flags)
|
||||
queue->flags = flags;
|
||||
|
||||
// allocate events for the queue
|
||||
queue->doneevent = CreateEvent(NULL, TRUE, TRUE, NULL); // manual reset, signalled
|
||||
queue->doneevent = osd_event_alloc(TRUE, TRUE); // manual reset, signalled
|
||||
if (queue->doneevent == NULL)
|
||||
goto error;
|
||||
|
||||
@ -214,7 +214,7 @@ osd_work_queue *osd_work_queue_alloc(int flags)
|
||||
thread->queue = queue;
|
||||
|
||||
// create the per-thread wake event
|
||||
thread->wakeevent = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset, not signalled
|
||||
thread->wakeevent = osd_event_alloc(FALSE, FALSE); // auto-reset, not signalled
|
||||
if (thread->wakeevent == NULL)
|
||||
goto error;
|
||||
|
||||
@ -295,10 +295,10 @@ int osd_work_queue_wait(osd_work_queue *queue, osd_ticks_t timeout)
|
||||
}
|
||||
|
||||
// reset our done event and double-check the items before waiting
|
||||
ResetEvent(queue->doneevent);
|
||||
osd_event_reset(queue->doneevent);
|
||||
atomic_exchange32(&queue->waiting, TRUE);
|
||||
if (queue->items != 0)
|
||||
WaitForSingleObject(queue->doneevent, timeout * 1000 / osd_ticks_per_second());
|
||||
osd_event_wait(queue->doneevent, timeout);
|
||||
atomic_exchange32(&queue->waiting, FALSE);
|
||||
|
||||
// return TRUE if we actually hit 0
|
||||
@ -326,7 +326,7 @@ void osd_work_queue_free(osd_work_queue *queue)
|
||||
{
|
||||
work_thread_info *thread = &queue->thread[threadnum];
|
||||
if (thread->wakeevent != NULL)
|
||||
SetEvent(thread->wakeevent);
|
||||
osd_event_set(thread->wakeevent);
|
||||
}
|
||||
|
||||
// wait for all the threads to go away
|
||||
@ -343,7 +343,7 @@ void osd_work_queue_free(osd_work_queue *queue)
|
||||
|
||||
// clean up the wake event
|
||||
if (thread->wakeevent != NULL)
|
||||
CloseHandle(thread->wakeevent);
|
||||
osd_event_free(thread->wakeevent);
|
||||
}
|
||||
|
||||
#if KEEP_STATISTICS
|
||||
@ -368,7 +368,7 @@ void osd_work_queue_free(osd_work_queue *queue)
|
||||
|
||||
// free all the events
|
||||
if (queue->doneevent != NULL)
|
||||
CloseHandle(queue->doneevent);
|
||||
osd_event_free(queue->doneevent);
|
||||
|
||||
// free all items in the free list
|
||||
while (queue->free != NULL)
|
||||
@ -376,7 +376,7 @@ void osd_work_queue_free(osd_work_queue *queue)
|
||||
osd_work_item *item = (osd_work_item *)queue->free;
|
||||
queue->free = item->next;
|
||||
if (item->event != NULL)
|
||||
CloseHandle(item->event);
|
||||
osd_event_free(item->event);
|
||||
osd_free(item);
|
||||
}
|
||||
|
||||
@ -386,7 +386,7 @@ void osd_work_queue_free(osd_work_queue *queue)
|
||||
osd_work_item *item = (osd_work_item *)queue->list;
|
||||
queue->list = item->next;
|
||||
if (item->event != NULL)
|
||||
CloseHandle(item->event);
|
||||
osd_event_free(item->event);
|
||||
osd_free(item);
|
||||
}
|
||||
|
||||
@ -474,7 +474,7 @@ osd_work_item *osd_work_item_queue_multiple(osd_work_queue *queue, osd_work_call
|
||||
// if this thread is not active, wake him up
|
||||
if (!thread->active)
|
||||
{
|
||||
SetEvent(thread->wakeevent);
|
||||
osd_event_set(thread->wakeevent);
|
||||
add_to_stat(&queue->setevents, 1);
|
||||
|
||||
// for non-shared, the first one we find is good enough
|
||||
@ -505,9 +505,9 @@ int osd_work_item_wait(osd_work_item *item, osd_ticks_t timeout)
|
||||
|
||||
// if we don't have an event, create one
|
||||
if (item->event == NULL)
|
||||
item->event = CreateEvent(NULL, TRUE, FALSE, NULL); // manual reset, not signalled
|
||||
item->event = osd_event_alloc(TRUE, FALSE); // manual reset, not signalled
|
||||
else
|
||||
ResetEvent(item->event);
|
||||
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)
|
||||
@ -519,7 +519,7 @@ int osd_work_item_wait(osd_work_item *item, osd_ticks_t timeout)
|
||||
|
||||
// otherwise, block on the event until done
|
||||
else if (!item->done)
|
||||
WaitForSingleObject(item->event, timeout * 1000 / osd_ticks_per_second());
|
||||
osd_event_wait(item->event, timeout);
|
||||
|
||||
// return TRUE if the refcount actually hit 0
|
||||
return item->done;
|
||||
@ -598,11 +598,12 @@ static unsigned __stdcall worker_thread_entry(void *param)
|
||||
// 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);
|
||||
WaitForSingleObject(thread->wakeevent, INFINITE);
|
||||
osd_event_wait(thread->wakeevent, INFINITE);
|
||||
end_timing(thread->waittime);
|
||||
}
|
||||
if (queue->exiting)
|
||||
@ -695,7 +696,7 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa
|
||||
// set the result and signal the event
|
||||
else if (item->event != NULL)
|
||||
{
|
||||
SetEvent(item->event);
|
||||
osd_event_set(item->event);
|
||||
add_to_stat(&item->queue->setevents, 1);
|
||||
}
|
||||
|
||||
@ -708,7 +709,7 @@ static void worker_thread_process(osd_work_queue *queue, work_thread_info *threa
|
||||
// we don't need to set the doneevent for multi queues because they spin
|
||||
if (queue->waiting)
|
||||
{
|
||||
SetEvent(queue->doneevent);
|
||||
osd_event_set(queue->doneevent);
|
||||
add_to_stat(&queue->setevents, 1);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user