schedule(xbt_context_t c);
static void
-unschedule(xbt_context_t c);
+yield(xbt_context_t c);
static void
schedule(xbt_context_t c)
{
- xbt_os_sem_post(c->begin);
- xbt_os_sem_wait(c->end);
+ xbt_os_sem_release(c->begin);
+ xbt_os_sem_acquire(c->end);
}
-static void unschedule(xbt_context_t c)
+static void yield(xbt_context_t c)
{
- xbt_os_sem_post(c->end);
- xbt_os_sem_wait(c->begin);
+ xbt_os_sem_release(c->end);
+ xbt_os_sem_acquire(c->begin);
}
#endif
#ifdef CONTEXT_THREADS
/*
- * initialize the semaphores used to schedule/unschedule
+ * initialize the semaphores used to schedule/yield
* the process associated to the newly created context
*/
- res->begin = xbt_os_sem_init(0,0);
- res->end = xbt_os_sem_init(0,0);
+ res->begin = xbt_os_sem_init(0);
+ res->end = xbt_os_sem_init(0);
#else
xbt_assert2(getcontext(&(res->uc)) == 0,
/*context->thread = xbt_os_thread_self();*/
/* signal its starting to the maestro and wait to start its job*/
- unschedule(context);
+ yield(context);
#endif
context->thread = xbt_os_thread_create(context->name,__context_wrapper, context);
/* wait the starting of the newly created process */
- xbt_os_sem_wait(context->end);
+ xbt_os_sem_acquire(context->end);
#else
makecontext(&(context->uc), (void (*)(void)) __context_wrapper, 1, context);
#endif
#ifdef CONTEXT_THREADS
/* signal to the maestro that it has finished */
- xbt_os_sem_post(current_context->end);
+ xbt_os_sem_release(current_context->end);
/* exit*/
xbt_os_thread_exit(NULL); /* We should provide return value in case other wants it */
#else
current_context = context;
/* yield itself */
- unschedule(context);
+ yield(context);
/* restore the current context to the previously saved context */
current_context = self;
return res;
}
-void xbt_os_mutex_lock(xbt_os_mutex_t mutex) {
+void xbt_os_mutex_acquire(xbt_os_mutex_t mutex) {
int errcode;
if ((errcode=pthread_mutex_lock(&(mutex->m))))
mutex, strerror(errcode));
}
-void xbt_os_mutex_unlock(xbt_os_mutex_t mutex) {
+void xbt_os_mutex_release(xbt_os_mutex_t mutex) {
int errcode;
if ((errcode=pthread_mutex_unlock(&(mutex->m))))
typedef struct xbt_os_sem_ {
sem_t s;
- int pshared;
- unsigned int value;
- const char* name;
}s_xbt_os_sem_t ;
xbt_os_sem_t
-xbt_os_sem_init(int pshared, unsigned int value)
+xbt_os_sem_init(unsigned int value)
{
xbt_os_sem_t res = xbt_new(s_xbt_os_sem_t,1);
- if(sem_init(&(res->s),pshared,value) < 0)
+ if(sem_init(&(res->s),0,value) < 0)
THROW1(system_error,errno,"sem_init() failed: %s",
strerror(errno));
- res->pshared = pshared;
- res->value = value;
-
return res;
}
void
-xbt_os_sem_wait(xbt_os_sem_t sem)
+xbt_os_sem_acquire(xbt_os_sem_t sem)
{
if(!sem)
- THROW1(arg_error,EINVAL,"xbt_os_sem_wait() failed: %s",
+ THROW1(arg_error,EINVAL,"xbt_os_sem_acquire() failed: %s",
strerror(EINVAL));
if(sem_wait(&(sem->s)) < 0)
strerror(errno));
}
-void xbt_os_sem_timedwait(xbt_os_sem_t sem,const struct timespec* abs_timeout)
+void xbt_os_sem_timedacquire(xbt_os_sem_t sem,double timeout)
{
+ int errcode;
+ struct timespec ts_end;
+ double end = timeout + xbt_os_time();
+
if(!sem)
- THROW1(arg_error,EINVAL,"xbt_os_sem_timedwait() failed: %s",
- strerror(EINVAL));
+ THROW1(arg_error,EINVAL,"xbt_os_sem_timedacquire() failed: %s",strerror(EINVAL));
- /* only throw an exception if the global variable errno is different than ETIMEDOUT :
- * (the semaphore could not be locked before the specified timeout expired)
- */
- if((sem_timedwait(&(sem->s),abs_timeout) < 0) && (ETIMEDOUT != errno))
- THROW1(system_error,errno,"sem_wait() failed: %s",
- strerror(errno));
+ if (timeout < 0)
+ {
+ xbt_os_sem_acquire(sem);
+ }
+ else
+ {
+ ts_end.tv_sec = (time_t) floor(end);
+ ts_end.tv_nsec = (long) ( ( end - ts_end.tv_sec) * 1000000000);
+ DEBUG2("sem_timedwait(%p,%p)",&(sem->s),&ts_end);
+
+ switch ((errcode=sem_timedwait(&(sem->s),&ts_end)))
+ {
+ case 0:
+ return;
+
+ case ETIMEDOUT:
+ THROW2(timeout_error,errcode,"semaphore %p wasn't signaled before timeout (%f)",sem,timeout);
+
+ default:
+ THROW3(system_error,errcode,"sem_timedwait(%p,%f) failed: %s",sem,timeout, strerror(errcode));
+ }
+ }
}
void
-xbt_os_sem_post(xbt_os_sem_t sem)
+xbt_os_sem_release(xbt_os_sem_t sem)
{
if(!sem)
- THROW1(arg_error,EINVAL,"xbt_os_sem_post() failed: %s",
+ THROW1(arg_error,EINVAL,"xbt_os_sem_release() failed: %s",
strerror(EINVAL));
if(sem_post(&(sem->s)) < 0)
strerror(errno));
}
-void
-xbt_os_sem_close(xbt_os_sem_t sem)
-{
- if(!sem)
- THROW1(arg_error,EINVAL,"xbt_os_sem_close() failed: %s",
- strerror(EINVAL));
-
- if(sem_close(&(sem->s)) < 0)
- THROW1(system_error,errno,"sem_close() failed: %s",
- strerror(errno));
-}
-
-xbt_os_sem_t
-xbt_os_sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
-{
- sem_t* ps;
- xbt_os_sem_t res = xbt_new(s_xbt_os_sem_t,1);
-
- if(SEM_FAILED == (ps = sem_open(name,oflag, mode, value)))
- THROW1(system_error,errno,"sem_open() failed: %s",
- strerror(errno));
-
- res->s = *ps;
- res->value = value;
-
- return res;
-}
-
void
xbt_os_sem_destroy(xbt_os_sem_t sem)
{
#elif defined(WIN32)
+#include <math.h>
+
typedef struct xbt_os_thread_ {
char *name;
HANDLE handle; /* the win thread handle */
return res;
}
-void xbt_os_mutex_lock(xbt_os_mutex_t mutex) {
+void xbt_os_mutex_acquire(xbt_os_mutex_t mutex) {
EnterCriticalSection(& mutex->lock);
}
-void xbt_os_mutex_unlock(xbt_os_mutex_t mutex) {
+void xbt_os_mutex_release(xbt_os_mutex_t mutex) {
LeaveCriticalSection (& mutex->lock);
typedef struct xbt_os_sem_ {
HANDLE h;
unsigned int value;
- const char* name;
CRITICAL_SECTION value_lock; /* protect access to value of the semaphore */
}s_xbt_os_sem_t ;
xbt_os_sem_t
-xbt_os_sem_init(int pshared, unsigned int value)
+xbt_os_sem_init(unsigned int value)
{
xbt_os_sem_t res;
- if(0 != pshared)
- THROW1(arg_error,EPERM,"xbt_os_sem_init() failed: %s",
- strerror(EPERM));
-
if(value > INT_MAX)
THROW1(arg_error,EINVAL,"xbt_os_sem_init() failed: %s",
strerror(EINVAL));
}
void
-xbt_os_sem_wait(xbt_os_sem_t sem)
+xbt_os_sem_acquire(xbt_os_sem_t sem)
{
if(!sem)
- THROW1(arg_error,EINVAL,"xbt_os_sem_wait() failed: %s",
+ THROW1(arg_error,EINVAL,"xbt_os_sem_acquire() failed: %s",
strerror(EINVAL));
/* wait failure */
LeaveCriticalSection(&(sem->value_lock));
}
-void xbt_os_sem_timedwait(xbt_os_sem_t sem,const struct timespec* abs_timeout)
+void xbt_os_sem_timedacquire(xbt_os_sem_t sem, double timeout)
{
- long timeout;
- struct timeval tv;
+ long seconds;
+ long milliseconds;
+ double end = timeout + xbt_os_time();
if(!sem)
- THROW1(arg_error,EINVAL,"xbt_os_sem_timedwait() failed: %s",
+ THROW1(arg_error,EINVAL,"xbt_os_sem_timedacquire() failed: %s",
strerror(EINVAL));
-
- if(!abs_timeout)
- timeout = INFINITE;
- else
- {
- if(gettimeofday(&tv, NULL) < 0)
- THROW1(system_error,errno,"gettimeofday() failed: %s",
- strerror(errno));
-
- timeout = ((long) (abs_timeout->tv_sec - tv.tv_sec) * 1e3 + (long)((abs_timeout->tv_nsec / 1e3) - tv.tv_usec) / 1e3);
- }
- switch(WaitForSingleObject(sem->h,timeout))
+ if (timeout < 0)
+ {
+ xbt_os_sem_acquire(sem);
+ }
+ else
{
- case WAIT_OBJECT_0:
- EnterCriticalSection(&(sem->value_lock));
- sem->value--;
- LeaveCriticalSection(&(sem->value_lock));
- return;
- case WAIT_TIMEOUT:
- /* it's not an exception :
- * (semaphore could not be locked before the specified timeout expired)
- */
- return;
+ seconds = (long) floor(end);
+ milliseconds = (long)( ( end - seconds) * 1000);
+ milliseconds += (seconds * 1000);
- default:
+ switch(WaitForSingleObject(sem->h,milliseconds))
+ {
+ case WAIT_OBJECT_0:
+ EnterCriticalSection(&(sem->value_lock));
+ sem->value--;
+ LeaveCriticalSection(&(sem->value_lock));
+ return;
+
+ case WAIT_TIMEOUT:
+ THROW2(timeout_error,GetLastError(),"semaphore %p wasn't signaled before timeout (%f)",sem,timeout);
+ return;
+
+ default:
- THROW1(system_error,GetLastError(),"WaitForSingleObject() failed: %s",
- strerror(GetLastError()));
+ THROW3(system_error,GetLastError(),"WaitForSingleObject(%p,%f) failed: %s",sem,timeout, strerror(GetLastError()));
+ }
}
}
void
-xbt_os_sem_post(xbt_os_sem_t sem)
+xbt_os_sem_release(xbt_os_sem_t sem)
{
if(!sem)
THROW1(arg_error,EINVAL,"xbt_os_sem_post() failed: %s",
LeaveCriticalSection(&(sem->value_lock));
}
-xbt_os_sem_t
-xbt_os_sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
-{
- THROW_UNIMPLEMENTED;
-}
-
-void
-xbt_os_sem_close(xbt_os_sem_t sem)
-{
- THROW_UNIMPLEMENTED;
-}
-
void
xbt_os_sem_destroy(xbt_os_sem_t sem)
{
rctx_t rctx;
DEBUG2("Armageddon request by <%s> (exit=%d)",initiator->filepos,exitcode);
- xbt_os_mutex_lock(armageddon_mutex);
+ xbt_os_mutex_acquire(armageddon_mutex);
if (armageddon_initiator != NULL) {
VERB0("Armageddon already started. Let it go");
- xbt_os_mutex_unlock(initiator->interruption);
- xbt_os_mutex_unlock(armageddon_mutex);
+ xbt_os_mutex_release(initiator->interruption);
+ xbt_os_mutex_release(armageddon_mutex);
return;
}
DEBUG1("Armageddon request by <%s> got the lock. Let's go amok",initiator->filepos);
armageddon_initiator = initiator;
- xbt_os_mutex_unlock(armageddon_mutex);
+ xbt_os_mutex_release(armageddon_mutex);
/* Kill any background commands */
while (xbt_dynar_length(bg_jobs)) {
xbt_dynar_pop(bg_jobs,&rctx);
if (rctx != initiator) {
INFO2("Kill <%s> because <%s> failed",rctx->filepos,initiator->filepos);
- xbt_os_mutex_lock(rctx->interruption);
+ xbt_os_mutex_acquire(rctx->interruption);
rctx->interrupted = 1;
- xbt_os_mutex_unlock(rctx->interruption);
+ xbt_os_mutex_release(rctx->interruption);
if (!rctx->reader_done) {
kill(rctx->pid,SIGTERM);
usleep(100);
now = time(NULL);
}
- xbt_os_mutex_lock(rctx->interruption);
+ xbt_os_mutex_acquire(rctx->interruption);
if (!rctx->interrupted && rctx->end_time > 0 && rctx->end_time < now) {
INFO1("<%s> timeouted. Kill the process.",rctx->filepos);
rctx->timeout = 1;
xbt_os_thread_join(rctx->writer,NULL);
xbt_os_thread_join(rctx->reader,NULL);
- /* xbt_os_mutex_unlock(rctx->interruption);
+ /* xbt_os_mutex_release(rctx->interruption);
if (rctx->interrupted)
return NULL;
- xbt_os_mutex_lock(rctx->interruption);*/
+ xbt_os_mutex_acquire(rctx->interruption);*/
xbt_strbuff_chomp(rctx->output_got);
xbt_strbuff_chomp(rctx->output_wanted);
}
}
- xbt_os_mutex_unlock(rctx->interruption);
+ xbt_os_mutex_release(rctx->interruption);
return NULL;
}