summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kamm <christian.d.kamm@nokia.com>2010-03-22 12:32:11 +0100
committerChristian Kamm <christian.d.kamm@nokia.com>2010-03-26 13:05:02 +0100
commit883dee678eca4f55faf3848a248253d4b4b8a40e (patch)
treef13c70472015d70cac2707a4dd5b8d295a437b5a
parentb03a4b990d9d26f62958cb1968bcf463e6d87eb5 (diff)
Rename Fiber -> Coroutine.
* Avoid confusion with Windows fibers. * Easier to search for.
-rw-r--r--coroutine.pro (renamed from fibers.pro)0
-rw-r--r--src/coroutine.cpp127
-rw-r--r--src/coroutine.h (renamed from src/fiber.h)20
-rw-r--r--src/fiber.cpp127
-rw-r--r--src/src.pro6
5 files changed, 140 insertions, 140 deletions
diff --git a/fibers.pro b/coroutine.pro
index 65d9262..65d9262 100644
--- a/fibers.pro
+++ b/coroutine.pro
diff --git a/src/coroutine.cpp b/src/coroutine.cpp
new file mode 100644
index 0000000..eb6ebc5
--- /dev/null
+++ b/src/coroutine.cpp
@@ -0,0 +1,127 @@
+#include <stdlib.h>
+#include <QtCore/QtGlobal>
+#include <QtCore/QThreadStorage>
+
+#include "coroutine.h"
+
+/*!
+ \class Coroutine
+ \brief The Coroutine class provides cooperatively scheduled stacks of execution.
+
+ Coroutines, also known as fibers, allow managing multiple stacks in the same
+ thread.
+
+ \omit ### outdated \endomit
+ To create a coroutine, subclass Coroutine and override the run() method. To run it,
+ call cont(). This will execute the code in run() until it calls Coroutine::yield().
+ At that point, the call to cont() returns. Subsequent calls to cont() will
+ continue execution of the coroutine just after the yield().
+
+ Example:
+ void myCoroutine()
+ {
+ qDebug() << "1";
+ Coroutine::yield();
+ qDebug() << "2";
+ }
+
+ MyCoroutine c(&myCoroutine);
+ qDebug() << "0.5";
+ c.cont(); // prints 1
+ qDebug() << "1.5";
+ c.cont(); // prints 2
+*/
+
+#ifdef Q_OS_MAC
+extern "C" void switchStackInternal(void* to, void** from);
+void initializeStack(void *data, int size, void (*entry)(), void **stackPointer);
+void switchStack(void* to, void** from) { switchStackInternal(to, from); }
+#else
+extern "C" void _switchStackInternal(void* to, void** from);
+void initializeStack(void *data, int size, void (*entry)(), void **stackPointer);
+void switchStack(void* to, void** from) { _switchStackInternal(to, from); }
+#endif
+
+Coroutine::Coroutine(StartFunction startFunction, int stackSize)
+ : _startFunction(startFunction)
+ , _stackData(0)
+ , _stackPointer(0)
+ , _previousCoroutine(0)
+ , _status(NotStarted)
+{
+ // establish starting coroutine context if necessary
+ currentCoroutine();
+
+ _stackData = malloc(stackSize);
+ initializeStack(_stackData, stackSize, &entryPoint, &_stackPointer);
+}
+
+Coroutine::Coroutine()
+ : _startFunction(0)
+ , _stackData(0)
+ , _stackPointer(0)
+ , _previousCoroutine(0)
+ , _status(Running)
+{
+}
+
+Coroutine::~Coroutine()
+{
+ if (_stackData)
+ free(_stackData);
+}
+
+static QThreadStorage<Coroutine *> qt_currentCoroutine;
+
+Coroutine *Coroutine::currentCoroutine()
+{
+ Coroutine *current = qt_currentCoroutine.localData();
+ if (current)
+ return current;
+
+ // establish a context for the starting coroutine
+ current = new Coroutine;
+ qt_currentCoroutine.setLocalData(current);
+ return current;
+}
+
+void Coroutine::entryPoint()
+{
+ qt_currentCoroutine.localData()->_startFunction();
+ yieldHelper(Terminated);
+ Q_ASSERT(0); // unreachable
+}
+
+// returns whether it can be continued again
+bool Coroutine::cont()
+{
+ Q_ASSERT(_status == NotStarted || _status == Stopped);
+ Q_ASSERT(!_previousCoroutine);
+
+ _status = Running;
+
+ _previousCoroutine = qt_currentCoroutine.localData();
+ qt_currentCoroutine.setLocalData(this);
+ switchStack(_stackPointer, &_previousCoroutine->_stackPointer);
+ return _status != Terminated;
+}
+
+void Coroutine::yield()
+{
+ yieldHelper(Stopped);
+}
+
+void Coroutine::yieldHelper(Status stopStatus)
+{
+ Coroutine *stoppingCoroutine = qt_currentCoroutine.localData();
+ Q_ASSERT(stoppingCoroutine);
+ Q_ASSERT(stoppingCoroutine->_status == Running);
+ stoppingCoroutine->_status = stopStatus;
+
+ Coroutine *continuingCoroutine = stoppingCoroutine->_previousCoroutine;
+ Q_ASSERT(continuingCoroutine);
+
+ stoppingCoroutine->_previousCoroutine = 0;
+ qt_currentCoroutine.setLocalData(continuingCoroutine);
+ switchStack(continuingCoroutine, &stoppingCoroutine->_stackPointer);
+}
diff --git a/src/fiber.h b/src/coroutine.h
index b7bbcb1..ca47e77 100644
--- a/src/fiber.h
+++ b/src/coroutine.h
@@ -1,7 +1,7 @@
-#ifndef INCLUDE_FIBER_H
-#define INCLUDE_FIBER_H
+#ifndef INCLUDE_COROUTINE_H
+#define INCLUDE_COROUTINE_H
-class Fiber
+class Coroutine
{
public:
typedef void(*StartFunction)();
@@ -15,8 +15,8 @@ public:
};
public:
- explicit Fiber(StartFunction startFunction, int stackSize = 32768);
- ~Fiber();
+ explicit Coroutine(StartFunction startFunction, int stackSize = 32768);
+ ~Coroutine();
bool cont();
static void yield();
@@ -24,11 +24,11 @@ public:
Status status()
{ return _status; }
- static Fiber *currentFiber();
+ static Coroutine *currentCoroutine();
private:
- // for the original fiber
- Fiber();
+ // for the original coroutine
+ Coroutine();
static void yieldHelper(Status stopStatus);
static void entryPoint();
@@ -36,8 +36,8 @@ private:
StartFunction _startFunction;
void *_stackData;
void *_stackPointer;
- Fiber *_previousFiber;
+ Coroutine *_previousCoroutine;
Status _status;
};
-#endif // INCLUDE_FIBER_H
+#endif // INCLUDE_COROUTINE_H
diff --git a/src/fiber.cpp b/src/fiber.cpp
deleted file mode 100644
index 1c484e1..0000000
--- a/src/fiber.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include <stdlib.h>
-#include <QtCore/QtGlobal>
-#include <QtCore/QThreadStorage>
-
-#include "fiber.h"
-
-/*!
- \class Fiber
- \brief The Fiber class provides cooperatively scheduled stacks of execution.
-
- Fibers, also known as coroutines, allow managing multiple stacks in the same
- thread.
-
- \omit ### outdated \endomit
- To create a fiber, subclass Fiber and override the run() method. To run it,
- call cont(). This will execute the code in run() until it calls Fiber::yield().
- At that point, the call to cont() returns. Subsequent calls to cont() will
- continue execution of the fiber just after the yield().
-
- Example:
- void myFiber()
- {
- qDebug() << "1";
- Fiber::yield();
- qDebug() << "2";
- }
-
- MyFiber fib(&myFiber);
- qDebug() << "0.5";
- fib.cont(); // prints 1
- qDebug() << "1.5";
- fib.cont(); // prints 2
-*/
-
-#ifdef Q_OS_MAC
-extern "C" void switchStackInternal(void* to, void** from);
-void initializeStack(void *data, int size, void (*entry)(), void **stackPointer);
-void switchStack(void* to, void** from) { switchStackInternal(to, from); }
-#else
-extern "C" void _switchStackInternal(void* to, void** from);
-void initializeStack(void *data, int size, void (*entry)(), void **stackPointer);
-void switchStack(void* to, void** from) { _switchStackInternal(to, from); }
-#endif
-
-Fiber::Fiber(StartFunction startFunction, int stackSize)
- : _startFunction(startFunction)
- , _stackData(0)
- , _stackPointer(0)
- , _previousFiber(0)
- , _status(NotStarted)
-{
- // establish starting fiber context if necessary
- currentFiber();
-
- _stackData = malloc(stackSize);
- initializeStack(_stackData, stackSize, &entryPoint, &_stackPointer);
-}
-
-Fiber::Fiber()
- : _startFunction(0)
- , _stackData(0)
- , _stackPointer(0)
- , _previousFiber(0)
- , _status(Running)
-{
-}
-
-Fiber::~Fiber()
-{
- if (_stackData)
- free(_stackData);
-}
-
-static QThreadStorage<Fiber *> qt_currentFiber;
-
-Fiber *Fiber::currentFiber()
-{
- Fiber *current = qt_currentFiber.localData();
- if (current)
- return current;
-
- // establish a context for the starting fiber
- current = new Fiber;
- qt_currentFiber.setLocalData(current);
- return current;
-}
-
-void Fiber::entryPoint()
-{
- qt_currentFiber.localData()->_startFunction();
- yieldHelper(Terminated);
- Q_ASSERT(0); // unreachable
-}
-
-// returns whether it can be continued again
-bool Fiber::cont()
-{
- Q_ASSERT(_status == NotStarted || _status == Stopped);
- Q_ASSERT(!_previousFiber);
-
- _status = Running;
-
- _previousFiber = qt_currentFiber.localData();
- qt_currentFiber.setLocalData(this);
- switchStack(_stackPointer, &_previousFiber->_stackPointer);
- return _status != Terminated;
-}
-
-void Fiber::yield()
-{
- yieldHelper(Stopped);
-}
-
-void Fiber::yieldHelper(Status stopStatus)
-{
- Fiber *stoppingFiber = qt_currentFiber.localData();
- Q_ASSERT(stoppingFiber);
- Q_ASSERT(stoppingFiber->_status == Running);
- stoppingFiber->_status = stopStatus;
-
- Fiber *continuingFiber = stoppingFiber->_previousFiber;
- Q_ASSERT(continuingFiber);
-
- stoppingFiber->_previousFiber = 0;
- qt_currentFiber.setLocalData(continuingFiber);
- switchStack(continuingFiber, &stoppingFiber->_stackPointer);
-}
diff --git a/src/src.pro b/src/src.pro
index b2b9f6d..6fe0bd2 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,8 +1,8 @@
TEMPLATE = lib
-TARGET = fibers
+TARGET = coroutine
-HEADERS += fiber.h
-SOURCES += fiber.cpp
+HEADERS += coroutine.h
+SOURCES += coroutine.cpp
INCLUDEPATH += .
DEPENDPATH += .