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>) {
Worker* worker = new Worker(*this);
Fibre* mainFibre = new Fibre(*worker, Fibre::DefaultAffinity, _friend<Cluster>(), 0); // caller continues on pthread stack
setupWorker(mainFibre, worker);
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
Fibre* idleFibre = new Fibre(*worker, Fibre::FixedAffinity, _friend<Cluster>()); // idle fibre on new stack
idleFibre->setup((ptr_t)fibreHelper, worker, nullptr, idleFibre, _friend<Cluster>()); // set up idle fibre for execution
worker->setIdleLoop(idleFibre);
return mainFibre;
}
......@@ -143,9 +143,9 @@ Cluster::Worker& Cluster::addWorker(funcvoid1_t initFunc, ptr_t initArg) {
Worker* worker = new Worker(*this);
Fibre* initFibre = new Fibre(*worker, Fibre::FixedAffinity, _friend<Cluster>());
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 {
initFibre->setup((ptr_t)initDummy, nullptr);
initFibre->setup((ptr_t)initDummy, nullptr, nullptr, initFibre, _friend<Cluster>());
}
Argpack args = { this, worker, initFibre };
pthread_t tid;
......
......@@ -169,8 +169,12 @@ private:
#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);
}
Fibre* runInternal(ptr_t func, ptr_t p1, ptr_t p2, Fibre* This) {
start(func, p1, p2, This);
return this;
}
......@@ -201,32 +205,36 @@ public:
/** Exit fibre (with join, if not detached). */
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
void destroy(_friend<Fred>) {
clearSpecific();
clearDebug();
stackFree();
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. */
Fibre* run(void (*func)()) {
return runInternal((ptr_t)func, nullptr, nullptr, nullptr);
return runInternal((ptr_t)func, nullptr, nullptr, this);
}
/** Start fibre. */
template<typename T1>
Fibre* run(void (*func)(T1*), T1* p1) {
return runInternal((ptr_t)func, (ptr_t)p1, nullptr, nullptr);
}
/** 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);
return runInternal((ptr_t)func, (ptr_t)p1, nullptr, this);
}
/** Start fibre with pthread-type run function. */
template<typename T1>
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. */
......
......@@ -21,16 +21,14 @@
inline void RuntimeStartFred(funcvoid3_t func, ptr_t arg1, ptr_t arg2, ptr_t arg3) {
Context::CurrProcessor().countFredStarted();
ptr_t p;
try {
if (arg3) {
funcptr3_t f3 = (funcptr3_t)(ptr_t)(func);
*(ptr_t*)arg3 = f3(arg1, arg2, arg3);
} else {
func(arg1, arg2, arg3);
}
funcptr3_t f3 = (funcptr3_t)(ptr_t)(func);
p = (Fibre::ExitException*)f3(arg1, arg2, arg3);
} 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) {
......
......@@ -119,7 +119,7 @@ public:
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) {
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