emacs-diffs
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]