Skip to content
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

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conversation

mmoskal
Copy link
Contributor

@mmoskal mmoskal commented Feb 22, 2019

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 mmoskal changed the title port codal fiber changes from codal for PXT GC support port fiber changes from codal for PXT GC support Feb 22, 2019
@abchatra
Copy link

@mmoskal Can you please merge this? Also if possible create the right tags in the repos so we can point to it.

@finneyj
Copy link
Contributor

finneyj commented Feb 27, 2019

@mmoskal @abchatra

Would you mind holding off on merging until I've had chance to review the changes to the scheduler fully? Some changes in this PR are pretty deep, and I feel another pair of eyes on it can only help. I'll try to find time in the next 24hrs...

@abchatra
Copy link

Sure @finneyj. Sorry, I thought review was completed. (Green tick only means review requested 😞 ).

queue = queue->next;
}
}

Copy link
Contributor

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++;
Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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);
Copy link
Contributor

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?

https://github.com/lancaster-university/microbit-dal/blob/js-event-semantics/source/core/MicroBitFiber.cpp#L944

}
}
return f;
}
Copy link
Contributor

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();
Copy link
Contributor

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?

Copy link
Contributor Author

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)
Copy link
Contributor

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) {
Copy link
Contributor

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;
}
Copy link
Contributor

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);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cor - good spot.

@finneyj
Copy link
Contributor

finneyj commented Mar 1, 2019

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?

finneyj added a commit that referenced this pull request May 7, 2019
  - 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants