-#include <sched.h>
-void xbt_os_thread_yield(void) {
- sched_yield();
-}
-void xbt_os_thread_cancel(xbt_os_thread_t t) {
- pthread_cancel(t->t);
-}
-/****** mutex related functions ******/
-typedef struct xbt_os_mutex_ {
- /* KEEP IT IN SYNC WITH xbt_thread.c */
- pthread_mutex_t m;
-} s_xbt_os_mutex_t;
-
-#include <time.h>
-#include <math.h>
-
-xbt_os_mutex_t xbt_os_mutex_init(void) {
- xbt_os_mutex_t res = xbt_new(s_xbt_os_mutex_t,1);
- int errcode;
-
- if ((errcode = pthread_mutex_init(&(res->m),NULL)))
- THROW1(system_error,errcode,"pthread_mutex_init() failed: %s",
- strerror(errcode));
-
- return res;
-}
-
-void xbt_os_mutex_acquire(xbt_os_mutex_t mutex) {
- int errcode;
-
- if ((errcode=pthread_mutex_lock(&(mutex->m))))
- THROW2(system_error,errcode,"pthread_mutex_lock(%p) failed: %s",
- mutex, strerror(errcode));
-}
-
-
-void xbt_os_mutex_timedacquire(xbt_os_mutex_t mutex, double delay) {
- int errcode;
-
- if (delay < 0) {
- xbt_os_mutex_acquire(mutex);
-
- } else if (delay == 0) {
- errcode=pthread_mutex_trylock(&(mutex->m));
-
- switch (errcode) {
- case 0:
- return;
- case ETIMEDOUT:
- THROW1(timeout_error,0,"mutex %p not ready",mutex);
- default:
- THROW2(system_error,errcode,"xbt_mutex_tryacquire(%p) failed: %s",mutex, strerror(errcode));
- }
-
-
- } else {
-
-#ifdef HAVE_MUTEX_TIMEDLOCK
- struct timespec ts_end;
- double end = delay + xbt_os_time();
-
- 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);
-
- errcode=pthread_mutex_timedlock(&(mutex->m),&ts_end);
-
-#else /* Well, let's reimplement it since those lazy libc dudes didn't */
- double start = xbt_os_time();
- do {
- errcode = pthread_mutex_trylock(&(mutex->m));
- if (errcode == EBUSY)
- xbt_os_thread_yield();
- } while (errcode == EBUSY && xbt_os_time()-start <delay);
-
- if (errcode == EBUSY)
- errcode = ETIMEDOUT;
-
-#endif /* HAVE_MUTEX_TIMEDLOCK */
-
- switch (errcode) {
- case 0:
- return;
-
- case ETIMEDOUT:
- THROW2(timeout_error,delay,"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));
- }
- }
-}
-
-void xbt_os_mutex_release(xbt_os_mutex_t mutex) {
- int errcode;
-
- if ((errcode=pthread_mutex_unlock(&(mutex->m))))
- THROW2(system_error,errcode,"pthread_mutex_unlock(%p) failed: %s",
- mutex, strerror(errcode));
-}
-
-void xbt_os_mutex_destroy(xbt_os_mutex_t mutex) {
- int errcode;
-
- if (!mutex) return;
-
- if ((errcode=pthread_mutex_destroy(&(mutex->m))))
- THROW2(system_error,errcode,"pthread_mutex_destroy(%p) failed: %s",
- mutex, strerror(errcode));
- free(mutex);
-}
-
-/***** condition related functions *****/
-typedef struct xbt_os_cond_ {
- /* KEEP IT IN SYNC WITH xbt_thread.c */
- pthread_cond_t c;
-} s_xbt_os_cond_t;
-
-xbt_os_cond_t xbt_os_cond_init(void) {
- xbt_os_cond_t res = xbt_new(s_xbt_os_cond_t,1);
- int errcode;
- if ((errcode=pthread_cond_init(&(res->c),NULL)))
- THROW1(system_error,errcode,"pthread_cond_init() failed: %s",
- strerror(errcode));
-
- return res;
-}
-
-void xbt_os_cond_wait(xbt_os_cond_t cond, xbt_os_mutex_t mutex) {
- int errcode;
- if ((errcode=pthread_cond_wait(&(cond->c),&(mutex->m))))
- THROW3(system_error,errcode,"pthread_cond_wait(%p,%p) failed: %s",
- cond,mutex, strerror(errcode));
-}
-
-
-void xbt_os_cond_timedwait(xbt_os_cond_t cond, xbt_os_mutex_t mutex, double delay) {
- int errcode;
- struct timespec ts_end;
- double end = delay + xbt_os_time();
-
- if (delay < 0) {
- xbt_os_cond_wait(cond,mutex);
- } else {
- ts_end.tv_sec = (time_t) floor(end);
- ts_end.tv_nsec = (long) ( ( end - ts_end.tv_sec) * 1000000000);
- DEBUG3("pthread_cond_timedwait(%p,%p,%p)",&(cond->c),&(mutex->m), &ts_end);
- switch ( (errcode=pthread_cond_timedwait(&(cond->c),&(mutex->m), &ts_end)) ) {
- case 0:
- return;
- case ETIMEDOUT:
- THROW3(timeout_error,errcode,"condition %p (mutex %p) wasn't signaled before timeout (%f)",
- cond,mutex, delay);
- default:
- THROW4(system_error,errcode,"pthread_cond_timedwait(%p,%p,%f) failed: %s",
- cond,mutex, delay, strerror(errcode));
- }
- }
-}
-
-void xbt_os_cond_signal(xbt_os_cond_t cond) {
- int errcode;
- if ((errcode=pthread_cond_signal(&(cond->c))))
- THROW2(system_error,errcode,"pthread_cond_signal(%p) failed: %s",
- cond, strerror(errcode));
-}
-
-void xbt_os_cond_broadcast(xbt_os_cond_t cond){
- int errcode;
- if ((errcode=pthread_cond_broadcast(&(cond->c))))
- THROW2(system_error,errcode,"pthread_cond_broadcast(%p) failed: %s",
- cond, strerror(errcode));
-}
-void xbt_os_cond_destroy(xbt_os_cond_t cond){
- int errcode;
-
- if (!cond) return;
-
- if ((errcode=pthread_cond_destroy(&(cond->c))))
- THROW2(system_error,errcode,"pthread_cond_destroy(%p) failed: %s",
- cond, strerror(errcode));
- free(cond);
-}
-
-void *xbt_os_thread_getparam(void) {
- xbt_os_thread_t t = xbt_os_thread_self();
- return t?t->param:NULL;
-}
-
-typedef struct xbt_os_sem_ {
- #ifndef HAVE_SEM_INIT
- char* name;
- #endif
- sem_t s;
- sem_t *ps;
-}s_xbt_os_sem_t ;
-
-#ifndef SEM_FAILED
-#define SEM_FAILED (-1)
-#endif
-
-xbt_os_sem_t
-xbt_os_sem_init(unsigned int value) {
- xbt_os_sem_t res = xbt_new(s_xbt_os_sem_t,1);
-
- /* On some systems (MAC OS X), only the stub of sem_init is to be found.
- * Any attempt to use it leads to ENOSYS (function not implemented).
- * If such a prehistoric system is detected, do the job with sem_open instead
- */
-#ifdef HAVE_SEM_INIT
- if(sem_init(&(res->s),0,value) != 0)
- THROW1(system_error,errno,"sem_init() failed: %s", strerror(errno));
- res->ps = &(res->s);
-
-#else /* damn, no sem_init(). Reimplement it */
-
- xbt_os_mutex_acquire(next_sem_ID_lock);
- res->name = bprintf("/%d.%d",(*xbt_getpid)(),++next_sem_ID);
- xbt_os_mutex_release(next_sem_ID_lock);
-
- res->ps = sem_open(res->name, O_CREAT, 0644, value);
- if ((res->ps == (sem_t *)SEM_FAILED) && (errno == ENAMETOOLONG)) {
- /* Old darwins only allow 13 chars. Did you create *that* amount of semaphores? */
- res->name[13] = '\0';
- res->ps = sem_open(res->name, O_CREAT, 0644, 1);
- }
- if ((res->ps == (sem_t *)SEM_FAILED))
- THROW1(system_error,errno,"sem_open() failed: %s",strerror(errno));
-
- /* Remove the name from the semaphore namespace: we never join on it */
- if(sem_unlink(res->name) < 0)
- THROW1(system_error,errno,"sem_unlink() failed: %s", strerror(errno));
-