Previous 199869 Revisions Next

r32109 Saturday 13th September, 2014 at 19:44:41 UTC by Oliver Stöneberg
more work to make sdlwork.c and winwork.c match / un-broke Windows SDL build by completely moving the sdlsync_win32.c code to winsync.c (nw)
[src/osd/sdl]sdlsync_win32.c
[src/osd/windows]winsync.c winsync.h winwork.c

trunk/src/osd/sdl/sdlsync_win32.c
r32108r32109
99//
1010//============================================================
1111
12#define WIN32_LEAN_AND_MEAN
13#include <windows.h>
14#include <process.h>
15#include <tchar.h>
16
17#ifdef __GNUC__
18#include <stdint.h>
19#endif
20
21// MAME headers
22#include "osdcore.h"
23#include "osinline.h"
24#include "sdlsync.h"
25
26#include "../windows/winsync.c"
27
28
29//============================================================
30//  DEBUGGING
31//============================================================
32
33#define USE_SCALABLE_LOCKS      (0)
34
35
36//============================================================
37//  TYPE DEFINITIONS
38//============================================================
39
40struct osd_event
41{
42   void *  ptr;
43};
44
45struct osd_thread {
46   HANDLE handle;
47   osd_thread_callback callback;
48   void *param;
49};
50
51//============================================================
52//  osd_event_alloc
53//============================================================
54
55osd_event *osd_event_alloc(int manualreset, int initialstate)
56{
57   return (osd_event *) CreateEvent(NULL, manualreset, initialstate, NULL);
58}
59
60//============================================================
61//  osd_event_free
62//============================================================
63
64void osd_event_free(osd_event *event)
65{
66   CloseHandle((HANDLE) event);
67}
68
69//============================================================
70//  osd_event_set
71//============================================================
72
73void osd_event_set(osd_event *event)
74{
75   SetEvent((HANDLE) event);
76}
77
78//============================================================
79//  osd_event_reset
80//============================================================
81
82void osd_event_reset(osd_event *event)
83{
84   ResetEvent((HANDLE) event);
85}
86
87//============================================================
88//  osd_event_wait
89//============================================================
90
91int osd_event_wait(osd_event *event, osd_ticks_t timeout)
92{
93   int ret = WaitForSingleObject((HANDLE) event, timeout * 1000 / osd_ticks_per_second());
94   return ( ret == WAIT_OBJECT_0);
95}
96
97//============================================================
98//  Scalable Locks
99//============================================================
100
101struct osd_scalable_lock
102{
103#if USE_SCALABLE_LOCKS
104   struct
105   {
106      volatile INT32  haslock;        // do we have the lock?
107      INT32           filler[64/4-1]; // assumes a 64-byte cache line
108   } slot[WORK_MAX_THREADS];           // one slot per thread
109   volatile INT32      nextindex;      // index of next slot to use
110#else
111   CRITICAL_SECTION    section;
112#endif
113};
114
115osd_scalable_lock *osd_scalable_lock_alloc(void)
116{
117   osd_scalable_lock *lock;
118
119   lock = (osd_scalable_lock *)calloc(1, sizeof(*lock));
120
121   memset(lock, 0, sizeof(*lock));
122#if USE_SCALABLE_LOCKS
123   lock->slot[0].haslock = TRUE;
124#else
125   InitializeCriticalSection(&lock->section);
126#endif
127   return lock;
128}
129
130
131INT32 osd_scalable_lock_acquire(osd_scalable_lock *lock)
132{
133#if USE_SCALABLE_LOCKS
134   INT32 myslot = (interlocked_increment(&lock->nextindex) - 1) & (WORK_MAX_THREADS - 1);
135   INT32 backoff = 1;
136
137   while (!lock->slot[myslot].haslock)
138   {
139      INT32 backcount;
140      for (backcount = 0; backcount < backoff; backcount++)
141         YieldProcessor();
142      backoff <<= 1;
143   }
144   lock->slot[myslot].haslock = FALSE;
145   return myslot;
146#else
147   EnterCriticalSection(&lock->section);
148   return 0;
149#endif
150}
151
152
153void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot)
154{
155#if USE_SCALABLE_LOCKS
156   interlocked_exchange32(&lock->slot[(myslot + 1) & (WORK_MAX_THREADS - 1)].haslock, TRUE);
157#else
158   LeaveCriticalSection(&lock->section);
159#endif
160}
161
162void osd_scalable_lock_free(osd_scalable_lock *lock)
163{
164#if USE_SCALABLE_LOCKS
165#else
166   DeleteCriticalSection(&lock->section);
167#endif
168   free(lock);
169}
170
171//============================================================
172//  osd_thread_create
173//============================================================
174
175static unsigned __stdcall worker_thread_entry(void *param)
176{
177   osd_thread *thread = (osd_thread *) param;
178   void *res;
179   res = thread->callback(thread->param);
180#ifdef PTR64
181   return (unsigned) (long long) res;
182#else
183   return (unsigned) res;
184#endif
185}
186
187osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam)
188{
189   osd_thread *thread;
190   uintptr_t handle;
191
192   thread = (osd_thread *)calloc(1, sizeof(osd_thread));
193   thread->callback = callback;
194   thread->param = cbparam;
195   handle = _beginthreadex(NULL, 0, worker_thread_entry, thread, 0, NULL);
196   thread->handle = (HANDLE) handle;
197   return thread;
198}
199
200//============================================================
201//  osd_thread_wait_free
202//============================================================
203
204void osd_thread_wait_free(osd_thread *thread)
205{
206   WaitForSingleObject(thread->handle, INFINITE);
207   CloseHandle(thread->handle);
208   free(thread);
209}
210
211//============================================================
212//  osd_thread_adjust_priority
213//============================================================
214
215int osd_thread_adjust_priority(osd_thread *thread, int adjust)
216{
217   if (adjust)
218      SetThreadPriority(thread->handle, THREAD_PRIORITY_ABOVE_NORMAL);
219   else
220      SetThreadPriority(thread->handle, GetThreadPriority(GetCurrentThread()));
221   return TRUE;
222}
223
224//============================================================
225//  osd_thread_cpu_affinity
226//============================================================
227
228int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask)
229{
230   return TRUE;
231}
232
233//============================================================
234//  osd_process_kill
235//============================================================
236
237void osd_process_kill(void)
238{
239   TerminateProcess(GetCurrentProcess(), -1);
240}
12#include "../windows/winsync.c"
No newline at end of file
trunk/src/osd/windows/winsync.c
r32108r32109
1010#define WIN32_LEAN_AND_MEAN
1111#include <windows.h>
1212#include <stdlib.h>
13#include <process.h>
1314
1415// MAME headers
1516#include "osdcore.h"
1617#include "osinline.h"
18#include "winsync.h"
1719
1820
1921//============================================================
r32108r32109
4143   void *  ptr;
4244};
4345
46struct osd_thread {
47   HANDLE handle;
48   osd_thread_callback callback;
49   void *param;
50};
51
4452struct osd_scalable_lock
4553{
4654#if USE_SCALABLE_LOCKS
r32108r32109
236244}
237245
238246//============================================================
247//  osd_thread_create
248//============================================================
249
250static unsigned __stdcall worker_thread_entry(void *param)
251{
252   osd_thread *thread = (osd_thread *) param;
253   void *res;
254   res = thread->callback(thread->param);
255#ifdef PTR64
256   return (unsigned) (long long) res;
257#else
258   return (unsigned) res;
259#endif
260}
261
262osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam)
263{
264   osd_thread *thread;
265   uintptr_t handle;
266
267   thread = (osd_thread *)calloc(1, sizeof(osd_thread));
268   thread->callback = callback;
269   thread->param = cbparam;
270   handle = _beginthreadex(NULL, 0, worker_thread_entry, thread, 0, NULL);
271   thread->handle = (HANDLE) handle;
272   return thread;
273}
274
275//============================================================
276//  osd_thread_wait_free
277//============================================================
278
279void osd_thread_wait_free(osd_thread *thread)
280{
281   WaitForSingleObject(thread->handle, INFINITE);
282   CloseHandle(thread->handle);
283   free(thread);
284}
285
286//============================================================
287//  osd_thread_adjust_priority
288//============================================================
289
290int osd_thread_adjust_priority(osd_thread *thread, int adjust)
291{
292   if (adjust)
293      SetThreadPriority(thread->handle, THREAD_PRIORITY_ABOVE_NORMAL);
294   else
295      SetThreadPriority(thread->handle, GetThreadPriority(GetCurrentThread()));
296   return TRUE;
297}
298
299//============================================================
300//  osd_thread_cpu_affinity
301//============================================================
302
303int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask)
304{
305   return TRUE;
306}
307
308//============================================================
309//  osd_process_kill
310//============================================================
311
312void osd_process_kill(void)
313{
314   TerminateProcess(GetCurrentProcess(), -1);
315}
316
317//============================================================
239318//  Scalable Locks
240319//============================================================
241320
trunk/src/osd/windows/winsync.h
r32108r32109
9999-----------------------------------------------------------------------------*/
100100void osd_event_free(osd_event *event);
101101
102/***************************************************************************
103    SYNCHRONIZATION INTERFACES - Threads
104***************************************************************************/
105
106/* osd_thread is an opaque type which represents a thread */
107struct osd_thread;
108
109
110/* osd_thread_callback is a callback function that will be called from the thread */
111typedef void *(*osd_thread_callback)(void *param);
112
113
114/*-----------------------------------------------------------------------------
115    osd_thread_create: create a new thread
116
117    Parameters:
118
119        callback - The callback function to be called once the thread is up
120        cbparam  - The parameter to pass to the callback function.
121
122    Return value:
123
124        A pointer to the created thread.
125-----------------------------------------------------------------------------*/
126osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam);
127
128/*-----------------------------------------------------------------------------
129    osd_thread_adjust_priority: adjust priority of a thread
130
131    Parameters:
132
133        thread - A pointer to a previously created thread.
134        adjust - signed integer to add to the thread priority
135
136    Return value:
137
138        TRUE on success, FALSE on failure
139-----------------------------------------------------------------------------*/
140int osd_thread_adjust_priority(osd_thread *thread, int adjust);
141
142
143/*-----------------------------------------------------------------------------
144    osd_thread_cpu_affinity: change cpu affinity of a thread
145
146    Parameters:
147
148        thread - A pointer to a previously created thread
149                 or NULL for main thread
150        mask   - bitmask to which cpus to bind
151                 i.e. 0x01 1st cpu, 0x02, 2nd cpu, 0x04 3rd cpu
152
153    Return value:
154
155        TRUE on success, FALSE on failure
156-----------------------------------------------------------------------------*/
157int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask);
158
159
160/*-----------------------------------------------------------------------------
161    osd_thread_wait_free: wait for thread to finish and free resources
162
163    Parameters:
164
165        thread - A pointer to a previously created thread.
166
167    Return value:
168
169        None.
170-----------------------------------------------------------------------------*/
171void osd_thread_wait_free(osd_thread *thread);
172
173/*-----------------------------------------------------------------------------
174    osd_process_kill: kill the current process
175
176    Parameters:
177
178        None.
179
180    Return value:
181
182        None.
183-----------------------------------------------------------------------------*/
184void osd_process_kill(void);
185
102186//============================================================
103187//  Scalable Locks
104188//============================================================
trunk/src/osd/windows/winwork.c
r32108r32109
8282struct work_thread_info
8383{
8484   osd_work_queue *    queue;          // pointer back to the queue
85   HANDLE              handle;         // handle to the thread
85   osd_thread *        handle;         // handle to the thread
8686   osd_event *         wakeevent;      // wake event for the thread
8787   volatile INT32      active;         // are we actively processing work?
8888
r32108r32109
143143//============================================================
144144
145145static int effective_num_processors(void);
146static unsigned __stdcall worker_thread_entry(void *param);
146static void * worker_thread_entry(void *param);
147147static void worker_thread_process(osd_work_queue *queue, work_thread_info *thread);
148148
149149
r32108r32109
208208   for (threadnum = 0; threadnum < queue->threads; threadnum++)
209209   {
210210      work_thread_info *thread = &queue->thread[threadnum];
211      uintptr_t handle;
212211
213212      // set a pointer back to the queue
214213      thread->queue = queue;
r32108r32109
219218         goto error;
220219
221220      // create the thread
222      handle = _beginthreadex(NULL, 0, worker_thread_entry, thread, 0, NULL);
223      thread->handle = (HANDLE)handle;
221      thread->handle = osd_thread_create(worker_thread_entry, thread);
224222      if (thread->handle == NULL)
225223         goto error;
226224
227225      // set its priority: I/O threads get high priority because they are assumed to be
228226      // blocked most of the time; other threads just match the creator's priority
229227      if (flags & WORK_QUEUE_FLAG_IO)
230         SetThreadPriority(thread->handle, THREAD_PRIORITY_ABOVE_NORMAL);
228         osd_thread_adjust_priority(thread->handle, 1);
231229      else
232         SetThreadPriority(thread->handle, GetThreadPriority(GetCurrentThread()));
230         osd_thread_adjust_priority(thread->handle, 0);
233231   }
234232
235233   // start a timer going for "waittime" on the main thread
r32108r32109
337335         // block on the thread going away, then close the handle
338336         if (thread->handle != NULL)
339337         {
340            WaitForSingleObject(thread->handle, INFINITE);
341            CloseHandle(thread->handle);
338            osd_thread_wait_free(thread->handle);
342339         }
343340
344341         // clean up the wake event
r32108r32109
590587//  worker_thread_entry
591588//============================================================
592589
593static unsigned __stdcall worker_thread_entry(void *param)
590static void *worker_thread_entry(void *param)
594591{
595592   work_thread_info *thread = (work_thread_info *)param;
596593   osd_work_queue *queue = thread->queue;
r32108r32109
642639      atomic_exchange32(&thread->active, FALSE);
643640      atomic_decrement32(&queue->livethreads);
644641   }
645   return 0;
642   return NULL;
646643}
647644
648645

Previous 199869 Revisions Next


© 1997-2024 The MAME Team