forked from ghostlander/nsgminer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
compat.h
152 lines (129 loc) · 3.83 KB
/
compat.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Copyright 2012-2013 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option)
* any later version. See COPYING for more details.
*/
#ifndef __COMPAT_H__
#define __COMPAT_H__
#include "config.h"
#ifdef WIN32
#include <winsock2.h>
#endif
#include <stdbool.h>
// NOTE: Nested preprocessor checks since the latter isn't defined at all without the former
#ifdef HAVE_LIBUSB
# if ! HAVE_DECL_LIBUSB_ERROR_NAME
static char my_libusb_error_name_buf[0x10];
# define libusb_error_name(x) (sprintf(my_libusb_error_name_buf, "%d", x), my_libusb_error_name_buf)
# endif
#endif
#ifdef WIN32
#include <errno.h>
#include <time.h>
#include <pthread.h>
#include <sys/time.h>
#include <windows.h>
#ifndef __maybe_unused
#define __maybe_unused __attribute__((unused))
#endif
#ifndef timersub
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
#ifndef timeradd
# define timeradd(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
if ((result)->tv_usec >= 1000000) \
{ \
++(result)->tv_sec; \
(result)->tv_usec -= 1000000; \
} \
} while (0)
#endif
// Some versions of MingW define this, but don't handle the timeval.tv_sec case that we use
#ifdef localtime_r
#undef localtime_r
#endif
// localtime is thread-safe on Windows
// We also use this with timeval.tv_sec, which is incorrectly smaller than time_t on Windows
// Need to cast to time_t* to suppress warning - actual problem shouldn't be possible in practice
#define localtime_r(timep, result) ( \
memcpy(result, \
( \
(sizeof(*timep) == sizeof(time_t)) \
? localtime((time_t*)timep) \
: localtime_convert(*timep) \
), \
sizeof(*result) \
) \
)
static inline
struct tm *localtime_convert(time_t t)
{
return localtime(&t);
}
#if !(__MINGW64__)
static inline int nanosleep(const struct timespec *req, struct timespec *rem)
{
struct timeval tstart;
DWORD msecs;
gettimeofday(&tstart, NULL);
msecs = (req->tv_sec * 1000) + ((999999 + req->tv_nsec) / 1000000);
if (SleepEx(msecs, true) == WAIT_IO_COMPLETION) {
if (rem) {
struct timeval tdone, tnow, tleft;
tdone.tv_sec = tstart.tv_sec + req->tv_sec;
tdone.tv_usec = tstart.tv_usec + ((999 + req->tv_nsec) / 1000);
if (tdone.tv_usec > 1000000) {
tdone.tv_usec -= 1000000;
++tdone.tv_sec;
}
gettimeofday(&tnow, NULL);
if (timercmp(&tnow, &tdone, >))
return 0;
timersub(&tdone, &tnow, &tleft);
rem->tv_sec = tleft.tv_sec;
rem->tv_nsec = tleft.tv_usec * 1000;
}
errno = EINTR;
return -1;
}
return 0;
}
static inline int sleep(unsigned int secs)
{
struct timespec req, rem;
req.tv_sec = secs;
req.tv_nsec = 0;
if (!nanosleep(&req, &rem))
return 0;
return rem.tv_sec + (rem.tv_nsec ? 1 : 0);
}
#endif
enum {
PRIO_PROCESS = 0,
};
static inline int setpriority(__maybe_unused int which, __maybe_unused int who, __maybe_unused int prio)
{
return -!SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
}
typedef unsigned long int ulong;
typedef unsigned short int ushort;
typedef unsigned int uint;
#ifndef __SUSECONDS_T_TYPE
typedef long suseconds_t;
#endif
#endif /* WIN32 */
#endif /* __COMPAT_H__ */