#define UNICODE
#include <windows.h>
-#else
+#elseif ! defined LIBTASK_USE_PTHREAD
#if defined(__APPLE__)
#if defined(__i386__)
return 0;
}
#endif
+
+#ifdef LIBTASK_USE_PTHREAD
+#include <pthread.h>
+static bool oucp_is_valid = false;
+
+int
+swapcontext (ucontext_t *oucp, /* const */ ucontext_t *ucp)
+{
+ oucp->running = false;
+ ucp->running = true;
+ pthread_mutex_lock (&ucp->mutex);
+ pthread_cond_signal (&ucp->cond);
+ pthread_mutex_unlock (&ucp->mutex);
+ if (! oucp_is_valid)
+ {
+ pthread_mutex_init (&oucp->mutex, NULL);
+ pthread_cond_init (&oucp->cond, NULL);
+ oucp->thread = pthread_self ();
+ oucp_is_valid = true;
+ }
+ pthread_mutex_lock (&oucp->mutex);
+ while (! oucp->running)
+ pthread_cond_wait (&oucp->cond, &oucp->mutex);
+ pthread_mutex_unlock (&oucp->mutex);
+}
+#endif
#include <windows.h>
#endif
+#ifdef LIBTASK_USE_PTHREAD
+#include <pthread.h>
+#endif
+
int taskdebuglevel;
int taskcount;
int tasknswitch;
fprint(fd, "%d._: %s\n", getpid(), buf);
}
-#ifndef LIBTASK_USE_FIBER
+#if ! defined LIBTASK_USE_FIBER && ! defined LIBTASK_USE_PTHREAD
static void
taskstart(uint y, uint x)
{
}
#endif
+#ifdef LIBTASK_USE_PTHREAD
+static void *
+thread_func (void *arg)
+{
+ Task *t = arg;
+ ucontext_t *uc = &t->context.uc;
+ pthread_mutex_lock (&uc->mutex);
+ while (! uc->running)
+ pthread_cond_wait (&uc->cond, &uc->mutex);
+ pthread_mutex_unlock (&uc->mutex);
+ t->startfn (t->startarg);
+ return NULL;
+}
+#endif
+
static int taskidgen;
static Task*
t->context.uc.fiber = CreateFiber (stack, fn, arg);
if (t->context.uc.fiber == NULL)
abort ();
+#else
+#ifdef LIBTASK_USE_PTHREAD
+ if (pthread_mutex_init (&t->context.uc.mutex, NULL) != 0)
+ abort ();
+ if (pthread_cond_init (&t->context.uc.cond, NULL) != 0)
+ abort ();
+ if (pthread_create (&t->context.uc.thread, NULL, thread_func, t) != 0)
+ abort ();
#else
t->stk = (uchar*)(t+1);
t->stksize = stack;
+#endif
#endif
t->id = ++taskidgen;
#ifndef LIBTASK_USE_FIBER
init_emacs_lisp_context (t->id == 1, &t->context.ec);
#endif
-#ifndef LIBTASK_USE_FIBER
+#if ! defined LIBTASK_USE_FIBER && ! defined LIBTASK_USE_PTHREAD
/* do a reasonable initialization */
memset(&t->context.uc, 0, sizeof t->context.uc);
sigemptyset(&zero);
#include <config.h>
#include "lisp.h"
#ifdef WINDOWSNT
-#undef USE_UCONTEXT
-#define USE_UCONTEXT 0
#define LIBTASK_USE_FIBER
+#else
+//#define LIBTASK_USE_PTHREAD
#endif
#endif
+#if defined LIBTASK_USE_FIBER || defined LIBTASK_USE_PTHREAD
+#undef USE_UCONTEXT
+#define USE_UCONTEXT 0
+#endif
+
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
char *vseprint(char*, char*, char*, va_list);
char *strecpy(char*, char*, char*);
-#ifdef LIBTASK_USE_FIBER
+#if defined LIBTASK_USE_FIBER
#undef ucontext
#undef ucontext_t
} libtask_fiber_ucontext_t;
extern int swapcontext(ucontext_t *, const ucontext_t *);
+#elif defined LIBTASK_USE_PTHREAD
+
+#include <pthread.h>
+#undef ucontext
+#undef ucontext_t
+#define ucontext libtask_pthread_ucontext
+#define ucontext_t libtask_pthread_ucontext_t
+typedef struct libtask_pthread_ucontext {
+ pthread_t thread;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ bool running;
+} libtask_pthread_ucontext_t;
+extern int swapcontext(ucontext_t *, /* const */ ucontext_t *);
+
#else
#if defined(__FreeBSD__) && __FreeBSD__ < 5