diff options
-rw-r--r-- | example/demo1.cc | 19 | ||||
-rw-r--r-- | lib/thread.cc | 6 | ||||
-rw-r--r-- | lib/thread.h | 23 |
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 |