extern "C" int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex, unsigned ms) {
  timespec abs_timeout;
  clock_gettime(CLOCK_MONOTONIC, &abs_timeout);
  abs_timeout.tv_sec  += ms / 1000;
  abs_timeout.tv_nsec += (ms % 1000) * 1000000;
  if (abs_timeout.tv_nsec >= 1000000000) {
    abs_timeout.tv_sec++;
    abs_timeout.tv_nsec -= 1000000000;
  }

  int error = __pthread_mutex_timedlock(mutex, &abs_timeout, CLOCK_MONOTONIC);
  if (error == ETIMEDOUT) {
    error = EBUSY;
  }
  return error;
}
extern "C" int pthread_mutex_lock_timeout_np(pthread_mutex_t* mutex, unsigned ms) {
  timespec abs_timeout;
  clock_gettime(CLOCK_MONOTONIC, &abs_timeout);
  abs_timeout.tv_sec  += ms / 1000;
  abs_timeout.tv_nsec += (ms % 1000) * 1000000;
  if (abs_timeout.tv_nsec >= 1000000000) {
    abs_timeout.tv_sec++;
    abs_timeout.tv_nsec -= 1000000000;
  }

  int err = __pthread_mutex_timedlock(mutex, &abs_timeout, CLOCK_MONOTONIC);
  if (err == ETIMEDOUT) {
    err = EBUSY;
  }
  if (PTHREAD_DEBUG_ENABLED) {
    if (!err) {
      pthread_debug_mutex_lock_check(mutex);
    }
  }
  return err;
}
int pthread_mutex_timedlock(pthread_mutex_t* mutex, const timespec* abs_timeout) {
  return __pthread_mutex_timedlock(mutex, abs_timeout, CLOCK_REALTIME);
}
#include <threads.h>
#include <errno.h>

int __pthread_mutex_timedlock(mtx_t *restrict, const struct timespec *restrict);

int mtx_timedlock(mtx_t *restrict m, const struct timespec *restrict ts)
{
	int ret = __pthread_mutex_timedlock(m, ts);
	switch (ret) {
	default:        return thrd_error;
	case 0:         return thrd_success;
	case ETIMEDOUT: return thrd_timedout;
	}
}