1
//============================================================
3
// sdlsync.c - SDL core synchronization functions
5
// Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
6
// Visit http://mamedev.org for licensing and usage restrictions.
8
// SDLMAME by Olivier Galibert and R. Belmont
10
//============================================================
13
#define _GNU_SOURCE // for PTHREAD_MUTEX_RECURSIVE; needs to be here before other glibc headers are included
19
#include <mach/mach.h>
37
typedef struct _hidden_mutex_t hidden_mutex_t;
38
struct _hidden_mutex_t {
43
pthread_mutex_t mutex;
45
volatile INT32 autoreset;
46
volatile INT32 signalled;
48
INT8 padding[40]; // Fill a 64-byte cache line
50
INT8 padding[48]; // A bit more padding
54
//============================================================
56
//============================================================
62
struct _osd_scalable_lock
67
//============================================================
69
//============================================================
71
osd_scalable_lock *osd_scalable_lock_alloc(void)
73
osd_scalable_lock *lock;
75
lock = (osd_scalable_lock *)calloc(1, sizeof(*lock));
77
lock->lock = osd_lock_alloc();
82
INT32 osd_scalable_lock_acquire(osd_scalable_lock *lock)
84
osd_lock_acquire(lock->lock);
89
void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot)
91
osd_lock_release(lock->lock);
94
void osd_scalable_lock_free(osd_scalable_lock *lock)
96
osd_lock_free(lock->lock);
101
//============================================================
103
//============================================================
105
osd_lock *osd_lock_alloc(void)
107
hidden_mutex_t *mutex;
108
pthread_mutexattr_t mtxattr;
110
mutex = (hidden_mutex_t *)calloc(1, sizeof(hidden_mutex_t));
112
pthread_mutexattr_init(&mtxattr);
113
pthread_mutexattr_settype(&mtxattr, PTHREAD_MUTEX_RECURSIVE);
114
pthread_mutex_init(&mutex->id, &mtxattr);
116
return (osd_lock *)mutex;
119
//============================================================
121
//============================================================
123
void osd_lock_acquire(osd_lock *lock)
125
hidden_mutex_t *mutex = (hidden_mutex_t *) lock;
128
r = pthread_mutex_lock(&mutex->id);
131
//mame_printf_error("Error on lock: %d: %s\n", r, strerror(r));
134
//============================================================
136
//============================================================
138
int osd_lock_try(osd_lock *lock)
140
hidden_mutex_t *mutex = (hidden_mutex_t *) lock;
143
r = pthread_mutex_trylock(&mutex->id);
147
// mame_printf_error("Error on trylock: %d: %s\n", r, strerror(r));
151
//============================================================
153
//============================================================
155
void osd_lock_release(osd_lock *lock)
157
hidden_mutex_t *mutex = (hidden_mutex_t *) lock;
159
pthread_mutex_unlock(&mutex->id);
162
//============================================================
164
//============================================================
166
void osd_lock_free(osd_lock *lock)
168
hidden_mutex_t *mutex = (hidden_mutex_t *) lock;
170
pthread_mutex_unlock(&mutex->id);
171
pthread_mutex_destroy(&mutex->id);
175
//============================================================
177
//============================================================
179
osd_event *osd_event_alloc(int manualreset, int initialstate)
182
pthread_mutexattr_t mtxattr;
184
ev = (osd_event *)calloc(1, sizeof(osd_event));
186
pthread_mutexattr_init(&mtxattr);
187
pthread_mutex_init(&ev->mutex, &mtxattr);
188
pthread_cond_init(&ev->cond, NULL);
189
ev->signalled = initialstate;
190
ev->autoreset = !manualreset;
195
//============================================================
197
//============================================================
199
void osd_event_free(osd_event *event)
201
pthread_mutex_destroy(&event->mutex);
202
pthread_cond_destroy(&event->cond);
206
//============================================================
208
//============================================================
210
void osd_event_set(osd_event *event)
212
pthread_mutex_lock(&event->mutex);
213
if (event->signalled == FALSE)
215
event->signalled = TRUE;
216
if (event->autoreset)
217
pthread_cond_signal(&event->cond);
219
pthread_cond_broadcast(&event->cond);
221
pthread_mutex_unlock(&event->mutex);
224
//============================================================
226
//============================================================
228
void osd_event_reset(osd_event *event)
230
pthread_mutex_lock(&event->mutex);
231
event->signalled = FALSE;
232
pthread_mutex_unlock(&event->mutex);
235
//============================================================
237
//============================================================
239
int osd_event_wait(osd_event *event, osd_ticks_t timeout)
241
pthread_mutex_lock(&event->mutex);
244
if (!event->signalled)
246
pthread_mutex_unlock(&event->mutex);
252
if (!event->signalled)
256
UINT64 msec = timeout * 1000 / osd_ticks_per_second();
259
gettimeofday(&tp, NULL);
261
ts.tv_sec = tp.tv_sec;
262
nsec = (UINT64) tp.tv_usec * (UINT64) 1000 + (msec * (UINT64) 1000000);
263
ts.tv_nsec = nsec % (UINT64) 1000000000;
264
ts.tv_sec += nsec / (UINT64) 1000000000;
267
int ret = pthread_cond_timedwait(&event->cond, &event->mutex, &ts);
268
if ( ret == ETIMEDOUT )
270
if (!event->signalled)
272
pthread_mutex_unlock(&event->mutex);
282
printf("Error %d while waiting for pthread_cond_timedwait: %s\n", ret, strerror(ret));
289
if (event->autoreset)
290
event->signalled = 0;
292
pthread_mutex_unlock(&event->mutex);
297
//============================================================
299
//============================================================
301
osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam)
306
thread = (osd_thread *)calloc(1, sizeof(osd_thread));
307
pthread_attr_init(&attr);
308
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
309
if ( pthread_create(&thread->thread, &attr, callback, cbparam) != 0 )
317
//============================================================
318
// osd_thread_adjust_priority
319
//============================================================
321
int osd_thread_adjust_priority(osd_thread *thread, int adjust)
323
struct sched_param sched;
326
if ( pthread_getschedparam( thread->thread, &policy, &sched ) == 0 )
328
sched.sched_priority += adjust;
329
if ( pthread_setschedparam(thread->thread, policy, &sched ) == 0)
338
//============================================================
339
// osd_thread_cpu_affinity
340
//============================================================
342
int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask)
344
#if !defined(NO_AFFINITY_NP)
350
for (bitnum=0; bitnum<32; bitnum++)
351
if (mask & (1<<bitnum))
352
CPU_SET(bitnum, &cmask);
355
lthread = pthread_self();
357
lthread = thread->thread;
359
if (pthread_setaffinity_np(lthread, sizeof(cmask), &cmask) <0)
361
/* Not available during link in all targets */
362
fprintf(stderr, "error %d setting cpu affinity to mask %08x", errno, mask);
372
//============================================================
373
// osd_thread_wait_free
374
//============================================================
376
void osd_thread_wait_free(osd_thread *thread)
378
pthread_join(thread->thread, NULL);