~ubuntu-branches/ubuntu/lucid/sdlmame/lucid

« back to all changes in this revision

Viewing changes to src/osd/sdl/sdlsync_tc.c

  • Committer: Bazaar Package Importer
  • Author(s): Cesare Falco
  • Date: 2009-11-03 17:10:15 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20091103171015-6hop4ory5lxnumpn
Tags: 0.135-0ubuntu1
* New upstream release - Closes (LP: #403212)
* debian/watch: unstable releases are no longer detected
* mame.ini: added the cheat subdirectories to cheatpath so zipped
  cheatfiles will be searched too
* renamed crsshair subdirectory to crosshair to reflect upstream change
* mame.ini: renamed references to crosshair subdirectory (see above)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//============================================================
 
2
//
 
3
//  sdlsync.c - SDL core synchronization functions
 
4
//
 
5
//  Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
 
6
//  Visit http://mamedev.org for licensing and usage restrictions.
 
7
//
 
8
//  SDLMAME by Olivier Galibert and R. Belmont
 
9
//
 
10
//============================================================
 
11
 
 
12
#ifndef _GNU_SOURCE
 
13
#define _GNU_SOURCE     // for PTHREAD_MUTEX_RECURSIVE; needs to be here before other glibc headers are included
 
14
#endif
 
15
 
 
16
#include "SDL/SDL.h"
 
17
 
 
18
#ifdef SDLMAME_MACOSX
 
19
#include <mach/mach.h>
 
20
#endif
 
21
 
 
22
// standard C headers
 
23
#include <math.h>
 
24
#include <unistd.h>
 
25
 
 
26
// MAME headers
 
27
#include "osdcore.h"
 
28
#include "osinline.h"
 
29
#include "sdlsync.h"
 
30
 
 
31
#include "eminline.h"
 
32
 
 
33
#include <pthread.h>
 
34
#include <errno.h>
 
35
#include <sys/time.h>
 
36
 
 
37
typedef struct _hidden_mutex_t hidden_mutex_t;
 
38
struct _hidden_mutex_t {
 
39
        pthread_mutex_t id;
 
40
};
 
41
 
 
42
struct _osd_event {
 
43
        pthread_mutex_t         mutex;
 
44
        pthread_cond_t          cond;
 
45
        volatile INT32          autoreset;
 
46
        volatile INT32          signalled;
 
47
#ifdef PTR64
 
48
        INT8                            padding[40];    // Fill a 64-byte cache line
 
49
#else
 
50
        INT8                            padding[48];    // A bit more padding
 
51
#endif
 
52
};
 
53
 
 
54
//============================================================
 
55
//  TYPE DEFINITIONS
 
56
//============================================================
 
57
 
 
58
struct _osd_thread {
 
59
        pthread_t                       thread;
 
60
};
 
61
 
 
62
struct _osd_scalable_lock
 
63
{
 
64
        osd_lock                        *lock;
 
65
};
 
66
 
 
67
//============================================================
 
68
//  Scalable Locks
 
69
//============================================================
 
70
 
 
71
osd_scalable_lock *osd_scalable_lock_alloc(void)
 
72
{
 
73
        osd_scalable_lock *lock;
 
74
        
 
75
        lock = (osd_scalable_lock *)calloc(1, sizeof(*lock));
 
76
 
 
77
        lock->lock = osd_lock_alloc();
 
78
        return lock;
 
79
}
 
80
 
 
81
 
 
82
INT32 osd_scalable_lock_acquire(osd_scalable_lock *lock)
 
83
{
 
84
        osd_lock_acquire(lock->lock);
 
85
        return 0;
 
86
}
 
87
 
 
88
 
 
89
void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot)
 
90
{
 
91
        osd_lock_release(lock->lock);
 
92
}
 
93
 
 
94
void osd_scalable_lock_free(osd_scalable_lock *lock)
 
95
{
 
96
        osd_lock_free(lock->lock);
 
97
        free(lock);
 
98
}
 
99
 
 
100
 
 
101
//============================================================
 
102
//  osd_lock_alloc
 
103
//============================================================
 
104
 
 
105
osd_lock *osd_lock_alloc(void)
 
106
{
 
107
        hidden_mutex_t *mutex;
 
108
        pthread_mutexattr_t mtxattr;
 
109
 
 
110
        mutex = (hidden_mutex_t *)calloc(1, sizeof(hidden_mutex_t));
 
111
 
 
112
        pthread_mutexattr_init(&mtxattr);
 
113
        pthread_mutexattr_settype(&mtxattr, PTHREAD_MUTEX_RECURSIVE);
 
114
        pthread_mutex_init(&mutex->id, &mtxattr);
 
115
 
 
116
        return (osd_lock *)mutex;
 
117
}
 
118
 
 
119
//============================================================
 
120
//  osd_lock_acquire
 
121
//============================================================
 
122
 
 
123
void osd_lock_acquire(osd_lock *lock)
 
124
{
 
125
        hidden_mutex_t *mutex = (hidden_mutex_t *) lock;
 
126
        int r;
 
127
        
 
128
        r =     pthread_mutex_lock(&mutex->id);
 
129
        if (r==0)
 
130
                return;
 
131
        //mame_printf_error("Error on lock: %d: %s\n", r, strerror(r));
 
132
}
 
133
 
 
134
//============================================================
 
135
//  osd_lock_try
 
136
//============================================================
 
137
 
 
138
int osd_lock_try(osd_lock *lock)
 
139
{
 
140
        hidden_mutex_t *mutex = (hidden_mutex_t *) lock;
 
141
        int r;
 
142
        
 
143
        r = pthread_mutex_trylock(&mutex->id);
 
144
        if (r==0)
 
145
                return 1;
 
146
        //if (r!=EBUSY)
 
147
    //  mame_printf_error("Error on trylock: %d: %s\n", r, strerror(r));
 
148
        return 0;
 
149
}
 
150
 
 
151
//============================================================
 
152
//  osd_lock_release
 
153
//============================================================
 
154
 
 
155
void osd_lock_release(osd_lock *lock)
 
156
{
 
157
        hidden_mutex_t *mutex = (hidden_mutex_t *) lock;
 
158
 
 
159
        pthread_mutex_unlock(&mutex->id);
 
160
}
 
161
 
 
162
//============================================================
 
163
//  osd_lock_free
 
164
//============================================================
 
165
 
 
166
void osd_lock_free(osd_lock *lock)
 
167
{
 
168
        hidden_mutex_t *mutex = (hidden_mutex_t *) lock;
 
169
 
 
170
        pthread_mutex_unlock(&mutex->id);
 
171
        pthread_mutex_destroy(&mutex->id);
 
172
        free(mutex);
 
173
}
 
174
 
 
175
//============================================================
 
176
//  osd_event_alloc
 
177
//============================================================
 
178
 
 
179
osd_event *osd_event_alloc(int manualreset, int initialstate)
 
180
{
 
181
        osd_event *ev;
 
182
        pthread_mutexattr_t mtxattr;
 
183
 
 
184
        ev = (osd_event *)calloc(1, sizeof(osd_event));
 
185
 
 
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;
 
191
                
 
192
        return ev;
 
193
}
 
194
 
 
195
//============================================================
 
196
//  osd_event_free
 
197
//============================================================
 
198
 
 
199
void osd_event_free(osd_event *event)
 
200
{
 
201
        pthread_mutex_destroy(&event->mutex);
 
202
        pthread_cond_destroy(&event->cond);
 
203
        free(event);
 
204
}
 
205
 
 
206
//============================================================
 
207
//  osd_event_set
 
208
//============================================================
 
209
 
 
210
void osd_event_set(osd_event *event)
 
211
{
 
212
        pthread_mutex_lock(&event->mutex);
 
213
        if (event->signalled == FALSE)
 
214
        {
 
215
                event->signalled = TRUE;
 
216
                if (event->autoreset)
 
217
                        pthread_cond_signal(&event->cond);
 
218
                else
 
219
                        pthread_cond_broadcast(&event->cond);
 
220
        }
 
221
        pthread_mutex_unlock(&event->mutex);
 
222
}
 
223
 
 
224
//============================================================
 
225
//  osd_event_reset
 
226
//============================================================
 
227
 
 
228
void osd_event_reset(osd_event *event)
 
229
{
 
230
        pthread_mutex_lock(&event->mutex);
 
231
        event->signalled = FALSE;
 
232
        pthread_mutex_unlock(&event->mutex);
 
233
}
 
234
 
 
235
//============================================================
 
236
//  osd_event_wait
 
237
//============================================================
 
238
 
 
239
int osd_event_wait(osd_event *event, osd_ticks_t timeout)
 
240
{
 
241
        pthread_mutex_lock(&event->mutex);
 
242
        if (!timeout)
 
243
        {
 
244
                if (!event->signalled)
 
245
                {
 
246
                                pthread_mutex_unlock(&event->mutex);
 
247
                                return FALSE;
 
248
                }
 
249
        }
 
250
        else
 
251
        {
 
252
                if (!event->signalled)
 
253
                {
 
254
                        struct timespec   ts;
 
255
                        struct timeval    tp;
 
256
                        UINT64 msec = timeout * 1000 / osd_ticks_per_second();
 
257
                        UINT64 nsec;
 
258
                        
 
259
                        gettimeofday(&tp, NULL);
 
260
        
 
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;
 
265
 
 
266
                        do {
 
267
                                int ret = pthread_cond_timedwait(&event->cond, &event->mutex, &ts);
 
268
                                if ( ret == ETIMEDOUT )
 
269
                                {
 
270
                                        if (!event->signalled)
 
271
                                        {
 
272
                                                pthread_mutex_unlock(&event->mutex);
 
273
                                                return FALSE;
 
274
                                        }
 
275
                                        else
 
276
                                                break;
 
277
                                }
 
278
                                if (ret == 0)
 
279
                                        break;
 
280
                                if ( ret != EINTR)
 
281
                                {
 
282
                                        printf("Error %d while waiting for pthread_cond_timedwait:  %s\n", ret, strerror(ret));
 
283
                                }
 
284
                                
 
285
                        } while (TRUE);
 
286
                }
 
287
        }
 
288
 
 
289
        if (event->autoreset)
 
290
                event->signalled = 0;
 
291
 
 
292
        pthread_mutex_unlock(&event->mutex);
 
293
 
 
294
        return TRUE;
 
295
}
 
296
 
 
297
//============================================================
 
298
//  osd_thread_create
 
299
//============================================================
 
300
 
 
301
osd_thread *osd_thread_create(osd_thread_callback callback, void *cbparam)
 
302
{
 
303
        osd_thread *thread;
 
304
        pthread_attr_t  attr;
 
305
 
 
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 )
 
310
        {
 
311
                free(thread);
 
312
                return NULL;
 
313
        }
 
314
        return thread;
 
315
}
 
316
 
 
317
//============================================================
 
318
//  osd_thread_adjust_priority
 
319
//============================================================
 
320
 
 
321
int osd_thread_adjust_priority(osd_thread *thread, int adjust)
 
322
{
 
323
        struct sched_param      sched;
 
324
        int                                     policy;
 
325
                        
 
326
        if ( pthread_getschedparam( thread->thread, &policy, &sched ) == 0 )
 
327
        {
 
328
                sched.sched_priority += adjust;
 
329
                if ( pthread_setschedparam(thread->thread, policy, &sched ) == 0)
 
330
                        return TRUE;
 
331
                else
 
332
                        return FALSE;
 
333
        }
 
334
        else
 
335
                return FALSE;
 
336
}
 
337
 
 
338
//============================================================
 
339
//  osd_thread_cpu_affinity
 
340
//============================================================
 
341
 
 
342
int osd_thread_cpu_affinity(osd_thread *thread, UINT32 mask)
 
343
{
 
344
#if !defined(NO_AFFINITY_NP)
 
345
        cpu_set_t       cmask;
 
346
        pthread_t       lthread;
 
347
        int                     bitnum;
 
348
 
 
349
        CPU_ZERO(&cmask);
 
350
        for (bitnum=0; bitnum<32; bitnum++)
 
351
                if (mask & (1<<bitnum))
 
352
                        CPU_SET(bitnum, &cmask);
 
353
        
 
354
        if (thread == NULL)
 
355
                lthread = pthread_self();
 
356
        else
 
357
                lthread = thread->thread;
 
358
    
 
359
        if (pthread_setaffinity_np(lthread, sizeof(cmask), &cmask) <0)
 
360
        {
 
361
                /* Not available during link in all targets */
 
362
                fprintf(stderr, "error %d setting cpu affinity to mask %08x", errno, mask);
 
363
                return FALSE;
 
364
        }
 
365
        else
 
366
                return TRUE;
 
367
#else
 
368
        return TRUE;
 
369
#endif
 
370
}
 
371
 
 
372
//============================================================
 
373
//  osd_thread_wait_free
 
374
//============================================================
 
375
 
 
376
void osd_thread_wait_free(osd_thread *thread)
 
377
{
 
378
        pthread_join(thread->thread, NULL);
 
379
        free(thread);
 
380
}
 
381