Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Haskell
Wiki community
Recent changes
Random page
HaskellWiki
Search
Search
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Lightweight concurrency
(section)
Page
Discussion
English
Read
Edit
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit
View history
General
What links here
Related changes
Special pages
Page information
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
=== Safe foreign calls === A safe foreign calls does not impede the execution of other Haskell threads on the same scheduler, if the foreign call blocks, unlike unsafe foreign calls. A safe foreign call is typically more expensive than its unsafe counterpart since it ''potentially'' involves switching between Haskell threads. At the very least, a safe foreign call involves releasing and re-acquiring capability. ==== Anatomy of a safe foreign call ==== Every capability, among other things, has a list of tasks (returning_tasks) that have completed their safe foreign call. The following are the steps involved in invoking a safe foreign call: * Before the foreign call, release the current capability to another worker task. * Perform the foreign call. * Add the current task to returning_tasks list. * Reacquire the capability. * Resume execution of Haskell thread. The first action performed by the worker task that acquired the capability is to check if returning_tasks is not empty. If so, the worker yields the capability to the first task in the returning_task list (fast path). Otherwise, the worker proceeds to run the next task from the run queue (slow path). Thus, in the fast path, the haskell thread never switches. ==== Problem ==== In the LWC implementation, the worker does not have the reference to the scheduler to pick the next task from. And for the same reason, when the task returns from the foreign call, it needs to know what to do with the Haskell thread, whether to switch to it (fast path) or add it to the scheduler data structure, to which it does not have a reference to. Even if the RTS had a reference to the scheduler data structure, it must be implemented in such a way that it is operable by both C and Haskell code. ==== Proposal ==== We might build on top of [[Lightweight_concurrency#Up-call_handlers|up-call handlers]]. * Before the foreign call, release the current capability to a worker, along with its switchToNext closure. * Perform the foreign call. * Add the current task to returning_tasks list. * Reacquire the capability. * If I am on the fast path (i.e, worker did not get the capability), resume execution of Haskell thread. * Otherwise (slow path), execute unblockThread upcall to enque the Haskell thread to the scheduler. At the worker: * Try to acquire the capability. * If the returning_tasks list is not empty, yield capability to the task from the head of the list (fast path). * Otherwise (slow path), execute the switchToNext closure, which will switch control to the next Haskell thread.
Summary:
Please note that all contributions to HaskellWiki are considered to be released under simple permissive license (see
HaskellWiki:Copyrights
for details). If you don't want your writing to be edited mercilessly and redistributed at will, then don't submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!
Cancel
Editing help
(opens in new window)
Toggle limited content width