winpthreads: add support for _USE_32BIT_TIME_T and _TIME_BITS
This patch adds handling for CRT's _USE_32BIT_TIME_T and
POSIX _TIME_BITS macros.
This patch adds two versions of each public function which uses
`struct timespec`. One version with suffix `32`, which uses
`struct _timespec32` and one version with suffix `64`, which uses
`struct _timespec64`.
The plain versions without the suffix are implemented as static inline functions
which call explicitly sized version and perform type cast from
`struct timespec*` to explicitly sized version of the structure.
External symbols for plain versions are still provided.
They use either 32- or 64-suffixed version internally.
pthread_compat.h:
- new macro `WINPTHREADS_TIME_BITS` has been added
- new macro `WINPTHREADS_ALWAYS_INLINE` has been added
- a few new supplementary macros have been added
pthread.h:
Function `__pthread_clock_nanosleep` has been removed.
winpthreads now provides `clock_nanosleep` with standard POSIX name.
Signed-off-by: Kirill Makurin <maiddaisuki@outlook.com>
Signed-off-by: LIU Hao <lh_mouse@126.com>
diff --git a/mingw-w64-libraries/winpthreads/include/pthread.h b/mingw-w64-libraries/winpthreads/include/pthread.h
index d06c0c8..3ab5db7 100644
--- a/mingw-w64-libraries/winpthreads/include/pthread.h
+++ b/mingw-w64-libraries/winpthreads/include/pthread.h
@@ -139,7 +139,16 @@
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
WINPTHREAD_API void * pthread_timechange_handler_np(void * dummy);
-WINPTHREAD_API int pthread_delay_np (const struct timespec *interval);
+WINPTHREAD_API int pthread_delay32_np (const struct _timespec32 *interval);
+WINPTHREAD_API int pthread_delay64_np (const struct _timespec64 *interval);
+WINPTHREAD_THREAD_DECL int pthread_delay_np (const struct timespec *interval)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return pthread_delay32_np ((const struct _timespec32 *) interval);
+#else
+ return pthread_delay64_np ((const struct _timespec64 *) interval);
+#endif
+}
WINPTHREAD_API int pthread_num_processors_np(void);
WINPTHREAD_API int pthread_set_num_processors_np(int n);
@@ -269,12 +278,29 @@
WINPTHREAD_API int pthread_setname_np(pthread_t thread, const char *name);
WINPTHREAD_API int pthread_getname_np(pthread_t thread, char *name, size_t len);
-
WINPTHREAD_API int pthread_rwlock_init(pthread_rwlock_t *rwlock_, const pthread_rwlockattr_t *attr);
WINPTHREAD_API int pthread_rwlock_wrlock(pthread_rwlock_t *l);
-WINPTHREAD_API int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *ts);
+WINPTHREAD_API int pthread_rwlock_timedwrlock32(pthread_rwlock_t *rwlock, const struct _timespec32 *ts);
+WINPTHREAD_API int pthread_rwlock_timedwrlock64(pthread_rwlock_t *rwlock, const struct _timespec64 *ts);
+WINPTHREAD_RWLOCK_DECL int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *ts)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return pthread_rwlock_timedwrlock32 (rwlock, (const struct _timespec32 *) ts);
+#else
+ return pthread_rwlock_timedwrlock64 (rwlock, (const struct _timespec64 *) ts);
+#endif
+}
WINPTHREAD_API int pthread_rwlock_rdlock(pthread_rwlock_t *l);
-WINPTHREAD_API int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts);
+WINPTHREAD_API int pthread_rwlock_timedrdlock32(pthread_rwlock_t *l, const struct _timespec32 *ts);
+WINPTHREAD_API int pthread_rwlock_timedrdlock64(pthread_rwlock_t *l, const struct _timespec64 *ts);
+WINPTHREAD_RWLOCK_DECL int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return pthread_rwlock_timedrdlock32 (l, (const struct _timespec32 *) ts);
+#else
+ return pthread_rwlock_timedrdlock64 (l, (const struct _timespec64 *) ts);
+#endif
+}
WINPTHREAD_API int pthread_rwlock_unlock(pthread_rwlock_t *l);
WINPTHREAD_API int pthread_rwlock_tryrdlock(pthread_rwlock_t *l);
WINPTHREAD_API int pthread_rwlock_trywrlock(pthread_rwlock_t *l);
@@ -285,11 +311,38 @@
WINPTHREAD_API int pthread_cond_signal (pthread_cond_t *cv);
WINPTHREAD_API int pthread_cond_broadcast (pthread_cond_t *cv);
WINPTHREAD_API int pthread_cond_wait (pthread_cond_t *cv, pthread_mutex_t *external_mutex);
-WINPTHREAD_API int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct timespec *t);
-WINPTHREAD_API int pthread_cond_timedwait_relative_np(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct timespec *t);
+WINPTHREAD_API int pthread_cond_timedwait32(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct _timespec32 *t);
+WINPTHREAD_API int pthread_cond_timedwait64(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct _timespec64 *t);
+WINPTHREAD_COND_DECL int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct timespec *t)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return pthread_cond_timedwait32 (cv, external_mutex, (const struct _timespec32 *) t);
+#else
+ return pthread_cond_timedwait64 (cv, external_mutex, (const struct _timespec64 *) t);
+#endif
+}
+WINPTHREAD_API int pthread_cond_timedwait32_relative_np(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct _timespec32 *t);
+WINPTHREAD_API int pthread_cond_timedwait64_relative_np(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct _timespec64 *t);
+WINPTHREAD_COND_DECL int pthread_cond_timedwait_relative_np(pthread_cond_t *cv, pthread_mutex_t *external_mutex, const struct timespec *t)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return pthread_cond_timedwait32_relative_np (cv, external_mutex, (const struct _timespec32 *) t);
+#else
+ return pthread_cond_timedwait64_relative_np (cv, external_mutex, (const struct _timespec64 *) t);
+#endif
+}
WINPTHREAD_API int pthread_mutex_lock(pthread_mutex_t *m);
-WINPTHREAD_API int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *ts);
+WINPTHREAD_API int pthread_mutex_timedlock32(pthread_mutex_t *m, const struct _timespec32 *ts);
+WINPTHREAD_API int pthread_mutex_timedlock64(pthread_mutex_t *m, const struct _timespec64 *ts);
+WINPTHREAD_MUTEX_DECL int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *ts)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return pthread_mutex_timedlock32 (m, (const struct _timespec32 *) ts);
+#else
+ return pthread_mutex_timedlock64 (m, (const struct _timespec64 *) ts);
+#endif
+}
WINPTHREAD_API int pthread_mutex_unlock(pthread_mutex_t *m);
WINPTHREAD_API int pthread_mutex_trylock(pthread_mutex_t *m);
WINPTHREAD_API int pthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a);
@@ -343,7 +396,6 @@
clockid_t *clock_id);
WINPTHREAD_API int pthread_condattr_setclock(pthread_condattr_t *attr,
clockid_t clock_id);
-WINPTHREAD_API int __pthread_clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp);
WINPTHREAD_API int pthread_barrierattr_init(void **attr);
WINPTHREAD_API int pthread_barrierattr_destroy(void **attr);
diff --git a/mingw-w64-libraries/winpthreads/include/pthread_compat.h b/mingw-w64-libraries/winpthreads/include/pthread_compat.h
index 9611872..3a85528 100644
--- a/mingw-w64-libraries/winpthreads/include/pthread_compat.h
+++ b/mingw-w64-libraries/winpthreads/include/pthread_compat.h
@@ -60,6 +60,12 @@
#ifndef WIN_PTHREADS_PTHREAD_COMPAT_H
#define WIN_PTHREADS_PTHREAD_COMPAT_H
+#if defined(_USE_32BIT_TIME_T) || (defined(_TIME_BITS) && _TIME_BITS == 32)
+#define WINPTHREADS_TIME_BITS 32
+#else
+#define WINPTHREADS_TIME_BITS 64
+#endif
+
#if defined(IN_WINPTHREAD)
# if defined(DLL_EXPORT)
# define WINPTHREAD_API __declspec(dllexport) /* building the DLL */
@@ -97,7 +103,8 @@
#ifdef __GNUC__
-#define WINPTHREADS_INLINE inline
+#define WINPTHREADS_INLINE __inline__
+#define WINPTHREADS_ALWAYS_INLINE __inline__ __attribute__((__always_inline__))
#define WINPTHREADS_ATTRIBUTE(X) __attribute__(X)
#define WINPTHREADS_SECTION(X) __section__(X)
@@ -110,9 +117,32 @@
#endif
#define WINPTHREADS_INLINE __inline
+#define WINPTHREADS_ALWAYS_INLINE __inline __forceinline
#define WINPTHREADS_ATTRIBUTE(X) __declspec X
#define WINPTHREADS_SECTION(X) allocate(X)
#endif
+#ifndef WINPTHREAD_CLOCK_DECL
+#define WINPTHREAD_CLOCK_DECL static WINPTHREADS_ALWAYS_INLINE
+#endif
+#ifndef WINPTHREAD_COND_DECL
+#define WINPTHREAD_COND_DECL static WINPTHREADS_ALWAYS_INLINE
+#endif
+#ifndef WINPTHREAD_MUTEX_DECL
+#define WINPTHREAD_MUTEX_DECL static WINPTHREADS_ALWAYS_INLINE
+#endif
+#ifndef WINPTHREAD_NANOSLEEP_DECL
+#define WINPTHREAD_NANOSLEEP_DECL static WINPTHREADS_ALWAYS_INLINE
+#endif
+#ifndef WINPTHREAD_RWLOCK_DECL
+#define WINPTHREAD_RWLOCK_DECL static WINPTHREADS_ALWAYS_INLINE
+#endif
+#ifndef WINPTHREAD_SEM_DECL
+#define WINPTHREAD_SEM_DECL static WINPTHREADS_ALWAYS_INLINE
+#endif
+#ifndef WINPTHREAD_THREAD_DECL
+#define WINPTHREAD_THREAD_DECL static WINPTHREADS_ALWAYS_INLINE
+#endif
+
#endif
diff --git a/mingw-w64-libraries/winpthreads/include/pthread_time.h b/mingw-w64-libraries/winpthreads/include/pthread_time.h
index 363154d..ac014ae 100644
--- a/mingw-w64-libraries/winpthreads/include/pthread_time.h
+++ b/mingw-w64-libraries/winpthreads/include/pthread_time.h
@@ -73,12 +73,60 @@
extern "C" {
#endif
-WINPTHREAD_API int __cdecl nanosleep(const struct timespec *request, struct timespec *remain);
+WINPTHREAD_API int __cdecl nanosleep32(const struct _timespec32 *request, struct _timespec32 *remain);
+WINPTHREAD_API int __cdecl nanosleep64(const struct _timespec64 *request, struct _timespec64 *remain);
+WINPTHREAD_NANOSLEEP_DECL int __cdecl nanosleep(const struct timespec *request, struct timespec *remain)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return nanosleep32 ((struct _timespec32 *)request, (struct _timespec32 *)remain);
+#else
+ return nanosleep64 ((struct _timespec64 *)request, (struct _timespec64 *)remain);
+#endif
+}
-WINPTHREAD_API int __cdecl clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *request, struct timespec *remain);
-WINPTHREAD_API int __cdecl clock_getres(clockid_t clock_id, struct timespec *res);
-WINPTHREAD_API int __cdecl clock_gettime(clockid_t clock_id, struct timespec *tp);
-WINPTHREAD_API int __cdecl clock_settime(clockid_t clock_id, const struct timespec *tp);
+WINPTHREAD_API int __cdecl clock_nanosleep32(clockid_t clock_id, int flags, const struct _timespec32 *request, struct _timespec32 *remain);
+WINPTHREAD_API int __cdecl clock_nanosleep64(clockid_t clock_id, int flags, const struct _timespec64 *request, struct _timespec64 *remain);
+WINPTHREAD_CLOCK_DECL int __cdecl clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *request, struct timespec *remain)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return clock_nanosleep32 (clock_id, flags, (struct _timespec32 *)request, (struct _timespec32 *)remain);
+#else
+ return clock_nanosleep64 (clock_id, flags, (struct _timespec64 *)request, (struct _timespec64 *)remain);
+#endif
+}
+
+WINPTHREAD_API int __cdecl clock_getres32(clockid_t clock_id, struct _timespec32 *res);
+WINPTHREAD_API int __cdecl clock_getres64(clockid_t clock_id, struct _timespec64 *res);
+WINPTHREAD_CLOCK_DECL int __cdecl clock_getres(clockid_t clock_id, struct timespec *res)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return clock_getres32 (clock_id, (struct _timespec32 *)res);
+#else
+ return clock_getres64 (clock_id, (struct _timespec64 *)res);
+#endif
+}
+
+WINPTHREAD_API int __cdecl clock_gettime32(clockid_t clock_id, struct _timespec32 *tp);
+WINPTHREAD_API int __cdecl clock_gettime64(clockid_t clock_id, struct _timespec64 *tp);
+WINPTHREAD_CLOCK_DECL int __cdecl clock_gettime(clockid_t clock_id, struct timespec *tp)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return clock_gettime32 (clock_id, (struct _timespec32 *)tp);
+#else
+ return clock_gettime64 (clock_id, (struct _timespec64 *)tp);
+#endif
+}
+
+WINPTHREAD_API int __cdecl clock_settime32(clockid_t clock_id, const struct _timespec32 *tp);
+WINPTHREAD_API int __cdecl clock_settime64(clockid_t clock_id, const struct _timespec64 *tp);
+WINPTHREAD_CLOCK_DECL int __cdecl clock_settime(clockid_t clock_id, const struct timespec *tp)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return clock_settime32 (clock_id, (struct _timespec32 *)tp);
+#else
+ return clock_settime64 (clock_id, (struct _timespec64 *)tp);
+#endif
+}
#ifdef __cplusplus
}
diff --git a/mingw-w64-libraries/winpthreads/include/semaphore.h b/mingw-w64-libraries/winpthreads/include/semaphore.h
index b6cd13f..649583f 100644
--- a/mingw-w64-libraries/winpthreads/include/semaphore.h
+++ b/mingw-w64-libraries/winpthreads/include/semaphore.h
@@ -43,7 +43,16 @@
WINPTHREAD_API int sem_wait(sem_t *sem);
-WINPTHREAD_API int sem_timedwait(sem_t * sem, const struct timespec *t);
+WINPTHREAD_API int sem_timedwait32(sem_t * sem, const struct _timespec32 *t);
+WINPTHREAD_API int sem_timedwait64(sem_t * sem, const struct _timespec64 *t);
+WINPTHREAD_SEM_DECL int sem_timedwait(sem_t * sem, const struct timespec *t)
+{
+#if WINPTHREADS_TIME_BITS == 32
+ return sem_timedwait32 (sem, (const struct _timespec32 *) t);
+#else
+ return sem_timedwait64 (sem, (const struct _timespec64 *) t);
+#endif
+}
WINPTHREAD_API int sem_post(sem_t *sem);
diff --git a/mingw-w64-libraries/winpthreads/src/clock.c b/mingw-w64-libraries/winpthreads/src/clock.c
index 17aa3da..922c5de 100644
--- a/mingw-w64-libraries/winpthreads/src/clock.c
+++ b/mingw-w64-libraries/winpthreads/src/clock.c
@@ -8,6 +8,7 @@
#include "config.h"
#endif
+#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <time.h>
@@ -15,6 +16,8 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#define WINPTHREAD_CLOCK_DECL WINPTHREAD_API
+
/* public header files */
#include "pthread_time.h"
/* internal header files */
@@ -56,7 +59,7 @@
* If the function fails, the return value is -1,
* with errno set to indicate the error.
*/
-int clock_getres(clockid_t clock_id, struct timespec *res)
+static int __clock_getres(clockid_t clock_id, struct _timespec64 *res)
{
clockid_t id = clock_id;
@@ -118,7 +121,7 @@
* If the function fails, the return value is -1,
* with errno set to indicate the error.
*/
-int clock_gettime(clockid_t clock_id, struct timespec *tp)
+static int __clock_gettime(clockid_t clock_id, struct _timespec64 *tp)
{
unsigned __int64 t;
LARGE_INTEGER pf, pc;
@@ -206,20 +209,20 @@
* If the function fails, the return value is -1,
* with errno set to indicate the error.
*/
-int clock_nanosleep(clockid_t clock_id, int flags,
- const struct timespec *request,
- struct timespec *remain)
+static int __clock_nanosleep(clockid_t clock_id, int flags,
+ const struct _timespec64 *request,
+ struct _timespec64 *remain)
{
- struct timespec tp;
+ struct _timespec64 tp;
if (clock_id != CLOCK_REALTIME)
return lc_set_errno(EINVAL);
if (flags == 0)
- return nanosleep(request, remain);
+ return nanosleep64(request, remain);
/* TIMER_ABSTIME = 1 */
- clock_gettime(CLOCK_REALTIME, &tp);
+ __clock_gettime(CLOCK_REALTIME, &tp);
tp.tv_sec = request->tv_sec - tp.tv_sec;
tp.tv_nsec = request->tv_nsec - tp.tv_nsec;
@@ -228,7 +231,7 @@
tp.tv_sec --;
}
- return nanosleep(&tp, remain);
+ return nanosleep64(&tp, remain);
}
/**
@@ -239,7 +242,7 @@
* If the function fails, the return value is -1,
* with errno set to indicate the error.
*/
-int clock_settime(clockid_t clock_id, const struct timespec *tp)
+static int __clock_settime(clockid_t clock_id, const struct _timespec64 *tp)
{
SYSTEMTIME st;
@@ -260,3 +263,92 @@
return 0;
}
+
+/**
+ * Versions to use with 64-bit time_t (struct _timespec64)
+ */
+
+int clock_getres64 (clockid_t clock_id, struct _timespec64 *tp)
+{
+ return __clock_getres (clock_id, tp);
+}
+
+int clock_gettime64 (clockid_t clock_id, struct _timespec64 *tp)
+{
+ return __clock_gettime (clock_id, tp);
+}
+
+int clock_settime64 (clockid_t clock_id, const struct _timespec64 *tp)
+{
+ return __clock_settime (clock_id, tp);
+}
+
+int clock_nanosleep64 (clockid_t clock_id, int flags,
+ const struct _timespec64 *request, struct _timespec64 *remain)
+{
+ return __clock_nanosleep (clock_id, flags, request, remain);
+}
+
+/**
+ * Versions to use with 32-bit time_t (struct _timespec32)
+ */
+
+int clock_getres32 (clockid_t clock_id, struct _timespec32 *tp)
+{
+ struct _timespec64 tp64 = {0};
+
+ if (__clock_getres (clock_id, &tp64) == -1)
+ return -1;
+
+ tp->tv_sec = (__time32_t) tp64.tv_sec;
+ tp->tv_nsec = tp64.tv_nsec;
+
+ return 0;
+}
+
+int clock_gettime32 (clockid_t clock_id, struct _timespec32 *tp)
+{
+ struct _timespec64 tp64 = {0};
+
+ if (__clock_gettime (clock_id, &tp64) == -1)
+ return -1;
+
+ if (tp64.tv_sec > INT_MAX)
+ {
+ _set_errno (EOVERFLOW);
+ return -1;
+ }
+
+ tp->tv_sec = (__time32_t) tp64.tv_sec;
+ tp->tv_nsec = tp64.tv_nsec;
+
+ return 0;
+}
+
+int clock_settime32 (clockid_t clock_id, const struct _timespec32 *tp)
+{
+ struct _timespec64 tp64 = {.tv_sec = tp->tv_sec, .tv_nsec = tp->tv_nsec};
+ return __clock_settime (clock_id, &tp64);
+}
+
+int clock_nanosleep32 (clockid_t clock_id, int flags,
+ const struct _timespec32 *request, struct _timespec32 *remain)
+{
+ struct _timespec64 request64 = {
+ .tv_sec = request->tv_sec,
+ .tv_nsec = request->tv_nsec
+ };
+ struct _timespec64 remain64 = {0};
+
+ if (__clock_nanosleep (clock_id, flags, &request64, &remain64) == -1)
+ return -1;
+
+ assert (remain64.tv_sec <= INT_MAX);
+
+ if (remain != NULL) {
+ remain->tv_sec = (__time32_t)remain64.tv_sec;
+ remain->tv_nsec = remain64.tv_nsec;
+ }
+
+ return 0;
+}
diff --git a/mingw-w64-libraries/winpthreads/src/cond.c b/mingw-w64-libraries/winpthreads/src/cond.c
index afede30..a77cd3e 100644
--- a/mingw-w64-libraries/winpthreads/src/cond.c
+++ b/mingw-w64-libraries/winpthreads/src/cond.c
@@ -36,6 +36,8 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#define WINPTHREAD_COND_DECL WINPTHREAD_API
+
/* public header files */
#include "pthread.h"
#include "pthread_time.h"
@@ -124,40 +126,6 @@
}
int
-__pthread_clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *rqtp,
- struct timespec *rmtp)
-{
- unsigned long long tick, tick2;
- unsigned long long delay;
- DWORD dw;
-
- if (clock_id != CLOCK_REALTIME
- && clock_id != CLOCK_MONOTONIC
- && clock_id != CLOCK_PROCESS_CPUTIME_ID)
- return EINVAL;
- if ((flags & TIMER_ABSTIME) != 0)
- delay = _pthread_rel_time_in_ms (rqtp);
- else
- delay = _pthread_time_in_ms_from_timespec (rqtp);
- do
- {
- dw = (DWORD) (delay >= 99999ULL ? 99999ULL : delay);
- tick = _pthread_time_in_ms ();
- _pthread_delay_np_ms (dw);
- tick2 = _pthread_time_in_ms ();
- tick2 -= tick;
- if (tick2 >= delay)
- delay = 0;
- else
- delay -= tick2;
- }
- while (delay != 0ULL);
- if (rmtp)
- memset (rmtp, 0, sizeof (*rmtp));
- return 0;
-}
-
-int
pthread_condattr_setpshared (pthread_condattr_t *a, int s)
{
if (!a || (s != PTHREAD_PROCESS_SHARED && s != PTHREAD_PROCESS_PRIVATE))
@@ -445,7 +413,7 @@
}
static int
-pthread_cond_timedwait_impl (pthread_cond_t *c, pthread_mutex_t *external_mutex, const struct timespec *t, int rel)
+pthread_cond_timedwait_impl (pthread_cond_t *c, pthread_mutex_t *external_mutex, const struct _timespec64 *t, int rel)
{
sCondWaitHelper ch;
DWORD dwr;
@@ -511,17 +479,31 @@
}
int
-pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, const struct timespec *t)
+pthread_cond_timedwait64(pthread_cond_t *c, pthread_mutex_t *m, const struct _timespec64 *t)
{
return pthread_cond_timedwait_impl(c, m, t, 0);
}
int
-pthread_cond_timedwait_relative_np(pthread_cond_t *c, pthread_mutex_t *m, const struct timespec *t)
+pthread_cond_timedwait32(pthread_cond_t *c, pthread_mutex_t *m, const struct _timespec32 *t)
+{
+ struct _timespec64 t64 = {.tv_sec = t->tv_sec, .tv_nsec = t->tv_nsec};
+ return pthread_cond_timedwait_impl(c, m, &t64, 0);
+}
+
+int
+pthread_cond_timedwait64_relative_np(pthread_cond_t *c, pthread_mutex_t *m, const struct _timespec64 *t)
{
return pthread_cond_timedwait_impl(c, m, t, 1);
}
+int
+pthread_cond_timedwait32_relative_np(pthread_cond_t *c, pthread_mutex_t *m, const struct _timespec32 *t)
+{
+ struct _timespec64 t64 = {.tv_sec = t->tv_sec, .tv_nsec = t->tv_nsec};
+ return pthread_cond_timedwait_impl(c, m, &t64, 1);
+}
+
static void
cleanup_wait (void *arg)
{
diff --git a/mingw-w64-libraries/winpthreads/src/misc.c b/mingw-w64-libraries/winpthreads/src/misc.c
index 1e0d612..d9c5504 100644
--- a/mingw-w64-libraries/winpthreads/src/misc.c
+++ b/mingw-w64-libraries/winpthreads/src/misc.c
@@ -95,7 +95,7 @@
- 0x19DB1DED53E8000ULL) / 10000ULL;
}
-unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts)
+unsigned long long _pthread_time_in_ms_from_timespec(const struct _timespec64 *ts)
{
unsigned long long t = (unsigned long long) ts->tv_sec * 1000LL;
/* The +999999 is here to ensure that the division always rounds up */
@@ -104,7 +104,7 @@
return t;
}
-unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts)
+unsigned long long _pthread_rel_time_in_ms(const struct _timespec64 *ts)
{
unsigned long long t1 = _pthread_time_in_ms_from_timespec(ts);
unsigned long long t2 = _pthread_time_in_ms();
diff --git a/mingw-w64-libraries/winpthreads/src/misc.h b/mingw-w64-libraries/winpthreads/src/misc.h
index 75818b4..f954ad4 100644
--- a/mingw-w64-libraries/winpthreads/src/misc.h
+++ b/mingw-w64-libraries/winpthreads/src/misc.h
@@ -75,8 +75,8 @@
}
unsigned long long _pthread_time_in_ms(void);
-unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts);
-unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts);
+unsigned long long _pthread_time_in_ms_from_timespec(const struct _timespec64 *ts);
+unsigned long long _pthread_rel_time_in_ms(const struct _timespec64 *ts);
unsigned long _pthread_wait_for_single_object (void *handle, unsigned long timeout);
unsigned long _pthread_wait_for_multiple_objects (unsigned long count, void **handles, unsigned int all, unsigned long timeout);
diff --git a/mingw-w64-libraries/winpthreads/src/mutex.c b/mingw-w64-libraries/winpthreads/src/mutex.c
index 20d8815..b901209 100644
--- a/mingw-w64-libraries/winpthreads/src/mutex.c
+++ b/mingw-w64-libraries/winpthreads/src/mutex.c
@@ -32,6 +32,8 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#define WINPTHREAD_MUTEX_DECL WINPTHREAD_API
+
/* public header files */
#include "pthread.h"
/* internal header files */
@@ -193,7 +195,8 @@
return pthread_mutex_lock_intern (m, INFINITE);
}
-int pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *ts)
+/* Internal version which always uses `struct _timespec64`. */
+static int __pthread_mutex_timedlock(pthread_mutex_t *m, const struct _timespec64 *ts)
{
unsigned long long patience;
if (ts != NULL) {
@@ -208,6 +211,17 @@
return pthread_mutex_lock_intern(m, patience);
}
+int pthread_mutex_timedlock64(pthread_mutex_t *m, const struct _timespec64 *ts)
+{
+ return __pthread_mutex_timedlock (m, ts);
+}
+
+int pthread_mutex_timedlock32(pthread_mutex_t *m, const struct _timespec32 *ts)
+{
+ struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec};
+ return __pthread_mutex_timedlock (m, &ts64);
+}
+
int pthread_mutex_unlock(pthread_mutex_t *m)
{
/* Here m might an initialiser of an error-checking or recursive mutex, in
diff --git a/mingw-w64-libraries/winpthreads/src/nanosleep.c b/mingw-w64-libraries/winpthreads/src/nanosleep.c
index d1c1390..a81bf2c 100644
--- a/mingw-w64-libraries/winpthreads/src/nanosleep.c
+++ b/mingw-w64-libraries/winpthreads/src/nanosleep.c
@@ -8,12 +8,15 @@
#include "config.h"
#endif
+#include <assert.h>
#include <errno.h>
#include <time.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#define WINPTHREAD_NANOSLEEP_DECL WINPTHREAD_API
+
/* public header files */
#include "pthread.h"
#include "pthread_time.h"
@@ -34,7 +37,7 @@
* If the function fails, the return value is -1,
* with errno set to indicate the error.
*/
-int nanosleep(const struct timespec *request, struct timespec *remain)
+static int __nanosleep(const struct _timespec64 *request, struct _timespec64 *remain)
{
unsigned long ms, rc = 0;
unsigned __int64 u64, want, real;
@@ -78,3 +81,29 @@
return 0;
}
+
+int nanosleep64(const struct _timespec64 *request, struct _timespec64 *remain)
+{
+ return __nanosleep (request, remain);
+}
+
+int nanosleep32(const struct _timespec32 *request, struct _timespec32 *remain)
+{
+ struct _timespec64 request64 = {
+ .tv_sec = request->tv_sec,
+ .tv_nsec = request->tv_nsec
+ };
+ struct _timespec64 remain64 = {0};
+
+ if (__nanosleep (&request64, &remain64) == -1)
+ return -1;
+
+ assert (remain64.tv_sec <= INT_MAX);
+
+ if (remain != NULL) {
+ remain->tv_sec = (__time32_t)remain64.tv_sec;
+ remain->tv_nsec = remain64.tv_nsec;
+ }
+
+ return 0;
+}
diff --git a/mingw-w64-libraries/winpthreads/src/rwlock.c b/mingw-w64-libraries/winpthreads/src/rwlock.c
index 8aa62ec..68ef2a7 100644
--- a/mingw-w64-libraries/winpthreads/src/rwlock.c
+++ b/mingw-w64-libraries/winpthreads/src/rwlock.c
@@ -31,6 +31,8 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#define WINPTHREAD_RWLOCK_DECL WINPTHREAD_API
+
/* public header files */
#include "pthread.h"
/* internal header files */
@@ -262,7 +264,8 @@
return rwl_unref(rwlock_, ret);
}
-int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct timespec *ts)
+/* Internal version which always uses `struct _timespec64`. */
+static int __pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct _timespec64 *ts)
{
rwlock_t *rwlock;
int ret;
@@ -273,12 +276,12 @@
if(ret != 0) return ret;
rwlock = (rwlock_t *)*rwlock_;
- if ((ret = pthread_mutex_timedlock (&rwlock->mex, ts)) != 0)
+ if ((ret = pthread_mutex_timedlock64 (&rwlock->mex, ts)) != 0)
return rwl_unref(rwlock_, ret);
InterlockedIncrement(&rwlock->nsh_count);
if (rwlock->nsh_count == INT_MAX)
{
- ret = pthread_mutex_timedlock(&rwlock->mcomplete, ts);
+ ret = pthread_mutex_timedlock64(&rwlock->mcomplete, ts);
if (ret != 0)
{
if (ret == ETIMEDOUT)
@@ -295,6 +298,17 @@
return rwl_unref(rwlock_, ret);
}
+int pthread_rwlock_timedrdlock64(pthread_rwlock_t *l, const struct _timespec64 *ts)
+{
+ return __pthread_rwlock_timedrdlock (l, ts);
+}
+
+int pthread_rwlock_timedrdlock32(pthread_rwlock_t *l, const struct _timespec32 *ts)
+{
+ struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec};
+ return __pthread_rwlock_timedrdlock (l, &ts64);
+}
+
int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock_)
{
rwlock_t *rwlock;
@@ -442,7 +456,8 @@
return rwl_unref(rwlock_,ret);
}
-int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct timespec *ts)
+/* Internal version which always uses `struct _timespec64`. */
+static int __pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct _timespec64 *ts)
{
int ret;
rwlock_t *rwlock;
@@ -454,10 +469,10 @@
return ret;
rwlock = (rwlock_t *)*rwlock_;
- ret = pthread_mutex_timedlock(&rwlock->mex, ts);
+ ret = pthread_mutex_timedlock64(&rwlock->mex, ts);
if (ret != 0)
return rwl_unref(rwlock_,ret);
- ret = pthread_mutex_timedlock (&rwlock->mcomplete, ts);
+ ret = pthread_mutex_timedlock64(&rwlock->mcomplete, ts);
if (ret != 0)
{
pthread_mutex_unlock(&rwlock->mex);
@@ -475,7 +490,7 @@
rwlock->ncomplete = -rwlock->nsh_count;
pthread_cleanup_push(st_cancelwrite, (void *) rwlock);
do {
- ret = pthread_cond_timedwait(&rwlock->ccomplete, &rwlock->mcomplete, ts);
+ ret = pthread_cond_timedwait64(&rwlock->ccomplete, &rwlock->mcomplete, ts);
} while (rwlock->ncomplete < 0 && !ret);
pthread_cleanup_pop(!ret ? 0 : 1);
@@ -488,6 +503,17 @@
return rwl_unref(rwlock_,ret);
}
+int pthread_rwlock_timedwrlock64(pthread_rwlock_t *rwlock, const struct _timespec64 *ts)
+{
+ return __pthread_rwlock_timedwrlock (rwlock, ts);
+}
+
+int pthread_rwlock_timedwrlock32(pthread_rwlock_t *rwlock, const struct _timespec32 *ts)
+{
+ struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec};
+ return __pthread_rwlock_timedwrlock (rwlock, &ts64);
+}
+
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
{
if (!a)
diff --git a/mingw-w64-libraries/winpthreads/src/sem.c b/mingw-w64-libraries/winpthreads/src/sem.c
index 1226bb8..37abf2e 100644
--- a/mingw-w64-libraries/winpthreads/src/sem.c
+++ b/mingw-w64-libraries/winpthreads/src/sem.c
@@ -220,8 +220,9 @@
return sem_result (ret);
}
-int
-sem_timedwait (sem_t *sem, const struct timespec *t)
+/* Internal version which always uses `struct _timespec64`. */
+static int
+__sem_timedwait (sem_t *sem, const struct _timespec64 *t)
{
int cur_v, ret = 0;
DWORD dwr;
@@ -259,6 +260,17 @@
return sem_result (ret);
}
+int sem_timedwait64(sem_t *sem, const struct _timespec64 *t)
+{
+ return __sem_timedwait (sem, t);
+}
+
+int sem_timedwait32(sem_t *sem, const struct _timespec32 *t)
+{
+ struct _timespec64 t64 = {.tv_sec = t->tv_sec, .tv_nsec = t->tv_nsec};
+ return __sem_timedwait (sem, &t64);
+}
+
int
sem_post (sem_t *sem)
{
diff --git a/mingw-w64-libraries/winpthreads/src/thread.c b/mingw-w64-libraries/winpthreads/src/thread.c
index 6a86472..c0b36bb 100644
--- a/mingw-w64-libraries/winpthreads/src/thread.c
+++ b/mingw-w64-libraries/winpthreads/src/thread.c
@@ -34,6 +34,8 @@
#include <windows.h>
#include <strsafe.h>
+#define WINPTHREAD_THREAD_DECL WINPTHREAD_API
+
/* public header files */
#include "pthread.h"
/* internal header files */
@@ -658,8 +660,8 @@
/* Compatibility routine for pthread-win32. It waits for ellapse of
interval and additionally checks for possible thread-cancelation. */
-int
-pthread_delay_np (const struct timespec *interval)
+static int
+__pthread_delay_np (const struct _timespec64 *interval)
{
DWORD to = (!interval ? 0 : dwMilliSecs (_pthread_time_in_ms_from_timespec (interval)));
struct _pthread_v *s = __pthread_self_lite ();
@@ -681,6 +683,19 @@
}
int
+pthread_delay64_np (const struct _timespec64 *interval)
+{
+ return __pthread_delay_np(interval);
+}
+
+int
+pthread_delay32_np (const struct _timespec32 *interval)
+{
+ struct _timespec64 interval64 = {.tv_sec = interval->tv_sec, .tv_nsec = interval->tv_nsec};
+ return __pthread_delay_np(&interval64);
+}
+
+int
_pthread_delay_np_ms (DWORD to)
{
struct _pthread_v *s = __pthread_self_lite ();