Commit 44518827 authored by Martin Karsten's avatar Martin Karsten
Browse files

- change fibre-specific destructors to run on fibre stack

parent d981074a
...@@ -133,8 +133,8 @@ Fibre* Cluster::registerWorker(_friend<EventScope>) { ...@@ -133,8 +133,8 @@ Fibre* Cluster::registerWorker(_friend<EventScope>) {
Worker* worker = new Worker(*this); Worker* worker = new Worker(*this);
Fibre* mainFibre = new Fibre(*worker, Fibre::DefaultAffinity, _friend<Cluster>(), 0); // caller continues on pthread stack Fibre* mainFibre = new Fibre(*worker, Fibre::DefaultAffinity, _friend<Cluster>(), 0); // caller continues on pthread stack
setupWorker(mainFibre, worker); setupWorker(mainFibre, worker);
Fibre* idleFibre = new Fibre(*worker, Fibre::FixedAffinity, _friend<Cluster>()); // idle fibre on new stack Fibre* idleFibre = new Fibre(*worker, Fibre::FixedAffinity, _friend<Cluster>()); // idle fibre on new stack
idleFibre->setup((ptr_t)fibreHelper, worker); // set up idle fibre for execution idleFibre->setup((ptr_t)fibreHelper, worker, nullptr, idleFibre, _friend<Cluster>()); // set up idle fibre for execution
worker->setIdleLoop(idleFibre); worker->setIdleLoop(idleFibre);
return mainFibre; return mainFibre;
} }
...@@ -143,9 +143,9 @@ Cluster::Worker& Cluster::addWorker(funcvoid1_t initFunc, ptr_t initArg) { ...@@ -143,9 +143,9 @@ Cluster::Worker& Cluster::addWorker(funcvoid1_t initFunc, ptr_t initArg) {
Worker* worker = new Worker(*this); Worker* worker = new Worker(*this);
Fibre* initFibre = new Fibre(*worker, Fibre::FixedAffinity, _friend<Cluster>()); Fibre* initFibre = new Fibre(*worker, Fibre::FixedAffinity, _friend<Cluster>());
if (initFunc) { // run init routine in dedicated fibre, so it can block if (initFunc) { // run init routine in dedicated fibre, so it can block
initFibre->setup((ptr_t)initFunc, initArg); initFibre->setup((ptr_t)initFunc, initArg, nullptr, initFibre, _friend<Cluster>());
} else { } else {
initFibre->setup((ptr_t)initDummy, nullptr); initFibre->setup((ptr_t)initDummy, nullptr, nullptr, initFibre, _friend<Cluster>());
} }
Argpack args = { this, worker, initFibre }; Argpack args = { this, worker, initFibre };
pthread_t tid; pthread_t tid;
......
...@@ -169,8 +169,12 @@ private: ...@@ -169,8 +169,12 @@ private:
#endif #endif
} }
Fibre* runInternal(ptr_t func, ptr_t p1, ptr_t p2, ptr_t p3) { void start(ptr_t func, ptr_t p1, ptr_t p2, ptr_t p3) { // hide base class start()
Fred::start(func, p1, p2, p3); Fred::start(func, p1, p2, p3);
}
Fibre* runInternal(ptr_t func, ptr_t p1, ptr_t p2, Fibre* This) {
start(func, p1, p2, This);
return this; return this;
} }
...@@ -201,32 +205,36 @@ public: ...@@ -201,32 +205,36 @@ public:
/** Exit fibre (with join, if not detached). */ /** Exit fibre (with join, if not detached). */
static void exit(ptr_t p = nullptr) __noreturn; static void exit(ptr_t p = nullptr) __noreturn;
// callback after Fred's main routine has finished
void finalize(ptr_t e) {
result = e;
clearSpecific();
}
// callback from Fred via Runtime after final context switch // callback from Fred via Runtime after final context switch
void destroy(_friend<Fred>) { void destroy(_friend<Fred>) {
clearSpecific();
clearDebug(); clearDebug();
stackFree(); stackFree();
done.post(); done.post();
} }
void setup(ptr_t func, ptr_t p1, ptr_t p2, ptr_t p3, _friend<Cluster>) { // hide base class setup()
Fred::setup(func, p1, p2, p3);
}
/** Start fibre. */ /** Start fibre. */
Fibre* run(void (*func)()) { Fibre* run(void (*func)()) {
return runInternal((ptr_t)func, nullptr, nullptr, nullptr); return runInternal((ptr_t)func, nullptr, nullptr, this);
} }
/** Start fibre. */ /** Start fibre. */
template<typename T1> template<typename T1>
Fibre* run(void (*func)(T1*), T1* p1) { Fibre* run(void (*func)(T1*), T1* p1) {
return runInternal((ptr_t)func, (ptr_t)p1, nullptr, nullptr); return runInternal((ptr_t)func, (ptr_t)p1, nullptr, this);
}
/** Start fibre. */
template<typename T1, typename T2>
Fibre* run(void (*func)(T1*, T2*), T1* p1, T2* p2) {
return runInternal((ptr_t)func, (ptr_t)p1, (ptr_t)p2, nullptr);
} }
/** Start fibre with pthread-type run function. */ /** Start fibre with pthread-type run function. */
template<typename T1> template<typename T1>
Fibre* run(void* (*func)(T1*), T1* p1) { Fibre* run(void* (*func)(T1*), T1* p1) {
return runInternal((ptr_t)func, (ptr_t)p1, nullptr, &result); return runInternal((ptr_t)func, (ptr_t)p1, nullptr, this);
} }
/** Sleep. */ /** Sleep. */
......
...@@ -21,16 +21,14 @@ ...@@ -21,16 +21,14 @@
inline void RuntimeStartFred(funcvoid3_t func, ptr_t arg1, ptr_t arg2, ptr_t arg3) { inline void RuntimeStartFred(funcvoid3_t func, ptr_t arg1, ptr_t arg2, ptr_t arg3) {
Context::CurrProcessor().countFredStarted(); Context::CurrProcessor().countFredStarted();
ptr_t p;
try { try {
if (arg3) { funcptr3_t f3 = (funcptr3_t)(ptr_t)(func);
funcptr3_t f3 = (funcptr3_t)(ptr_t)(func); p = (Fibre::ExitException*)f3(arg1, arg2, arg3);
*(ptr_t*)arg3 = f3(arg1, arg2, arg3);
} else {
func(arg1, arg2, arg3);
}
} catch (Fibre::ExitException* e) { } catch (Fibre::ExitException* e) {
if (arg3) *(ptr_t*)arg3 = e; p = e;
} }
reinterpret_cast<Fibre*>(arg3)->finalize(p);
} }
inline void RuntimePreFredSwitch(Fred& currFred, Fred& nextFred, _friend<Fred> fs) { inline void RuntimePreFredSwitch(Fred& currFred, Fred& nextFred, _friend<Fred> fs) {
......
...@@ -119,7 +119,7 @@ public: ...@@ -119,7 +119,7 @@ public:
stackDirect(stackPointer, func, nullptr, nullptr, nullptr); stackDirect(stackPointer, func, nullptr, nullptr, nullptr);
} }
// set up new fred and resume for concurrent execution // set up fred stack without immediate start
void setup(ptr_t func, ptr_t p1 = nullptr, ptr_t p2 = nullptr, ptr_t p3 = nullptr) { void setup(ptr_t func, ptr_t p1 = nullptr, ptr_t p2 = nullptr, ptr_t p3 = nullptr) {
stackPointer = stackInit(stackPointer, func, p1, p2, p3); stackPointer = stackInit(stackPointer, func, p1, p2, p3);
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment