-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Implement fibers for win32 #7995
Implement fibers for win32 #7995
Conversation
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.
I have been thinking a bit about the shadow space and added a comment with a suggestion of a small change that I think we need to make.
@ysbaddaden in #6955 (comment) (answered here in the new PR):
Sure, we can do that. I don't know yet what the proper We need to consider: Once we get proper multithreading, I suppose
Sounds good.
I'd like to include
I really don't know. Haven't looked into that yet. And I'd rather like to get fibers working right away because that's the limiting factor for porting other features as well. |
I pushed some updates but didn't move any files yet. I'm waiting for feedback on this before pushing things around. |
@straight-shoota |
6fd09a0
to
1e2cbdb
Compare
I've moved |
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.
It looks perfect now!
Renaming Thread
as Crystal::Thread
makes sense, but it may introduce annoying conflicts with other branches, and add some noise when using threads and mutexes, so I'll let @bcardiff decide whether we keep Thread
for the time being, or just move to Crystal::Thread
.
Yes, exactly. It kind of makes sense to have The PR changes everything to |
e9695d6
to
59a3f8d
Compare
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.
A few minor things, but in general this looks awesome!
@@ -0,0 +1,32 @@ | |||
module Crystal::EventLoop |
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.
It would be more consistent to rename these Crystal::System::EventLoop
, although it does make the diff even more noisy.
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.
I figured the Crystal::System
namespace is only really useful when there are both a system-specific type and a general type in Crystal
. Otherwise it only adds clutter.
There is however the possibility of name clashes with the compiler which also uses the Crystal
namespace. But that's a general issue unless we put everything in Crystal::System
.
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.
I put everything which has a platform-specific implementation - and is using the new Crystal::System
structure for it in Crystal::System
.
I'm fine with not renaming, but I personally would have done it, since the files are in src/crystal/system
.
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.
I see it that way that the things in Crystal::System
are not used anywhere directly except as an implementation detail of their specific counterpart in the public API. EventLoop
, Thread
etc. however are general APIs for Crystal's runtime. They only have system-specific implementations, but they're directly used in the runtime. Crystal::EventLoop
for example is referenced 10 times in the stdlib (without specs), Crystal::Thread
17 times.
f0d0eeb
to
0e4c26b
Compare
0e4c26b
to
fa90d53
Compare
Rebased and squashed. |
and CI failed |
It fails to build crystal itself (ECR.embed for the init command). |
@ysbaddaden To reproduce the error directly: $ bin/crystal run src/ecr/process.cr -- spec/std/data/test_template2.ecr
Unhandled exception: BUG: Crystal::Thread.current returned NULL (Exception)
from src/raise.cr:191:1 in 'raise'
from src/raise.cr:229:3 in 'raise'
from src/crystal/system/unix/pthread.cr:64:3 in 'current'
from src/crystal/scheduler.cr:17:5 in 'enqueue'
from src/concurrent.cr:63:3 in 'spawn'
from src/kernel.cr:540:1 in '__crystal_main'
from src/crystal/main.cr:97:5 in 'main_user_code'
from src/crystal/main.cr:86:7 in 'main'
from src/crystal/main.cr:106:3 in 'main'
from __libc_start_main
from _start
from ??? Out of a hunch, I re-inserted |
cf0a5e9
to
7804d9a
Compare
Another conflict? |
0708f2c
to
adcc631
Compare
Co-authored-by: cfsamson <cf@samson.no>
adcc631
to
fa7705f
Compare
would love another review |
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 great! I don't think this needs a thorough review (though I kind of did that, except for the asm part) because we still don't fully support Windows. Let's fill the missing pieces first. Once we can bootstrap the compiler on Windows we can tweak the little details.
popq %rbx | ||
popq %rdi // pop 1st argument (for initial resume) | ||
popq %gs:0x08 | ||
popq %gs:0x10 |
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.
The order it popped is different from the order it stored in makecontext
. Is it correct?
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.
I believe it's a documentation error of setting rbx in makecontext (or we push/pop rbx when we don't need to?)
We only pop up till rcx and the return address is left on the stack, I believe.
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.
@ysbaddaden Well, I meant these popq %gs:0x08
and popq %gs:0x10
two instructions , not about rbx
and rcx
. Sorry for including too large region.
In makecontext
, they store in the following order.
# The following two values are stored in the Thread Information Block (NT_TIB)
# and are used by Windows to track the current stack limits
stack_ptr[-2] = @stack_bottom # %gs:0x08: Stack Bottom
stack_ptr[-3] = @stack # %gs:0x10: Stack Limit
Shouldn't the pop order be this?
popq %gs:0x10
popq %gs:0x08
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.
I think you're right. GS:[0x08]
is the "high address", and GS:[0x10]
is the "low address" and if I'm not mistaken @stack_bottom
is the high address, and @stack
is the low address so they're put on the initial stack in the wrong order (or we need to change both push and pop orders in asm
).
I would just change the initial setup to:
stack_ptr[-2] = @stack # %gs:0x10: Stack Limit
stack_ptr[-3] = @stack_bottom # %gs:0x08: Stack Bottom
@ysbaddaden might be right that we don't need to push/pop %rcx
on every switch. I don't have the setup here to confirm that, but it might be a few cycles wasted there.
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 yes. They're inverted in makecontext. I totally missed that.
This makes sure Fiber compiles on win32. Fixes a merge order issue with crystal-lang#8225 and crystal-lang#7995.
This PR continues the efforts to bring concurrency features to windows (see #5430).
There are some refactorings to the the existing Fiber, Thread and EventLoop classes to extract the platform-specific implementation focused on POSIX and libevent.
Then it adds implementations of these classes for windows.
Thread
andEventLoop
are only stubbed so far.The core functionality is the context swap on win32.
concurrent_spec
passes and channels work in general, but the channel spec seems to hang.Supersedes #6955