Previous 199869 Revisions Next

r32098 Saturday 13th September, 2014 at 10:23:17 UTC by Oliver Stöneberg
more work to make sdlwork.c and winwork.c match (nw)
[src/osd/windows]winsync.c winsync.h winwork.c

trunk/src/osd/windows/winsync.c
r32097r32098
3636   CRITICAL_SECTION    critsect;
3737};
3838
39struct osd_event
40{
41   void *  ptr;
42};
43
3944struct osd_scalable_lock
4045{
4146#if USE_SCALABLE_LOCKS
r32097r32098
185190}
186191
187192//============================================================
193//  osd_event_alloc
194//============================================================
195
196osd_event *osd_event_alloc(int manualreset, int initialstate)
197{
198   return (osd_event *) CreateEvent(NULL, manualreset, initialstate, NULL);
199}
200
201//============================================================
202//  osd_event_free
203//============================================================
204
205void osd_event_free(osd_event *event)
206{
207   CloseHandle((HANDLE) event);
208}
209
210//============================================================
211//  osd_event_set
212//============================================================
213
214void osd_event_set(osd_event *event)
215{
216   SetEvent((HANDLE) event);
217}
218
219//============================================================
220//  osd_event_reset
221//============================================================
222
223void osd_event_reset(osd_event *event)
224{
225   ResetEvent((HANDLE) event);
226}
227
228//============================================================
229//  osd_event_wait
230//============================================================
231
232int osd_event_wait(osd_event *event, osd_ticks_t timeout)
233{
234   int ret = WaitForSingleObject((HANDLE) event, timeout * 1000 / osd_ticks_per_second());
235   return ( ret == WAIT_OBJECT_0);
236}
237
238//============================================================
188239//  Scalable Locks
189240//============================================================
190241
trunk/src/osd/windows/winsync.h
r32097r32098
1010#ifndef __WINSYNC__
1111#define __WINSYNC__
1212
13/***************************************************************************
14    SYNCHRONIZATION INTERFACES - Events
15***************************************************************************/
16
17/* osd_event is an opaque type which represents a setable/resetable event */
18
19struct osd_event;
20
21
22/*-----------------------------------------------------------------------------
23    osd_lock_event_alloc: allocate a new event
24
25    Parameters:
26
27        manualreset  - boolean. If true, the event will be automatically set
28                       to non-signalled after a thread successfully waited for
29                       it.
30        initialstate - boolean. If true, the event is signalled initially.
31
32    Return value:
33
34        A pointer to the allocated event.
35-----------------------------------------------------------------------------*/
36osd_event *osd_event_alloc(int manualreset, int initialstate);
37
38
39/*-----------------------------------------------------------------------------
40    osd_event_wait: wait for an event to be signalled
41
42    Parameters:
43
44        event - The event to wait for. If the event is in signalled state, the
45                function returns immediately. If not it will wait for the event
46                to become signalled.
47        timeout - timeout in osd_ticks
48
49    Return value:
50
51        TRUE:  The event was signalled
52        FALSE: A timeout occurred
53-----------------------------------------------------------------------------*/
54int osd_event_wait(osd_event *event, osd_ticks_t timeout);
55
56
57/*-----------------------------------------------------------------------------
58    osd_event_reset: reset an event to non-signalled state
59
60    Parameters:
61
62        event - The event to set to non-signalled state
63
64    Return value:
65
66        None
67-----------------------------------------------------------------------------*/
68void osd_event_reset(osd_event *event);
69
70
71/*-----------------------------------------------------------------------------
72    osd_event_set: set an event to signalled state
73
74    Parameters:
75
76        event - The event to set to signalled state
77
78    Return value:
79
80        None
81
82    Notes:
83
84        All threads waiting for the event will be signalled.
85-----------------------------------------------------------------------------*/
86void osd_event_set(osd_event *event);
87
88
89/*-----------------------------------------------------------------------------
90    osd_event_free: free the memory and resources associated with an osd_event
91
92    Parameters:
93
94        event - a pointer to a previously allocated osd_event.
95
96    Return value:
97
98        None.
99-----------------------------------------------------------------------------*/
100void osd_event_free(osd_event *event);
101
13102//============================================================
14103//  Scalable Locks
15104//============================================================
trunk/src/osd/windows/winwork.c
r32097r32098
8383{
8484   osd_work_queue *    queue;          // pointer back to the queue
8585   HANDLE              handle;         // handle to the thread
86   HANDLE              wakeevent;      // wake event for the thread
86   osd_event *         wakeevent;      // wake event for the thread
8787   volatile INT32      active;         // are we actively processing work?
8888
8989#if KEEP_STATISTICS
r32097r32098
109109   UINT32              threads;        // number of threads in this queue
110110   UINT32              flags;          // creation flags
111111   work_thread_info *  thread;         // array of thread information
112   HANDLE              doneevent;      // event signalled when work is complete
112   osd_event   *       doneevent;      // event signalled when work is complete
113113
114114#if KEEP_STATISTICS
115115   volatile INT32      itemsqueued;    // total items queued
r32097r32098
127127   osd_work_callback   callback;       // callback function
128128   void *              param;          // callback parameter
129129   void *              result;         // callback result
130   HANDLE              event;          // event signalled when complete
130   osd_event *         event;          // event signalled when complete
131131   UINT32              flags;          // creation flags
132132   volatile INT32      done;           // is the item done?
133133};
r32097r32098
169169   queue->flags = flags;
170170
171171   // allocate events for the queue
172   queue->doneevent = CreateEvent(NULL, TRUE, TRUE, NULL);     // manual reset, signalled
172   queue->doneevent = osd_event_alloc(TRUE, TRUE);     // manual reset, signalled
173173   if (queue->doneevent == NULL)
174174      goto error;
175175
r32097r32098
214214      thread->queue = queue;
215215
216216      // create the per-thread wake event
217      thread->wakeevent = CreateEvent(NULL, FALSE, FALSE, NULL);  // auto-reset, not signalled
217      thread->wakeevent = osd_event_alloc(FALSE, FALSE);  // auto-reset, not signalled
218218      if (thread->wakeevent == NULL)
219219         goto error;
220220
r32097r32098
295295   }
296296
297297   // reset our done event and double-check the items before waiting
298   ResetEvent(queue->doneevent);
298   osd_event_reset(queue->doneevent);
299299   atomic_exchange32(&queue->waiting, TRUE);
300300   if (queue->items != 0)
301      WaitForSingleObject(queue->doneevent, timeout * 1000 / osd_ticks_per_second());
301      osd_event_wait(queue->doneevent, timeout);
302302   atomic_exchange32(&queue->waiting, FALSE);
303303
304304   // return TRUE if we actually hit 0
r32097r32098
326326      {
327327         work_thread_info *thread = &queue->thread[threadnum];
328328         if (thread->wakeevent != NULL)
329            SetEvent(thread->wakeevent);
329            osd_event_set(thread->wakeevent);
330330      }
331331
332332      // wait for all the threads to go away
r32097r32098
343343
344344         // clean up the wake event
345345         if (thread->wakeevent != NULL)
346            CloseHandle(thread->wakeevent);
346            osd_event_free(thread->wakeevent);
347347      }
348348
349349#if KEEP_STATISTICS
r32097r32098
368368
369369   // free all the events
370370   if (queue->doneevent != NULL)
371      CloseHandle(queue->doneevent);
371      osd_event_free(queue->doneevent);
372372
373373   // free all items in the free list
374374   while (queue->free != NULL)
r32097r32098
376376      osd_work_item *item = (osd_work_item *)queue->free;
377377      queue->free = item->next;
378378      if (item->event != NULL)
379         CloseHandle(item->event);
379         osd_event_free(item->event);
380380      osd_free(item);
381381   }
382382
r32097r32098
386386      osd_work_item *item = (osd_work_item *)queue->list;
387387      queue->list = item->next;
388388      if (item->event != NULL)
389         CloseHandle(item->event);
389         osd_event_free(item->event);
390390      osd_free(item);
391391   }
392392
r32097r32098
474474         // if this thread is not active, wake him up
475475         if (!thread->active)
476476         {
477            SetEvent(thread->wakeevent);
477            osd_event_set(thread->wakeevent);
478478            add_to_stat(&queue->setevents, 1);
479479
480480            // for non-shared, the first one we find is good enough
r32097r32098
505505
506506   // if we don't have an event, create one
507507   if (item->event == NULL)
508      item->event = CreateEvent(NULL, TRUE, FALSE, NULL);     // manual reset, not signalled
508      item->event = osd_event_alloc(TRUE, FALSE);     // manual reset, not signalled
509509   else
510      ResetEvent(item->event);
510         osd_event_reset(item->event);
511511
512512   // if we don't have an event, we need to spin (shouldn't ever really happen)
513513   if (item->event == NULL)
r32097r32098
519519
520520   // otherwise, block on the event until done
521521   else if (!item->done)
522      WaitForSingleObject(item->event, timeout * 1000 / osd_ticks_per_second());
522      osd_event_wait(item->event, timeout);
523523
524524   // return TRUE if the refcount actually hit 0
525525   return item->done;
r32097r32098
598598   // loop until we exit
599599   for ( ;; )
600600   {
601      // block waiting for work or exit
601602      // bail on exit, and only wait if there are no pending items in queue
602603      if (!queue->exiting && queue->list == NULL)
603604      {
604605         begin_timing(thread->waittime);
605         WaitForSingleObject(thread->wakeevent, INFINITE);
606         osd_event_wait(thread->wakeevent, INFINITE);
606607         end_timing(thread->waittime);
607608      }
608609      if (queue->exiting)
r32097r32098
695696         // set the result and signal the event
696697         else if (item->event != NULL)
697698         {
698            SetEvent(item->event);
699            osd_event_set(item->event);
699700            add_to_stat(&item->queue->setevents, 1);
700701         }
701702
r32097r32098
708709   // we don't need to set the doneevent for multi queues because they spin
709710   if (queue->waiting)
710711   {
711      SetEvent(queue->doneevent);
712      osd_event_set(queue->doneevent);
712713      add_to_stat(&queue->setevents, 1);
713714   }
714715

Previous 199869 Revisions Next


© 1997-2024 The MAME Team