CPPMyth
Library to interoperate with MythTV server
Loading...
Searching...
No Matches
os-threads.h
1#pragma once
2/*
3 * Copyright (C) 2015 Jean-Luc Barriere
4 *
5 * This library is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation; either version 3, or (at your option)
8 * any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; see the file COPYING. If not, write to
17 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301 USA
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 */
22
23#include "../os.h"
24
25#if defined(_MSC_VER)
26#include "../windows/winpthreads.h"
27#else
28#include <pthread.h>
29#endif
30
31#ifdef NSROOT
32namespace NSROOT {
33#endif
34namespace OS
35{
36
37#if defined (__WINDOWS__)
38#define gettimeofday __gettimeofday
39 inline int __gettimeofday(struct timeval *pcur_time, struct timezone *tz)
40 {
41 if (pcur_time == nullptr)
42 {
43 SetLastError(EFAULT);
44 return -1;
45 }
46 struct _timeb current;
47 _ftime(&current);
48 pcur_time->tv_sec = (long) current.time;
49 pcur_time->tv_usec = current.millitm * 1000L;
50 if (tz)
51 {
52 tz->tz_minuteswest = current.timezone; /* minutes west of Greenwich */
53 tz->tz_dsttime = current.dstflag; /* type of dst correction */
54 }
55 return 0;
56 }
57
58#define sched_yield __sched_yield
59 inline int __sched_yield()
60 {
61 if (SwitchToThread())
62 return 0;
63 return (-1);
64 }
65#endif
66
67 typedef pthread_t thread_t;
68
69#define thread_create(a, b, c) __thread_create(a, b, c)
70 inline bool __thread_create(thread_t* thread, void* (*func)(void*), void* arg)
71 {
72 static pthread_attr_t _attr;
73 static bool _init = false;
74 if (!_init)
75 {
76 pthread_attr_init(&_attr);
77 pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_DETACHED);
78 _init = true;
79 }
80 return pthread_create(thread, &_attr, func, arg) == 0;
81 }
82
83#define thread_self() __thread_self()
84 inline thread_t __thread_self() { return pthread_self(); }
85
86#define thread_equal(a, b) __thread_equal(a, b)
87 inline int __thread_equal(thread_t t1, thread_t t2) { return pthread_equal(t1, t2); }
88
89 typedef pthread_mutex_t mutex_t;
90
91#define mutex_init(a) __mutex_init(a)
92 inline bool __mutex_init(mutex_t* mutex)
93 {
94 static pthread_mutexattr_t _attr;
95 static bool _init = false;
96 if (!_init)
97 {
98 pthread_mutexattr_init(&_attr);
99 pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE);
100 _init = true;
101 }
102 return pthread_mutex_init(mutex, &_attr) == 0;
103 }
104
105#define mutex_lock(a) __mutex_lock(a)
106 inline bool __mutex_lock(mutex_t* mutex) { return pthread_mutex_lock(mutex) == 0; }
107
108#define mutex_trylock(a) __mutex_trylock(a)
109 inline bool __mutex_trylock(mutex_t* mutex) { return pthread_mutex_trylock(mutex) == 0; }
110
111#define mutex_unlock(a) __mutex_unlock(a)
112 inline void __mutex_unlock(mutex_t* mutex) { pthread_mutex_unlock(mutex); }
113
114#define mutex_destroy(a) __mutex_destroy(a)
115 inline void __mutex_destroy(mutex_t* mutex) { pthread_mutex_destroy(mutex); }
116
117 typedef pthread_cond_t condition_t;
118
119#define cond_init(a) __cond_init(a)
120 inline bool __cond_init(condition_t* cond) { return pthread_cond_init(cond, nullptr) == 0; }
121
122#define cond_signal(a) __cond_signal(a)
123 inline void __cond_signal(condition_t* cond) { pthread_cond_signal(cond); }
124
125#define cond_broadcast(a) __cond_broadcast(a)
126 inline void __cond_broadcast(condition_t* cond) { pthread_cond_broadcast(cond); }
127
128#define cond_wait(a, b) __cond_wait(a, b)
129 inline bool __cond_wait(condition_t* cond, mutex_t* mutex) { return pthread_cond_wait(cond, mutex) == 0; }
130
131#define cond_timedwait(a, b, c) __cond_timedwait(a, b, c)
132 inline bool __cond_timedwait(condition_t* cond, mutex_t* mutex, unsigned millisec)
133 {
134 if (millisec == 0)
135 return cond_wait(cond, mutex);
136
137 struct timespec time;
138#if defined(__APPLE__) || defined(__WINDOWS__)
139 struct timeval tv;
140 gettimeofday(&tv, nullptr);
141 tv.tv_usec += (millisec % 1000) * 1000;
142 tv.tv_sec += millisec / 1000;
143 time.tv_sec = tv.tv_sec + tv.tv_usec / 1000000;
144 time.tv_nsec = (tv.tv_usec % 1000000) * 1000;
145#else
146 clock_gettime(CLOCK_REALTIME, &time);
147 time.tv_nsec += (millisec % 1000) * 1000000;
148 time.tv_sec += millisec / 1000 + time.tv_nsec / 1000000000;
149 time.tv_nsec %= 1000000000;
150#endif
151 return (pthread_cond_timedwait(cond, mutex, &time) == 0);
152 }
153
154#define cond_destroy(a) __cond_destroy(a)
155 inline void __cond_destroy(condition_t* cond) { pthread_cond_destroy(cond); }
156
157}
158#ifdef NSROOT
159}
160#endif