#include "taskimpl.h"
+#ifdef LIBTASK_USE_FIBER
+
+#define STRICT
+#define NOMINMAX
+#define UNICODE
+#include <windows.h>
+
+#else
+
#if defined(__APPLE__)
#if defined(__i386__)
#define NEEDX86MAKECONTEXT
#define NEEDMIPSMAKECONTEXT
#endif
+#endif
+
#ifdef NEEDPOWERMAKECONTEXT
void
makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
return 0;
}
#endif
+
+#ifdef LIBTASK_USE_FIBER
+int
+swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+{
+ SwitchToFiber (ucp->fiber);
+ return 0;
+}
+#endif
#include <fcntl.h>
#include <stdio.h>
+#ifdef LIBTASK_USE_FIBER
+#define STRICT
+#define NOMINMAX
+#define UNICODE
+#include <windows.h>
+#endif
+
int taskdebuglevel;
int taskcount;
int tasknswitch;
fprint(fd, "%d._: %s\n", getpid(), buf);
}
+#ifndef LIBTASK_USE_FIBER
static void
taskstart(uint y, uint x)
{
taskexit(0);
//print("not reacehd\n");
}
+#endif
static int taskidgen;
uint x, y;
ulong z;
+#ifdef LIBTASK_USE_FIBER
+ t = malloc (sizeof *t);
+#else
/* allocate the task and stack together */
t = malloc(sizeof *t+stack);
+#endif
if(t == nil){
fprint(2, "taskalloc malloc: %r\n");
abort();
}
memset(t, 0, sizeof *t);
+#ifdef LIBTASK_USE_FIBER
+ t->context.uc.fiber = CreateFiber (stack, fn, arg);
+ if (t->context.uc.fiber == NULL)
+ abort ();
+#else
t->stk = (uchar*)(t+1);
t->stksize = stack;
+#endif
t->id = ++taskidgen;
+#ifndef LIBTASK_USE_FIBER
t->startfn = fn;
t->startarg = arg;
+#endif
#ifdef EMACS
init_emacs_lisp_context (t->id == 1, &t->context.ec);
#endif
+#ifndef LIBTASK_USE_FIBER
/* do a reasonable initialization */
memset(&t->context.uc, 0, sizeof t->context.uc);
sigemptyset(&zero);
z >>= 16; /* hide undefined 32-bit shift from 32-bit compilers */
x = z>>16;
makecontext(&t->context.uc, (void(*)())taskstart, 2, y, x);
+#endif
return t;
}
void
needstack(int n)
{
+#ifndef LIBTASK_USE_FIBER
Task *t;
t = taskrunning;
fprint(2, "task stack overflow: &t=%p tstk=%p n=%d\n", &t, t->stk, 256+n);
abort();
}
+#endif
}
static void
taskargc = argc;
taskargv = argv;
+#ifdef LIBTASK_USE_FIBER
+ if (ConvertThreadToFiber (NULL) == NULL)
+ return 2;
+#endif
+
if(mainstacksize == 0)
mainstacksize = 256*1024;
#ifdef EMACS
#ifdef EMACS
#include <config.h>
#include "lisp.h"
+#ifdef WINDOWSNT
+#undef USE_UCONTEXT
+#define USE_UCONTEXT 0
+#define LIBTASK_USE_FIBER
+#endif
#endif
#include <errno.h>
char *vseprint(char*, char*, char*, va_list);
char *strecpy(char*, char*, char*);
+#ifdef LIBTASK_USE_FIBER
+
+#undef ucontext
+#undef ucontext_t
+#define ucontext libtask_fiber_ucontext
+#define ucontext_t libtask_fiber_ucontext_t
+typedef struct libtask_fiber_ucontext {
+ void *fiber;
+} libtask_fiber_ucontext_t;
+extern int swapcontext(ucontext_t *, const ucontext_t *);
+
+#else
+
#if defined(__FreeBSD__) && __FreeBSD__ < 5
extern int getmcontext(mcontext_t*);
extern void setmcontext(const mcontext_t*);
#define getcontext(u) getmcontext(&(u)->uc_mcontext)
#endif
+#endif
+
typedef struct Context Context;
enum
Context context;
uvlong alarmtime;
uint id;
+#ifndef LIBTASK_USE_FIBER
uchar *stk;
uint stksize;
+#endif
int exiting;
int alltaskslot;
int system;
int ready;
+#ifndef LIBTASK_USE_FIBER
void (*startfn)(void*);
void *startarg;
+#endif
void *udata;
};