[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] concurrency-libtask 80d9d4e: Support for context switching
From: |
Philipp Stephani |
Subject: |
[Emacs-diffs] concurrency-libtask 80d9d4e: Support for context switching using pthreads |
Date: |
Thu, 27 Oct 2016 21:14:52 +0000 (UTC) |
branch: concurrency-libtask
commit 80d9d4e6001c71707e941455592072332573e616
Author: Philipp Stephani <address@hidden>
Commit: Philipp Stephani <address@hidden>
Support for context switching using pthreads
Experimental, doesn’t work yet
---
lib/libtask/context.c | 28 +++++++++++++++++++++++++++-
lib/libtask/task.c | 32 ++++++++++++++++++++++++++++++--
lib/libtask/taskimpl.h | 26 +++++++++++++++++++++++---
3 files changed, 80 insertions(+), 6 deletions(-)
diff --git a/lib/libtask/context.c b/lib/libtask/context.c
index db7d25c..95c140c 100644
--- a/lib/libtask/context.c
+++ b/lib/libtask/context.c
@@ -9,7 +9,7 @@
#define UNICODE
#include <windows.h>
-#else
+#elseif ! defined LIBTASK_USE_PTHREAD
#if defined(__APPLE__)
#if defined(__i386__)
@@ -159,3 +159,29 @@ swapcontext (ucontext_t *oucp, const ucontext_t *ucp)
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
diff --git a/lib/libtask/task.c b/lib/libtask/task.c
index 4e271f3..4d68e7e 100644
--- a/lib/libtask/task.c
+++ b/lib/libtask/task.c
@@ -11,6 +11,10 @@
#include <windows.h>
#endif
+#ifdef LIBTASK_USE_PTHREAD
+#include <pthread.h>
+#endif
+
int taskdebuglevel;
int taskcount;
int tasknswitch;
@@ -62,7 +66,7 @@ return;
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)
{
@@ -82,6 +86,21 @@ 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*
@@ -108,9 +127,18 @@ taskalloc(void (*fn)(void*), void *arg, uint stack)
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
t->startfn = fn;
@@ -121,7 +149,7 @@ taskalloc(void (*fn)(void*), void *arg, uint stack)
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);
diff --git a/lib/libtask/taskimpl.h b/lib/libtask/taskimpl.h
index 2b1e31c..0d23373 100644
--- a/lib/libtask/taskimpl.h
+++ b/lib/libtask/taskimpl.h
@@ -28,12 +28,17 @@
#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>
@@ -89,7 +94,7 @@ char *vsnprint(char*, uint, char*, va_list);
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
@@ -100,6 +105,21 @@ typedef struct libtask_fiber_ucontext {
} 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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] concurrency-libtask 80d9d4e: Support for context switching using pthreads,
Philipp Stephani <=