/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#if !defined(_WIN32)
#include <sys/time.h>
#include <unistd.h>
-#endif
#include "misc.h"
#include "empthread.h"
#include "prototypes.h"
#define EMPTH_KILLED 1
+#define EMPTH_INTR 2
struct empth_t {
char *name; /* thread name */
pthread_t id; /* thread id */
};
-struct empth_sem_t {
- pthread_mutex_t mtx_update; /* use it to update count */
- int count;
- char name[80];
- pthread_mutex_t mtx_sem;
- pthread_cond_t cnd_sem;
-};
-
struct empth_rwlock_t {
char *name;
pthread_rwlock_t lock;
}
-/*
- * prio can be used for setting scheeduling policy but...
- * it seems to be optional in POSIX threads and Solaris
- * for example just ignores it.
- * More then that priority is not needed even in lwp threads.
- */
empth_t *
-empth_create(int prio, void (*entry)(void *), int size, int flags,
+empth_create(void (*entry)(void *), int size, int flags,
char *name, void *ud)
{
pthread_t t;
empth_status("i am dead");
empth_exit();
}
+ ctx_ptr->state = 0;
empth_status("context restored");
}
{
/*
* Nothing to do --- we handle this signal just to let
- * empth_wakeup() interrupt system calls.
+ * empth_wakeup() and empth_terminate() interrupt system calls.
*/
- empth_status("got alarm signal");
}
void
empth_wakeup(empth_t *a)
{
empth_status("waking up thread %s", a->name);
+ if (a->state == 0)
+ a->state = EMPTH_INTR;
pthread_kill(a->id, SIGALRM);
}
-void
+int
empth_sleep(time_t until)
{
+ empth_t *ctx = pthread_getspecific(ctx_key);
struct timeval tv;
+ int res;
empth_status("going to sleep %ld sec", until - time(0));
pthread_mutex_unlock(&mtx_ctxsw);
- tv.tv_sec = until - time(NULL);
- tv.tv_usec = 0;
do {
- select(0, NULL, NULL, NULL, &tv);
- } while ((tv.tv_sec = until - time(NULL)) > 0);
+ tv.tv_sec = until - time(NULL);
+ tv.tv_usec = 0;
+ res = select(0, NULL, NULL, NULL, &tv);
+ } while (res < 0 && ctx->state == 0);
empth_status("sleep done. Waiting for lock");
pthread_mutex_lock(&mtx_ctxsw);
empth_restorectx();
+ return res;
}
int
}
}
-empth_sem_t *
-empth_sem_create(char *name, int cnt)
-{
- empth_sem_t *sm;
-
- sm = malloc(sizeof(empth_sem_t));
- if (!sm) {
- logerror("out of memory at %s:%d", __FILE__, __LINE__);
- return NULL;
- }
- strncpy(sm->name, name, sizeof(sm->name) - 1);
- sm->count = cnt;
- pthread_mutex_init(&sm->mtx_update, NULL);
- pthread_mutex_init(&sm->mtx_sem, NULL);
- pthread_cond_init(&sm->cnd_sem, NULL);
- return sm;
-}
-
-void
-empth_sem_signal(empth_sem_t *sm)
-{
- empth_status("signal on semaphore %s:%d", sm->name, sm->count);
- pthread_mutex_lock(&sm->mtx_update);
- if (sm->count++ < 0) {
- pthread_mutex_unlock(&sm->mtx_update);
- pthread_mutex_lock(&sm->mtx_sem);
- pthread_cond_signal(&sm->cnd_sem);
- pthread_mutex_unlock(&sm->mtx_sem);
- } else
- pthread_mutex_unlock(&sm->mtx_update);
-}
-
-void
-empth_sem_wait(empth_sem_t *sm)
-{
- empth_status("wait on semaphore %s:%d", sm->name, sm->count);
- pthread_mutex_lock(&sm->mtx_update);
- if (--sm->count < 0) {
- pthread_mutex_unlock(&sm->mtx_update);
- empth_status("blocking");
- pthread_mutex_unlock(&mtx_ctxsw);
- pthread_mutex_lock(&sm->mtx_sem);
- pthread_cond_wait(&sm->cnd_sem, &sm->mtx_sem);
- empth_status("waking up");
- pthread_mutex_unlock(&sm->mtx_sem);
- pthread_mutex_lock(&mtx_ctxsw);
- empth_restorectx();
- } else
- pthread_mutex_unlock(&sm->mtx_update);
-}
-
empth_rwlock_t *
empth_rwlock_create(char *name)
{