// 7.25.3.5
static inline int
-cnd_timedwait(cnd_t *cond, mtx_t *mtx, const xtime *xt)
+cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *abs_time)
{
- struct timespec abs_time;
int rt;
assert(mtx != NULL);
assert(cond != NULL);
- assert(xt != NULL);
+ assert(abs_time != NULL);
- abs_time.tv_sec = xt->sec;
- abs_time.tv_nsec = xt->nsec;
-
- rt = pthread_cond_timedwait(cond, mtx, &abs_time);
+ rt = pthread_cond_timedwait(cond, mtx, abs_time);
if (rt == ETIMEDOUT)
return thrd_busy;
return (rt == 0) ? thrd_success : thrd_error;
pthread_mutex_destroy(mtx);
}
+/*
+ * XXX: Workaround when building with -O0 and without pthreads link.
+ *
+ * In such cases constant folding and dead code elimination won't be
+ * available, thus the compiler will always add the pthread_mutexattr*
+ * functions into the binary. As we try to link, we'll fail as the
+ * symbols are unresolved.
+ *
+ * Ideally we'll enable the optimisations locally, yet that does not
+ * seem to work.
+ *
+ * So the alternative workaround is to annotate the symbols as weak.
+ * Thus the linker will be happy and things don't clash when building
+ * with -O1 or greater.
+ */
+#if defined(HAVE_FUNC_ATTRIBUTE_WEAK) && !defined(__CYGWIN__)
+__attribute__((weak))
+int pthread_mutexattr_init(pthread_mutexattr_t *attr);
+
+__attribute__((weak))
+int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
+
+__attribute__((weak))
+int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);
+#endif
+
// 7.25.4.2
static inline int
mtx_init(mtx_t *mtx, int type)
// 7.25.4.4
static inline int
-mtx_timedlock(mtx_t *mtx, const xtime *xt)
+mtx_timedlock(mtx_t *mtx, const struct timespec *ts)
{
assert(mtx != NULL);
- assert(xt != NULL);
+ assert(ts != NULL);
{
#ifdef EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
- struct timespec ts;
int rt;
- ts.tv_sec = xt->sec;
- ts.tv_nsec = xt->nsec;
- rt = pthread_mutex_timedlock(mtx, &ts);
+ rt = pthread_mutex_timedlock(mtx, ts);
if (rt == 0)
return thrd_success;
return (rt == ETIMEDOUT) ? thrd_busy : thrd_error;
#else
time_t expire = time(NULL);
- expire += xt->sec;
+ expire += ts->tv_sec;
while (mtx_trylock(mtx) != thrd_success) {
time_t now = time(NULL);
if (expire < now)
// 7.25.5.7
static inline void
-thrd_sleep(const xtime *xt)
+thrd_sleep(const struct timespec *time_point, struct timespec *remaining)
{
- struct timespec req;
- assert(xt);
- req.tv_sec = xt->sec;
- req.tv_nsec = xt->nsec;
- nanosleep(&req, NULL);
+ assert(time_point != NULL);
+ nanosleep(time_point, remaining);
}
// 7.25.5.8
/*-------------------- 7.25.7 Time functions --------------------*/
// 7.25.6.1
+#ifndef HAVE_TIMESPEC_GET
static inline int
-xtime_get(xtime *xt, int base)
+timespec_get(struct timespec *ts, int base)
{
- if (!xt) return 0;
+ if (!ts) return 0;
if (base == TIME_UTC) {
- xt->sec = time(NULL);
- xt->nsec = 0;
+ clock_gettime(CLOCK_REALTIME, ts);
return base;
}
return 0;
}
+#endif