-
Notifications
You must be signed in to change notification settings - Fork 18k
runtime: time is not correctly updated under wine #18537
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
Comments
@dvyukov Dmitry please comment on this issue |
@alexbrainman |
This should work
$ x86_64-w64-mingw32-gcc /tmp/wine.cpp -o /tmp/wine |
But I believe that detecting that interrupt time is not updated rather than application runs under wine is a better idea - one problem, one local fix. Who knows, maybe wine will eventually port this memory feature, although so far there are only workarounds which use dedicated thread which updates this page once in 15.6 ms to mimic only system time. |
Sure, we can change runtime to allow for Wine. Searching for wine_get_version functoin in ntdll.dll on startup sounds good to me. I am not clear about your alternative proposal - how are you going to detect that "interrupt time is not updated"? Also, once we know that we are running on Wine, how should runtime.unixnano and runtime.nanotime be implemented? Alternatively fill free to send your own proposal (https://golang.org/doc/contribute.html). Thank you. Alex |
Detecting that time is not updated is rather simple - just run this interrupt time checking loop in |
I do not understand your proposal. Do you suggest we check if runtime._KSYSTEM_TIME at runtime._INTERRUPT_TIME address changes in a loop? How many time should we run the loop before giving up? This should be fast - we don't want every Go program pay for this too much. Alex |
Interrupt time precision is about 10 updates per microsecond, so calling something like code below at every start will not ever slow down any go program, getting that windows starting code already calls things like It could be even better than what I wrote if using a systime()-like loop directly instead of calling I would not mind calling this with the loop duration specified via some environment variable or anything else, which will be zero by default and only wine users would specify it. Although imo it looks a bit ugly
|
Fair enough. We could, probably, do that. Or search for wine_get_version in ntdll.dll. You didn't say how runtime.unixnano and runtime.nanotime should be implemented for Wine. Alex |
I'm still not convinced.
Say, if ReactOS requires special cases, should we add them? Why wine is
different?
Wine is supposed to emulate Windows faithfully. Just because we generally
don't add special case for qemu-user, I don't think we should add special
case for wine too.
It's definitely possible to implement the system page under wine.
|
The way runtime.unixnano and runtime.nanotime are implemented is not documented by Microsoft. I think it is fare we implement them in a documented way. Personally I am happy to support whatever OS users use. Alex |
To implement nanotime in a correct fashion I would recommend using Wine is a bit different, because it is not really a windows, it tries its best to emulate it, but it quite frequently fails. It is up to the wine user to convince wine core team to fix it, and frankly saying I seriously doubt wine can ever fix this particular bug for at least 1ms resolution. This bug exists in wine bugzilla for at least 2 years, the only solution I saw uses dedicated thread to update the mapping, it emulates system time with 15.6 ms resulution, which is not enough for go (although its ok for me and most of the users I believe). This is really an ugly and expensive solution for most of the users out there (for everyone who doesn't need monotonic clocks). Quite contrary syscall behaviour is a standard, if QPC breaks there will be no hpet timers, and I'm pretty sure wine needs it. It has quite a serious performance overhead compared to reading 3 times from mapped memory, so it is not default. As of ReactOS - it doesn't really matter. It looks really feasible for me that some reactos user will eventually come here and say, that in version X.Y.Z of branch N something had stopped working. If golang can fix it easily without overhead, what's the problem? If you are an insane purist who fights for the absolute code and design perfection, you probably would not go in IT anyway. And fixing some issue for some users with a trivial check is a good way to go. Otherwise you can tell that time subsystem (and I question whether things like GC work) virtually doesn't work on one of the most popular crossover platform in the world. And after all this memory reading feature IS NOT OFFICIALLY DOCUMENTED. It exists in winapi headers quite for a while and starting from w2k there are some helpers which work with it (like is-debugger-present and similar), but yet again, if you fight for the purification, you should argue to change code to official syscalls. |
Sounds like a plan. Would you like to send a change? Here https://golang.org/doc/contribute.html is how to contribute. Maybe wait for a week to make sure no objections here. @minux might come around too. Alex |
The hard part of wine is implementing the undocumented side effects. If
wine just implements documented interfaces, I doubt it can run any major
Windows applications at all.
|
Changing our implementation to use documented interfaces (provided the
performance doesn't suffer too much) SGTM. But detecting wine and then act
differently is not ok from me.
|
I've cooked up a patch, which kind of works but raises an error when calling If there anything with signals which messes up between Here is a patch, its quite straightforward Here is a tracedump:
Application is rather trivial: https://play.golang.org/p/0ZUCNggw7e |
Patch for online review:
|
@bioothod, we can't accept or review patches on the bug tracker. They have to be in Gerrit. |
Again, wine specific code is not ok as the windows builder won't test them.
And I highly doubt we would add a wine builder (I'm pretty sure all.bat
won't pass on wine.)
|
This is not a request for inclusion, this is a demonstration of the idea @bradfitz There is no need to test it at build time since it doesn't work yet - it crashes probably because of signal mess, that's why I asked above what could be a reason for |
Some won't look at your code for legal reason. For Gerrit access, you must have completed one of the contributor license agreements. Not everything sent via Gerrit is reviewed or submitted.
I am, probably, wrong, but I think you cannot call stdcall1 from systime. stdcall1 function does a lot, and expects runtime to be in a consistent state. But systime (or nanotime) is called from everywhere. We already have osyield and usleep functions that are in a similar situation, perhaps you can do the same in systime. Alex |
Wow, assembler in the high-level language to call a function and save the stack! Ok, I will dust off my wizard hat, recover the ancient manuscripts and try to cook up a patch. |
I wonder how did it work previously, since just 2.5 years ago it was as simple as
is there any high-level document describing runtime changes which forced time code to go into hand crafted assembly? |
It happens to be much simpler than I thought, no need to switch stacks, problem is in division. Running By simpler I mean that I do not have to write asm code to invoke QPC syscalls, which for instance requires changing signature of Code works on i386 if I mark a bunch of division functions in |
For the reference, discussions about stack usage and why some functions had been changed to OS stack: |
@bioothod |
@dvyukov yeah, I've made the patch, added QPC test into So I post a patch here, please comment and merge, it works both for i386 and amd64 builds tested on wine, I will run it on real windows machine a bit later. Patch: Online:
|
@bioothod, sorry, for legal reasons we can't accept a patch here on the bug tracker. |
OMG, are you serious? You do allow proprietary binary crap in the executable and can not accept several lines diff which fixes real bug basically rendering system unusable in the most popular crossplatform environment on the world without shitty bureaucracy, which involves registering new google account, which virtually refuses to verify new user (probably because this phone number is already used in a completely irrelevant setup)? Guys, are you aware of the 21 century auth technologies? OAuth maybe, did you hear this word? Do you know about github? Maybe words 'signed-off-by' highlight something - those beardy guys in linux-kernel use it. Or maybe code of conduct, facebook requires to sign a special page to accept patches... What's wrong with you? You create a good language for its purpose, and you add so much crap around it. Someone, please copy this patch into review system or rewrite it the way you like, I've shown the basic idea, implementation fixes time bug in wine environment and works without overhead for common windows users. |
On Sun, Jan 15, 2017 at 6:28 PM, Evgeniy Polyakov ***@***.***> wrote:
You do allow proprietary binary crap in the executable and
Please elaborate on this. Where are the proprietary binary blobs in Go?
|
I do not work for Google, and have no special contacts there. Sorry. Alex |
@minux I talked about binaries distributed via vendoring feature |
@bioothod, I'm sorry you're upset, but we can't make legal exceptions just because you're upset. The bureaucracy has pros and cons. You've hit a con. The pros are that we have a very clean contribution history and legal story. Users of Go appreciate that. If you manage to create a Google account we can start a code review for you. Until then, we'll just have to wait. |
@alexbrainman I'm not insisting on fixing google account bugs of course, I'm just pointing that code review process is flawed at best imo, and I would describe it in more colourful details actually... I've shown the idea of how to fix it, I would gladly submit it for review and fix this bug, but I believe we have a show stopper so far, I will try to resolve it, but hardly see what can be done except finding another phone number. |
On Sun, Jan 15, 2017 at 7:16 PM, Evgeniy Polyakov ***@***.***> wrote:
@minux <https://github.com/minux> I talked about binaries distributed via
vendoring feature
The vendoring feature is about source codes.
Go does have support for binary only packages (//go:binary-only-package),
but we intentionally makes it impossible to distribute them using regular
"go get". And there is a little-known feature of *.syso files, but there is
no proprietary binary syso blobs in the Go repos.
|
@bradfitz flawed google account requirement has virtually zero correlation with go users who appreciate clean contribution. Your words imply that facebook or linux-kernel contribution history and legal story are not clean enough, are you sure that requiring flawed google account is strong enough for such words? |
@bioothod, I'm not going to debate our CLA requirements in this forum. If you're looking for an argument, look elsewhere. |
@minux I didn't tell about golang repos per se, but |
@bradfitz I'm curious, whether I need to have posts in google+ social network and how many, apparently this might be a requirement too like using google account. Apart from the size of google drive had to be used to review the patch, is it ok from technical point of view? I.e. does it break something, or highlight some issue with stalled time detection, or maybe incorrect syscall usage? |
Updated QPC fallback time implementation. On the real hardware 100 loop iterations are actually either too quick (which is unlikely), or windows updates those mappings on some other events which are not happening in go. Anyway, running a following loop on the real hardware ended up with unchanged times:
so I updated test to actually perform a sleep, I call If it is not, there is plan B. Embedded patch for review. If you are still afraid of letters and believe that commenting patch on github causes legal issues, headache and baldness, @noxiouz will push it into gerrit on my behalf
|
Again, please stop putting patches here. Nobody is allowed to review this code unless it comes via Gerrit. If I see any further patches or any code reviews in this thread I will unfortunately be forced to lock this thread. |
If laywers dictate how you accept patches, well, one day they will come after you. Run away from the project before they do. |
I think we want to do as little as possible on startup. What happened to "searching for wine_get_version function in ntdll.dll" idea? We already search ntdll.dll for other things, so you would need to add just a couple of lines.
I have been bold for years. And have no problems with headache. But I wouldn't want legal troubles for the Go Team. I think we all want them to be happy and write code and do code review and ... instead of wasting their time with legal matters. So if @noxiouz wants to send this change, that would be good. I would do it myself, but my TODO list is very long, and you would have to wait awhile. Alex |
Patch has been submitted into gerrit, please comment (preferably here) and merge |
Kudos to Anton Tiurin @noxiouz for this |
CL https://golang.org/cl/35710 mentions this issue. |
You should note that https://go-review.googlesource.com/#/c/35710/ will not progress (Brad set -2 there) until CLA is cleared. Alex |
After golang had changed its clocks to monotonic, windows port started to use slightly unofficial memory mapping hack to get current time: https://codereview.appspot.com/108700045/patch/120001/130001
Unfortunately wine (as of jan 2016 neither hack was committed) does not update that page, this ends up with
time.Sleep()
taking forever on wine (checked with GOOS=windows and go 1.7.4)It seems that hack to read mapped memory containing interrupt time works for all systems but wine, are there any plans to add a check into magic
systime()
call at https://github.com/golang/go/blob/master/src/runtime/os_windows.go#L594 to fallback to query performance counter syscall for example if mapped memory is not being updated?The text was updated successfully, but these errors were encountered: