1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * Threading support, using pthreads
5 *
6 * Copyright 1997 Bernd Schmidt
7 * Copyright 2004 Richard Drummond
8 *
9 * This handles initialization when using named semaphores.
10 * Idea stolen from SDL.
11 */
12 #ifdef _WIN32
13 #define WIN32_LEAN_AND_MEAN
14 #include <windows.h>
15 #include <process.h>
16
17 #include "sysconfig.h"
18 #include "sysdeps.h"
19
20 #include "thread.h"
uae_sem_init(uae_sem_t * event,int manual_reset,int initial_state)21 void uae_sem_init (uae_sem_t * event, int manual_reset, int initial_state)
22 {
23 if(*event) {
24 if (initial_state)
25 SetEvent (*event);
26 else
27 ResetEvent (*event);
28 } else {
29 *event = CreateEvent (NULL, manual_reset, initial_state, NULL);
30 }
31 }
32
uae_sem_wait(uae_sem_t * event)33 void uae_sem_wait (uae_sem_t * event)
34 {
35 WaitForSingleObject (*event, INFINITE);
36 }
37
uae_sem_post(uae_sem_t * event)38 void uae_sem_post (uae_sem_t * event)
39 {
40 SetEvent (*event);
41 }
42
uae_sem_trywait(uae_sem_t * event)43 int uae_sem_trywait (uae_sem_t * event)
44 {
45 return WaitForSingleObject (*event, 0) == WAIT_OBJECT_0 ? 0 : -1;
46 }
47
uae_sem_destroy(uae_sem_t * event)48 void uae_sem_destroy (uae_sem_t * event)
49 {
50 if (*event) {
51 CloseHandle (*event);
52 *event = NULL;
53 }
54 }
55
56
57
58 typedef unsigned (__stdcall *BEGINTHREADEX_FUNCPTR)(void *);
59
60 struct thparms
61 {
62 void *(*f)(void*);
63 void *arg;
64 };
65
thread_init(void * f)66 static unsigned __stdcall thread_init (void *f)
67 {
68 struct thparms *thp = (struct thparms*)f;
69 void *(*fp)(void*) = thp->f;
70 void *arg = thp->arg;
71
72 xfree (f);
73
74
75 fp (arg);
76
77
78
79 return 0;
80 }
81
uae_end_thread(uae_thread_id * tid)82 void uae_end_thread (uae_thread_id *tid)
83 {
84 if (tid) {
85 CloseHandle (*tid);
86 *tid = NULL;
87 }
88 }
89
uae_start_thread(const TCHAR * name,void * (* f)(void *),void * arg,uae_thread_id * tid)90 int uae_start_thread (const TCHAR *name, void *(*f)(void *), void *arg, uae_thread_id *tid)
91 {
92 HANDLE hThread;
93 int result = 1;
94 unsigned foo;
95 struct thparms *thp;
96
97 thp = xmalloc (struct thparms, 1);
98 thp->f = f;
99 thp->arg = arg;
100 hThread = (HANDLE)_beginthreadex (NULL, 0, thread_init, thp, 0, &foo);
101 if (hThread) {
102 if (name) {
103 //write_log (_T("Thread '%s' started (%d)\n"), name, hThread);
104
105 SetThreadPriority (hThread, THREAD_PRIORITY_HIGHEST);
106
107 }
108 } else {
109 result = 0;
110 write_log (_T("Thread '%s' failed to start!?\n"), name ? name : _T("<unknown>"));
111 }
112 if (tid)
113 *tid = hThread;
114 else
115 CloseHandle (hThread);
116 return result;
117 }
118
uae_start_thread_fast(void * (* f)(void *),void * arg,uae_thread_id * tid)119 int uae_start_thread_fast (void *(*f)(void *), void *arg, uae_thread_id *tid)
120 {
121 int v = uae_start_thread (NULL, f, arg, tid);
122 if (*tid) {
123 SetThreadPriority (*tid, THREAD_PRIORITY_HIGHEST);
124
125 }
126 return v;
127 }
128
129 DWORD_PTR cpu_affinity = 1, cpu_paffinity = 1;
130
uae_set_thread_priority(uae_thread_id * tid)131 void uae_set_thread_priority (uae_thread_id *tid/*, int pri*/)
132 {
133 #if 0
134 int pri2;
135 HANDLE th;
136
137 if (tid)
138 th = *tid;
139 else
140 th = GetCurrentThread ();
141 pri2 = GetThreadPriority (th);
142 if (pri2 == THREAD_PRIORITY_ERROR_RETURN)
143 pri2 = 0;
144 if (pri > 0)
145 pri2 = THREAD_PRIORITY_HIGHEST;
146 else
147 pri2 = THREAD_PRIORITY_ABOVE_NORMAL;
148 pri2 += pri;
149 if (pri2 > 1)
150 pri2 = 1;
151 if (pri2 < -1)
152 pri2 = -1;
153 SetThreadPriority (th, pri2);
154 #endif
155
156 if (!SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_HIGHEST))
157 SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
158
159 }
160
161 #else
162
163 #include "sysconfig.h"
164 #include "sysdeps.h"
165
166 #ifdef WIIU
167 #include <wiiu_pthread.h>
168 #include <wiiu/os/semaphore.h>
169
170 #else
171 #include <pthread.h>
172 #include <semaphore.h>
173
174 #include "thread.h"
175
176 #ifdef USE_NAMED_SEMAPHORES
177
uae_sem_init(uae_sem_t * sem,int pshared,unsigned int value)178 int uae_sem_init (uae_sem_t *sem, int pshared, unsigned int value)
179 {
180 char name[32];
181 static int semno = 0;
182 int result = 0;
183
184 sprintf (name, "/uaesem-%d-%d", getpid (), semno++);
185
186 if ((sem->sem = sem_open (name, O_CREAT, 0600, value)) != (sem_t *)SEM_FAILED)
187 sem_unlink (name);
188 else {
189 sem->sem = 0;
190 result = -1;
191 }
192 return result;
193 }
194
195 #else
196
uae_sem_init(uae_sem_t * sem,int pshared,unsigned int value)197 int uae_sem_init (uae_sem_t *sem, int pshared, unsigned int value)
198 {
199 if (!sem || (sem && sem->sem))
200 return -1;
201 sem->sem = (sem_t*)calloc(1, sizeof(sem_t));
202 return sem_init (sem->sem, pshared, value);
203 }
204
205 #endif
206 #endif
207 #endif
208