aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohannst <johannes.stoelp@gmail.com>2020-10-05 17:57:26 +0200
committerjohannst <johannes.stoelp@gmail.com>2020-10-05 17:57:26 +0200
commit40335c667870e72deb739b81ffbf8d23902ebe71 (patch)
treef98587f320ec85f3d912430454e51e1acf99c04f
parente710fae8b8a1c34109644e5991f293b58e7eaa16 (diff)
downloadmatcha-threads-40335c667870e72deb739b81ffbf8d23902ebe71.tar.gz
matcha-threads-40335c667870e72deb739b81ffbf8d23902ebe71.zip
add support for function objects
-rw-r--r--example/demo1.cc19
-rw-r--r--lib/thread.cc6
-rw-r--r--lib/thread.h23
3 files changed, 46 insertions, 2 deletions
diff --git a/example/demo1.cc b/example/demo1.cc
index 1c910cd..b83c434 100644
--- a/example/demo1.cc
+++ b/example/demo1.cc
@@ -10,15 +10,21 @@ struct TestThread : public nMatcha::Thread {
TestThread(const char* name) : Thread(), mName(name) {}
virtual void threadFn() override {
- printf("[%s] starting up TestThread -> yield()\n", mName);
+ printf("[TestThread(%s)] start -> yield\n", mName);
yield();
- printf("[%s] yield() -> finishing TestThreads\n", mName);
+ printf("[TestThread(%s)] yield -> done\n", mName);
}
private:
const char* mName;
};
+void freeThreadFn(nMatcha::Yielder& y) {
+ puts("[freeThreadFn] start -> yield");
+ y.yield();
+ puts("[freeThreadFn] yield -> done");
+}
+
int main() {
puts("[main] start main thread");
@@ -26,6 +32,15 @@ int main() {
e.spawn(std::make_unique<TestThread>("Thread1"));
e.spawn(std::make_unique<TestThread>("Thread2"));
e.spawn(std::make_unique<TestThread>("Thread3"));
+
+ e.spawn(nMatcha::FnThread::make([](nMatcha::Yielder& y) {
+ puts("[Lambda Thread] start -> yield");
+ y.yield();
+ puts("[Lambda Thread] yield -> done");
+ }));
+
+ e.spawn(nMatcha::FnThread::make(freeThreadFn));
+
e.run();
puts("[main] finish main thread");
diff --git a/lib/thread.cc b/lib/thread.cc
index 31161ab..e6777c0 100644
--- a/lib/thread.cc
+++ b/lib/thread.cc
@@ -56,4 +56,10 @@ namespace nMatcha {
assert(mExecutor);
::yield(mExecutor->getStackPtr(), &mStackPtr);
}
+
+ std::unique_ptr<Thread> FnThread::make(UserFn f) { return std::make_unique<FnThread>(CreatorToken{}, f); }
+
+ void FnThread::threadFn() { mUserFn(*this); }
+
+ void FnThread::yield() { Thread::yield(); }
} // namespace nMatcha
diff --git a/lib/thread.h b/lib/thread.h
index d983734..3304892 100644
--- a/lib/thread.h
+++ b/lib/thread.h
@@ -2,6 +2,9 @@
#pragma once
+#include <functional>
+#include <memory>
+
namespace nMatcha {
struct Executor;
@@ -26,4 +29,24 @@ namespace nMatcha {
friend struct Executor;
const Executor* mExecutor;
};
+
+ struct Yielder {
+ virtual void yield() = 0;
+ };
+
+ struct FnThread : public Thread, public Yielder {
+ using UserFn = std::function<void(Yielder&)>;
+ static std::unique_ptr<Thread> make(UserFn f);
+
+ private:
+ virtual void threadFn() override;
+ virtual void yield() override;
+
+ UserFn mUserFn;
+
+ enum class CreatorToken {};
+
+ public:
+ FnThread(CreatorToken, UserFn f) : mUserFn(f) {}
+ };
} // namespace nMatcha