* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
+#ifndef assert
#include <assert.h>
+#endif
#include <limits.h>
#include <errno.h>
#include <unistd.h>
static inline int
cnd_broadcast(cnd_t *cond)
{
- if (!cond) return thrd_error;
- pthread_cond_broadcast(cond);
- return thrd_success;
+ assert(cond != NULL);
+ return (pthread_cond_broadcast(cond) == 0) ? thrd_success : thrd_error;
}
// 7.25.3.2
static inline int
cnd_init(cnd_t *cond)
{
- if (!cond) return thrd_error;
- pthread_cond_init(cond, NULL);
- return thrd_success;
+ assert(cond != NULL);
+ return (pthread_cond_init(cond, NULL) == 0) ? thrd_success : thrd_error;
}
// 7.25.3.4
static inline int
cnd_signal(cnd_t *cond)
{
- if (!cond) return thrd_error;
- pthread_cond_signal(cond);
- return thrd_success;
+ assert(cond != NULL);
+ return (pthread_cond_signal(cond) == 0) ? thrd_success : thrd_error;
}
// 7.25.3.5
{
struct timespec abs_time;
int rt;
- if (!cond || !mtx || !xt) return thrd_error;
+
+ assert(mtx != NULL);
+ assert(cond != NULL);
+ assert(xt != NULL);
+
+ abs_time.tv_sec = xt->sec;
+ abs_time.tv_nsec = xt->nsec;
+
rt = pthread_cond_timedwait(cond, mtx, &abs_time);
if (rt == ETIMEDOUT)
return thrd_busy;
static inline int
cnd_wait(cnd_t *cond, mtx_t *mtx)
{
- if (!cond || !mtx) return thrd_error;
- pthread_cond_wait(cond, mtx);
- return thrd_success;
+ assert(mtx != NULL);
+ assert(cond != NULL);
+ return (pthread_cond_wait(cond, mtx) == 0) ? thrd_success : thrd_error;
}
static inline void
mtx_destroy(mtx_t *mtx)
{
- assert(mtx);
+ assert(mtx != NULL);
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)
{
pthread_mutexattr_t attr;
- if (!mtx) return thrd_error;
+ assert(mtx != NULL);
if (type != mtx_plain && type != mtx_timed && type != mtx_try
&& type != (mtx_plain|mtx_recursive)
&& type != (mtx_timed|mtx_recursive)
&& type != (mtx_try|mtx_recursive))
return thrd_error;
- pthread_mutexattr_init(&attr);
- if ((type & mtx_recursive) != 0) {
-#if defined(__linux__) || defined(__linux)
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
-#else
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-#endif
+
+ if ((type & mtx_recursive) == 0) {
+ pthread_mutex_init(mtx, NULL);
+ return thrd_success;
}
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(mtx, &attr);
pthread_mutexattr_destroy(&attr);
return thrd_success;
static inline int
mtx_lock(mtx_t *mtx)
{
- if (!mtx) return thrd_error;
- pthread_mutex_lock(mtx);
- return thrd_success;
+ assert(mtx != NULL);
+ return (pthread_mutex_lock(mtx) == 0) ? thrd_success : thrd_error;
}
static inline int
static inline int
mtx_timedlock(mtx_t *mtx, const xtime *xt)
{
- if (!mtx || !xt) return thrd_error;
+ assert(mtx != NULL);
+ assert(xt != NULL);
+
{
#ifdef EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
struct timespec ts;
static inline int
mtx_trylock(mtx_t *mtx)
{
- if (!mtx) return thrd_error;
+ assert(mtx != NULL);
return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
}
static inline int
mtx_unlock(mtx_t *mtx)
{
- if (!mtx) return thrd_error;
- pthread_mutex_unlock(mtx);
- return thrd_success;
+ assert(mtx != NULL);
+ return (pthread_mutex_unlock(mtx) == 0) ? thrd_success : thrd_error;
}
thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
{
struct impl_thrd_param *pack;
- if (!thr) return thrd_error;
+ assert(thr != NULL);
pack = (struct impl_thrd_param *)malloc(sizeof(struct impl_thrd_param));
if (!pack) return thrd_nomem;
pack->func = func;
static inline int
tss_create(tss_t *key, tss_dtor_t dtor)
{
- if (!key) return thrd_error;
+ assert(key != NULL);
return (pthread_key_create(key, dtor) == 0) ? thrd_success : thrd_error;
}