-
Notifications
You must be signed in to change notification settings - Fork 131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
port fiber changes from codal for PXT GC support #424
base: master
Are you sure you want to change the base?
Conversation
This is port of relevant codal changes in support of GC in the PXT runtime. Also, limit the number of fibers in pool to 3.
Also port from codal-core in support of PXT GC. Also, fix compiler optimization bug in calloc().
@mmoskal Can you please merge this? Also if possible create the right tags in the repos so we can point to it. |
Sure @finneyj. Sorry, I thought review was completed. (Green tick only means review requested 😞 ). |
queue = queue->next; | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine, but just checking that sum is intentionally not initialized to zero in this function? (I'm guess this is intentional from the variable names).
Can we get a doc comment block on this function?
// so it may in fact have the user_data set if in FOB context | ||
if (dest) | ||
*dest++ = idleFiber; | ||
sum++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this increment be inside the conditional? Looks like maybe it should?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the idea is that you call this twice, once with dest==NULL to count, then you allocate, and then call it again to get the data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, ok.
__disable_irq(); | ||
get_fibers_from(&dest, &sum, runQueue); | ||
get_fibers_from(&dest, &sum, sleepQueue); | ||
get_fibers_from(&dest, &sum, waitQueue); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks ok, but don't forget we introduced a mutex semaphore as part of js-event-semantics... Each mutex has its own wait queue associated with it, so you could perhaps miss extracting those fiber context with this function? Would that cause a problem for your application of this?
} | ||
} | ||
return f; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great - I've been wanting to factor this out into a function for a while... Thanks @mmoskal!
if (f != currentFiber) { | ||
dequeue_fiber(f); | ||
queue_fiber(f, &runQueue); | ||
schedule(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm.... I'm not sure this is entirely safe for this particular funciton. fiber_wake_on_event() is used to place the current fiber on a wait queue without entering the scheduler (such that race conditions can be avoided). i.e.
fiber_wake_on_event(..)
// do something that will cause that event to happen at some later point
schedule();
or am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh wait, the schedule() is there already on master; I don't quite understand why, but I think it's fine to align with codal-core
@@ -475,7 +523,7 @@ int invoke(void (*entry_fn)(void)) | |||
if (!fiber_scheduler_running()) | |||
return MICROBIT_NOT_SUPPORTED; | |||
|
|||
if (currentFiber->flags & MICROBIT_FIBER_FLAG_FOB) | |||
if (currentFiber->flags & (MICROBIT_FIBER_FLAG_FOB | MICROBIT_FIBER_FLAG_PARENT | MICROBIT_FIBER_FLAG_CHILD) || HAS_THREAD_USER_DATA) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mmoskal Can you please describe the conditions when HAS_THREAD_USER_DATA is set? Will this affect all MakeCode application fibers / event handlers? Wouldn't this affect RAM efficiency and context switch time somewhat?
I also wonder if a global CONFIG option to disable FOB might be simpler if that's the case? Just thinking of future maintenance here. Would be good to get your thoughts.
// limit the number of fibers in the pool | ||
int numFree = 0; | ||
for (Fiber *p = fiberPool; p; p = p->next) { | ||
if (!p->next && numFree > 3) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, but can we bring this constant out as a CONFIG option please?
@@ -754,6 +828,8 @@ void verify_stack_size(Fiber *f) | |||
|
|||
// Recalculate where the top of the stack is and we're done. | |||
f->stack_top = f->stack_bottom + bufferSize; | |||
|
|||
currentFiber = prevCurrFiber; | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this just for the case where the code may be pre-empted by an interrupt that scans the fiber list? if so, it's a short piece of code, can we protect with a more traditional disable/enable IRQ?
// and remove the memset | ||
((uint32_t*)mem)[0] = 1; | ||
memset(mem, 0, num*size); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cor - good spot.
Thanks for all the work on this @mmoskal. Generally all looks positive. Happy to merge pending questions I've posted as line comments - so could you take a look at those? |
- Add new CONFIG option to enable per-fiber meta data (default: disabled) - Add (void *) pointer to Fiber struct when CONFIG option enabled - Add Yotta CONFIG glue - Refactor fork-on-block handling into a unified function - Align validation semantics of both flavours of invoke() function
CC @abchatra