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