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

different thread implementation #1

Open
M1cha opened this issue Jul 15, 2017 · 5 comments
Open

different thread implementation #1

M1cha opened this issue Jul 15, 2017 · 5 comments

Comments

@M1cha
Copy link

M1cha commented Jul 15, 2017

I just wanted to let you know about my take on UEFI threads in case you're interested :)
https://github.com/efidroid/uefi_edk2packages_EFIDroidLKLPkg/tree/master/UEFIThreads
I'm basically using TPL_CALLBACKs to schedule threads so there's no need for locking before calling UEFI-API functions.

Also I'd like to know how your CChangeContext callback works because it looks like you're blocking inside a TPL_NOTIFY function there which is not allowed as per UEFI spec.

@o-marshmallow
Copy link
Collaborator

Hello @M1cha ,
I am glad you are interested in my project and I am also very interested in yours.

I used TLP_NOTIFY to let all threads having at most 4ms (defined in Green.c) of CPU time.

When CChangeContext is executed, it looks for the next runnable thread in our array of threads. A thread is runnable is it has been preempted by the timer (and so it didn't Yield because it was waiting for a Mutex). When this new thread to run is found, a backup of the current context is made and the new thread's context is set/restored. To do so, I wrote an assembly routine, SwitchContext, which does this easily.

Moreover, the first thing the function of a thread does is restoring its priority level by calling:

gBS->RestoreTPL(TPL_APPLICATION);

So, the only way to block inside a higher priority function (CChangeContext) is to have a deadlock in the program using the threads, so it's a user-related problem

@M1cha
Copy link
Author

M1cha commented Jul 17, 2017

The problem is that UEFI-Events aren't some high level interrupts, they called from within the Event-Dispatcher loop.

So if I'm not completely mistaken, what happens in your code is the following:

  • You're running normal code inside TPL_APPLICATION
  • the TPL_NOTIFY event gets called, you're in TPL_NOTIFY now
  • you "switch" into the context of a new thread which effectively blocks the execution of the event dispatcher which called you
  • your ThreadWrapper then sets the TPL to TPL_APPLICATION even though your code wasn't the one who raised to TPL_NOTIFY, The whole system is now at the risk of running code which should not run at this time.
  • now, since you lowered the TPL, the event-dispatcher can be called again, even though effectively, you're still inside the TPL_NOTIFY-callback.
  • now you return back to the original context which means you're finally returning to the event-dispatcher. But you've confused the whole system now since you're blocking inside a second event-dispatcher-callback at the sime time

So, from the viewpoint of UEFI you're doing the follwing:

  • receiving a TPL_NOTIFY callback
  • lowering the TPL which you're not allowed to
  • still inside the callback, the exact same TPL_NOTIFY event is being raised again
  • now you finally return from the "real" callback with the event dispatcher being in a weird state
  • also, you returned from the dispatcher with TPL_APPLICATION instead of TPL_NOTIFY

I hope, that you understand my explanation. Feel free to correct me if I'm wrong in any point.

@o-marshmallow
Copy link
Collaborator

I understand your idea, I would better use TPL_CALLBACK and not TPL_NOTIFY for the event.
However, I still have to lower the TPL when executing the wrapper as we still want the CChangeContext function to be executed.

@o-marshmallow
Copy link
Collaborator

Commit ba2ae3d

@M1cha
Copy link
Author

M1cha commented Jul 17, 2017

The thing is that you're not allowed to set a tpl to something lower. Also you have to leave a function with the same tpl with which it was entered.

In short it means that you can't do real external scheduling in UEFI.
You have to rely on the threads calling either UEFI apis(which would cause event dispatching) or threading apis(where you could manually reschedule).

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

No branches or pull requests

2 participants