+void xbt_os_mutex_tryacquire(xbt_os_mutex_t mutex) {
+ int errcode;
+
+ if ((errcode=pthread_mutex_trylock(&(mutex->m))))
+ THROW2(system_error,errcode,"pthread_mutex_trylock(%p) failed: %s",
+ mutex, strerror(errcode));
+}
+
+
+
+#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+/* if the function is not availabled or if is MAC OS X use pthread_mutex_trylock() to define
+ * it.
+ */
+#include <time.h> /* declaration of the timespec structure and of the nanosleep() function */
+int pthread_mutex_timedlock(pthread_mutex_t * mutex, const struct timespec * abs_timeout)
+{
+ int rv;
+ long ellapsed_time = 0;
+ struct timespec ts;
+
+ do
+ {
+ /* the mutex could not be acquired because it was already locked by an other thread */
+ rv = pthread_mutex_trylock(mutex);
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 2.5e7 /* (25 ms (2 context switch + 5 ms)) */;
+
+ do
+ {
+ nanosleep(&ts, &ts);
+ }while(EINTR == errno);
+
+ ellapsed_time += ts.tv_nsec;
+
+ }
+ while (/* locked */ (EBUSY == rv) && /* !timeout */ (ellapsed_time < ((long)(abs_timeout->tv_sec * 1e9) + abs_timeout->tv_nsec)));
+
+ return (EBUSY == rv) ? ETIMEDOUT : rv;
+}
+
+#endif
+
+void xbt_os_mutex_timedacquire(xbt_os_mutex_t mutex, double delay) {
+ int errcode;
+ struct timespec ts_end;
+ double end = delay + xbt_os_time();
+
+ if (delay < 0) {
+ xbt_os_mutex_acquire(mutex);
+ } else {
+ ts_end.tv_sec = (time_t) floor(end);
+ ts_end.tv_nsec = (long) ( ( end - ts_end.tv_sec) * 1000000000);
+ DEBUG2("pthread_mutex_timedlock(%p,%p)",&(mutex->m), &ts_end);
+
+ switch ((errcode=pthread_mutex_timedlock(&(mutex->m),&ts_end)))
+ {
+ case 0:
+ return;
+
+ case ETIMEDOUT:
+ THROW2(timeout_error,errcode,"mutex %p wasn't signaled before timeout (%f)",mutex,delay);
+
+ default:
+ THROW3(system_error,errcode,"pthread_mutex_timedlock(%p,%f) failed: %s",mutex,delay, strerror(errcode));
+ }
+ }
+}
+