Freeciv-3.3
Loading...
Searching...
No Matches
fcthread.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "log.h"
20#include "mem.h"
21#include "support.h"
22
23#include "fcthread.h"
24
25static at_thread_exit_cb *ate_cb = nullptr;
26
27/*******************************************************************/
33{
34 if (ate_cb != nullptr) {
35 log_error("Trying to register multiple at_thread_exit callbacks.");
36 log_error("That's not supported yet.");
37
38 return FALSE;
39 }
40
41 ate_cb = cb;
42
43 return TRUE;
44}
45
46/*******************************************************************/
49static void at_thread_exit(void)
50{
51 if (ate_cb != nullptr) {
52 ate_cb();
53 }
54}
55
56#ifdef FREECIV_C11_THR
57
59 void *arg;
60 void (*func)(void *arg);
61};
62
63/*******************************************************************/
67static int fc_thread_wrapper(void *arg)
68{
69 struct fc_thread_wrap_data *data = (struct fc_thread_wrap_data *) arg;
70
71 data->func(data->arg);
72
73 free(data);
74
76
77 return EXIT_SUCCESS;
78}
79
80/*******************************************************************/
83int fc_thread_start(fc_thread *thread, void (*function) (void *arg),
84 void *arg)
85{
86 int ret;
87
88 /* Freed by child thread once it's finished with data */
89 struct fc_thread_wrap_data *data = fc_malloc(sizeof(*data));
90
91 data->arg = arg;
92 data->func = function;
93
94 ret = thrd_create(thread, &fc_thread_wrapper, data);
95
96 return ret != thrd_success;
97}
98
99/*******************************************************************/
102void fc_thread_wait(fc_thread *thread)
103{
104 int *return_value = nullptr;
105
106 thrd_join(*thread, return_value);
107}
108
109/*******************************************************************/
113{
114 return thrd_current();
115}
116
117/*******************************************************************/
121{
122 return thrd_equal(thr1, thr2);
123}
124
125/*******************************************************************/
128void fc_mutex_init(fc_mutex *mutex)
129{
131}
132
133/*******************************************************************/
136void fc_mutex_destroy(fc_mutex *mutex)
137{
138 mtx_destroy(mutex);
139}
140
141/*******************************************************************/
144void fc_mutex_allocate(fc_mutex *mutex)
145{
146 mtx_lock(mutex);
147}
148
149/*******************************************************************/
152void fc_mutex_release(fc_mutex *mutex)
153{
154 mtx_unlock(mutex);
155}
156
157/*******************************************************************/
161{
162 cnd_init(cond);
163}
164
165/*******************************************************************/
169{
171}
172
173/*******************************************************************/
177{
178 cnd_wait(cond, mutex);
179}
180
181/*******************************************************************/
185{
187}
188
189#elif defined(FREECIV_HAVE_PTHREAD)
190
191struct fc_thread_wrap_data {
192 void *arg;
193 void (*func)(void *arg);
194};
195
196/*******************************************************************/
200static void *fc_thread_wrapper(void *arg)
201{
202 struct fc_thread_wrap_data *data = (struct fc_thread_wrap_data *) arg;
203
204 data->func(data->arg);
205
206 free(data);
207
209
210 return nullptr;
211}
212
213/*******************************************************************/
216int fc_thread_start(fc_thread *thread, void (*function) (void *arg),
217 void *arg)
218{
219 int ret;
221
222 /* Freed by child thread once it's finished with data */
223 struct fc_thread_wrap_data *data = fc_malloc(sizeof(*data));
224
225 data->arg = arg;
226 data->func = function;
227
228 /* Explicitly set thread as joinable to maximize portability
229 between pthread implementations */
232
233 ret = pthread_create(thread, &attr, &fc_thread_wrapper, data);
234
236
237 return ret;
238}
239
240/*******************************************************************/
243void fc_thread_wait(fc_thread *thread)
244{
245 void **return_value = nullptr;
246
247 pthread_join(*thread, return_value);
248}
249
250/*******************************************************************/
254{
255 return pthread_self();
256}
257
258/*******************************************************************/
262{
263 return pthread_equal(thr1, thr2);
264}
265
266/*******************************************************************/
269void fc_mutex_init(fc_mutex *mutex)
270{
272
275
276 pthread_mutex_init(mutex, &attr);
277
279}
280
281/*******************************************************************/
284void fc_mutex_destroy(fc_mutex *mutex)
285{
287}
288
289/*******************************************************************/
292void fc_mutex_allocate(fc_mutex *mutex)
293{
294 pthread_mutex_lock(mutex);
295}
296
297/*******************************************************************/
300void fc_mutex_release(fc_mutex *mutex)
301{
303}
304
305/*******************************************************************/
309{
310 pthread_cond_init(cond, nullptr);
311}
312
313/*******************************************************************/
317{
319}
320
321/*******************************************************************/
325{
326 pthread_cond_wait(cond, mutex);
327}
328
329/*******************************************************************/
333{
335}
336
337#elif defined(FREECIV_HAVE_WINTHREADS)
338
339struct fc_thread_wrap_data {
340 void *arg;
341 void (*func)(void *arg);
342};
343
344/*******************************************************************/
349{
350 struct fc_thread_wrap_data *data = (struct fc_thread_wrap_data *) arg;
351
352 data->func(data->arg);
353
354 free(data);
355
357
358 return 0;
359}
360
361/*******************************************************************/
364int fc_thread_start(fc_thread *thread, void (*function) (void *arg), void *arg)
365{
366 /* Freed by child thread once it's finished with data */
367 struct fc_thread_wrap_data *data = fc_malloc(sizeof(*data));
368
369 data->arg = arg;
370 data->func = function;
371
372 *thread = CreateThread(nullptr, 0, &fc_thread_wrapper, data, 0, nullptr);
373
374 if (*thread == nullptr) {
375 return 1;
376 }
377
378 return 0;
379}
380
381/*******************************************************************/
384void fc_thread_wait(fc_thread *thread)
385{
387
388 GetExitCodeThread(*thread, &exit_code);
389
390 while (exit_code == STILL_ACTIVE) {
391 fc_usleep(1000);
392 GetExitCodeThread(*thread, &exit_code);
393 }
394
395 CloseHandle(*thread);
396}
397
398/*******************************************************************/
402{
403 return GetCurrentThreadId();
404}
405
406/*******************************************************************/
410{
411 return thr1 == thr2;
412}
413
414/*******************************************************************/
417void fc_mutex_init(fc_mutex *mutex)
418{
419 *mutex = CreateMutex(nullptr, FALSE, nullptr);
420}
421
422/*******************************************************************/
425void fc_mutex_destroy(fc_mutex *mutex)
426{
427 CloseHandle(*mutex);
428}
429
430/*******************************************************************/
433void fc_mutex_allocate(fc_mutex *mutex)
434{
436}
437
438/*******************************************************************/
441void fc_mutex_release(fc_mutex *mutex)
442{
443 ReleaseMutex(*mutex);
444}
445
446/* TODO: Windows thread condition variable support.
447 * Currently related functions are always dummy ones below
448 * (see #ifndef FREECIV_HAVE_THREAD_COND) */
449
450#else /* No thread implementation */
451
452#error "No working thread implementation"
453
454#endif /* FREECIV_HAVE_PTHREAD || FREECIV_HAVE_WINTHREADS */
455
456
457#ifndef FREECIV_HAVE_THREAD_COND
458
459/* Dummy thread condition variable functions */
460
461/*******************************************************************/
466
467/*******************************************************************/
472
473/*******************************************************************/
478
479/*******************************************************************/
484
485#endif /* !FREECIV_HAVE_THREAD_COND */
486
487/*******************************************************************/
491{
492#ifdef FREECIV_HAVE_THREAD_COND
493 return TRUE;
494#else
495 return FALSE;
496#endif
497}
char * incite_cost
Definition comments.c:76
void fc_thread_cond_destroy(fc_thread_cond *cond)
Definition fcthread.c:470
void fc_thread_cond_signal(fc_thread_cond *cond)
Definition fcthread.c:482
void fc_thread_cond_wait(fc_thread_cond *cond, fc_mutex *mutex)
Definition fcthread.c:476
static void at_thread_exit(void)
Definition fcthread.c:49
bool has_thread_cond_impl(void)
Definition fcthread.c:490
bool register_at_thread_exit_callback(at_thread_exit_cb *cb)
Definition fcthread.c:32
void fc_thread_cond_init(fc_thread_cond *cond)
Definition fcthread.c:464
static at_thread_exit_cb * ate_cb
Definition fcthread.c:25
void fc_mutex_allocate(fc_mutex *mutex)
void() at_thread_exit_cb(void)
Definition fcthread.h:89
int fc_thread_start(fc_thread *thread, void(*function)(void *arg), void *arg)
void fc_mutex_init(fc_mutex *mutex)
void fc_mutex_release(fc_mutex *mutex)
void fc_thread_wait(fc_thread *thread)
fc_thread_id fc_thread_self(void)
bool fc_threads_equal(fc_thread_id thr1, fc_thread_id thr2)
void fc_mutex_destroy(fc_mutex *mutex)
get_token_fn_t func
Definition inputfile.c:128
#define log_error(message,...)
Definition log.h:104
#define fc_malloc(sz)
Definition mem.h:34
void fc_usleep(unsigned long usec)
Definition support.c:639
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47