diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | includes/Task.h | 12 | ||||
-rw-r--r-- | includes/TaskMan.h | 6 | ||||
-rw-r--r-- | linux-config.h | 2 | ||||
-rw-r--r-- | src/Task.cc | 20 | ||||
-rw-r--r-- | src/TaskMan.cc | 5 |
6 files changed, 45 insertions, 3 deletions
@@ -139,9 +139,12 @@ darwin-eprintf.c \ endif +ifneq ($(SYSTEM),MINGW32) LIBCORO_SOURCES = \ coro.c \ +endif + LIBEV_SOURCES = \ ev.c \ event.c \ diff --git a/includes/Task.h b/includes/Task.h index 042624d..b124731 100644 --- a/includes/Task.h +++ b/includes/Task.h @@ -1,7 +1,9 @@ #pragma once #include <stdlib.h> +#ifndef _WIN32 #include <coro.h> +#endif #include <ev++.h> #include <vector> #include <Exceptions.h> @@ -81,6 +83,10 @@ class Async : public BaseEvent { ev::async m_evt; }; +#ifndef _WIN32 +#define CALLBACK +#endif + class Custom : public BaseEvent { public: void doSignal() { BaseEvent::doSignal(); ev_break(m_loop, EVBREAK_ALL); } @@ -137,9 +143,13 @@ class Task { private: size_t stackSize() { return 128 * 1024; } void switchTo(); - static void coroutine(void *); + static void CALLBACK coroutine(void *); void * m_stack; +#ifndef _WIN32 coro_context m_ctx; +#else + void * m_fiber; +#endif TaskMan * m_taskMan; Status m_status; void * m_tls; diff --git a/includes/TaskMan.h b/includes/TaskMan.h index 8144e93..ad19f65 100644 --- a/includes/TaskMan.h +++ b/includes/TaskMan.h @@ -1,7 +1,9 @@ #pragma once #include <stdint.h> +#ifndef _WIN32 #include <coro.h> +#endif #include <ev++.h> #include <ext/hash_set> #include <vector> @@ -26,7 +28,11 @@ class TaskMan { private: void registerTask(Task * t); void unregisterTask(Task * t); +#ifndef _WIN32 coro_context m_returnContext; +#else + void * m_fiber; +#endif friend class Task; struct taskHasher { size_t operator()(const Task * t) const { return reinterpret_cast<uintptr_t>(t); } }; typedef gnu::hash_set<Task *, taskHasher> taskHash_t; diff --git a/linux-config.h b/linux-config.h index 4531a67..fe447b7 100644 --- a/linux-config.h +++ b/linux-config.h @@ -2,7 +2,7 @@ #define STDC_HEADERS 1 #define WORDS_LITTLEENDIAN 1 -#define CORO_ASM 1 +#define CORO_UCONTEXT 1 #define _FILE_OFFSET_BITS 64 #define EMBED_LIBEIO 1 diff --git a/src/Task.cc b/src/Task.cc index 558b7de..ad481cc 100644 --- a/src/Task.cc +++ b/src/Task.cc @@ -8,8 +8,13 @@ static Balau::LocalTmpl<Balau::Task> localTask; Balau::Task::Task() { size_t size = stackSize(); +#ifndef _WIN32 m_stack = malloc(size); coro_create(&m_ctx, coroutine, this, m_stack, size); +#else + m_stack = NULL; + m_fiber = CreateFiber(size, coroutine, this); +#endif m_taskMan = TaskMan::getTaskMan(); m_taskMan->registerTask(this); @@ -27,7 +32,8 @@ Balau::Task::Task() { } Balau::Task::~Task() { - free(m_stack); + if (m_stack) + free(m_stack); free(m_tls); } @@ -48,7 +54,11 @@ void Balau::Task::coroutine(void * arg) { Printer::log(M_WARNING, "Task %s at %p caused an unknown exception - stopping.", task->getName(), task); task->m_status = FAULTED; } +#ifndef _WIN32 coro_transfer(&task->m_ctx, &task->m_taskMan->m_returnContext); +#else + SwitchToFiber(task->m_taskMan->m_fiber); +#endif } void Balau::Task::switchTo() { @@ -56,7 +66,11 @@ void Balau::Task::switchTo() { Assert(m_status == IDLE || m_status == STARTING); void * oldTLS = g_tlsManager->getTLS(); g_tlsManager->setTLS(m_tls); +#ifndef _WIN32 coro_transfer(&m_taskMan->m_returnContext, &m_ctx); +#else + SwitchToFiber(m_fiber); +#endif g_tlsManager->setTLS(oldTLS); if (m_status == RUNNING) m_status = IDLE; @@ -64,7 +78,11 @@ void Balau::Task::switchTo() { void Balau::Task::yield() { Printer::elog(E_TASK, "Task %p - %s yielding", this, getName()); +#ifndef _WIN32 coro_transfer(&m_ctx, &m_taskMan->m_returnContext); +#else + SwitchToFiber(m_taskMan->m_fiber); +#endif } Balau::Task * Balau::Task::getCurrentTask() { diff --git a/src/TaskMan.cc b/src/TaskMan.cc index fc33530..0fc4668 100644 --- a/src/TaskMan.cc +++ b/src/TaskMan.cc @@ -7,7 +7,12 @@ static Balau::DefaultTmpl<Balau::TaskMan> defaultTaskMan(50); static Balau::LocalTmpl<Balau::TaskMan> localTaskMan; Balau::TaskMan::TaskMan() : m_stopped(false), m_allowedToSignal(false) { +#ifndef _WIN32 coro_create(&m_returnContext, 0, 0, 0, 0); +#else + m_fiber = ConvertThreadToFiber(NULL); + Assert(m_fiber); +#endif if (!localTaskMan.getGlobal()) { localTaskMan.setGlobal(this); m_loop = ev_default_loop(EVFLAG_AUTO); |