[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] concurrency-libtask 150bbf2 3/6: Support for Windows fiber
From: |
Philipp Stephani |
Subject: |
[Emacs-diffs] concurrency-libtask 150bbf2 3/6: Support for Windows fibers |
Date: |
Tue, 25 Oct 2016 23:25:28 +0000 (UTC) |
branch: concurrency-libtask
commit 150bbf2e0ed5fff8aff5e073aff21db851e3d6a9
Author: Philipp Stephani <address@hidden>
Commit: Philipp Stephani <address@hidden>
Support for Windows fibers
---
lib/libtask/context.c | 20 ++++++++++++++++++++
lib/libtask/task.c | 30 ++++++++++++++++++++++++++++++
lib/libtask/taskimpl.h | 24 ++++++++++++++++++++++++
3 files changed, 74 insertions(+)
diff --git a/lib/libtask/context.c b/lib/libtask/context.c
index 9571996..db7d25c 100644
--- a/lib/libtask/context.c
+++ b/lib/libtask/context.c
@@ -2,6 +2,15 @@
#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
@@ -35,6 +44,8 @@
#define NEEDMIPSMAKECONTEXT
#endif
+#endif
+
#ifdef NEEDPOWERMAKECONTEXT
void
makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
@@ -139,3 +150,12 @@ swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
return 0;
}
#endif
+
+#ifdef LIBTASK_USE_FIBER
+int
+swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
+{
+ SwitchToFiber (ucp->fiber);
+ return 0;
+}
+#endif
diff --git a/lib/libtask/task.c b/lib/libtask/task.c
index ebb8681..4e271f3 100644
--- a/lib/libtask/task.c
+++ b/lib/libtask/task.c
@@ -4,6 +4,13 @@
#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;
@@ -55,6 +62,7 @@ return;
fprint(fd, "%d._: %s\n", getpid(), buf);
}
+#ifndef LIBTASK_USE_FIBER
static void
taskstart(uint y, uint x)
{
@@ -72,6 +80,7 @@ taskstart(uint y, uint x)
taskexit(0);
//print("not reacehd\n");
}
+#endif
static int taskidgen;
@@ -83,23 +92,36 @@ taskalloc(void (*fn)(void*), void *arg, uint stack)
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);
@@ -133,6 +155,7 @@ taskalloc(void (*fn)(void*), void *arg, uint stack)
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;
}
@@ -308,6 +331,7 @@ taskgetstate(void)
void
needstack(int n)
{
+#ifndef LIBTASK_USE_FIBER
Task *t;
t = taskrunning;
@@ -317,6 +341,7 @@ needstack(int n)
fprint(2, "task stack overflow: &t=%p tstk=%p n=%d\n", &t,
t->stk, 256+n);
abort();
}
+#endif
}
static void
@@ -374,6 +399,11 @@ main(int argc, char **argv)
taskargc = argc;
taskargv = argv;
+#ifdef LIBTASK_USE_FIBER
+ if (ConvertThreadToFiber (NULL) == NULL)
+ return 2;
+#endif
+
if(mainstacksize == 0)
mainstacksize = 256*1024;
#ifdef EMACS
diff --git a/lib/libtask/taskimpl.h b/lib/libtask/taskimpl.h
index 03a26c2..2b1dd8f 100644
--- a/lib/libtask/taskimpl.h
+++ b/lib/libtask/taskimpl.h
@@ -27,6 +27,11 @@
#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>
@@ -84,6 +89,19 @@ char *vsnprint(char*, uint, char*, va_list);
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*);
@@ -143,6 +161,8 @@ void setmcontext(const mcontext_t*);
#define getcontext(u) getmcontext(&(u)->uc_mcontext)
#endif
+#endif
+
typedef struct Context Context;
enum
@@ -169,14 +189,18 @@ struct Task
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;
};
- [Emacs-diffs] branch concurrency-libtask created (now cc11c5a), Philipp Stephani, 2016/10/25
- [Emacs-diffs] concurrency-libtask 4b160e6 5/6: Remove wrong assertion, Philipp Stephani, 2016/10/25
- [Emacs-diffs] concurrency-libtask 150bbf2 3/6: Support for Windows fibers,
Philipp Stephani <=
- [Emacs-diffs] concurrency-libtask cc11c5a 6/6: Transfer signals to main coroutine, Philipp Stephani, 2016/10/25
- [Emacs-diffs] concurrency-libtask b9d1f96 1/6: Clarify the behavior of minor mode commands, Philipp Stephani, 2016/10/25
- [Emacs-diffs] concurrency-libtask c349c4d4 4/6: malloc is redefined by config.h, Philipp Stephani, 2016/10/25
- [Emacs-diffs] concurrency-libtask 133208f 2/6: WIP: CSP based on libtask, Philipp Stephani, 2016/10/25