Hi Daniel and Piotr,
I am having a trouble with _Cnd_timedwait and I am trying to understand a few things.
The problem I'm running into is that the application I am dealing with passes a timestamp that is 30 days into the future. This overflows in _Xtime_diff_to_millis(2) and the result we get is somewhere in the area of -1708070296. Now _Cnd_timedwait casts this to an ULONGLONG, so I would expect the multiplication to come up with the right result, but no, the function passes a timeout of 170807029600000 to NtWaitForKeyedEvent, which is interpreted as an absolute value in the past and instantly times out.
To get the right result I have to assign the result of _Xtime_diff_to_millis to an ULONG and cast this back to a 64 bit signed value - otherwise the multiplication happens in unsigned 32 bit and results in a positive number that will fit in a a signed 64 bit integer with ease.
So my two questions are:
1) Why go through _Xtime_diff_to_millis at all? If I understand the server code right NtWaitForKeyedEvent should do the right thing if we pass timeout.QuadPart = sec * 1000 * 1000 * 100 + nsec / 10. And indeed in my quick testing this works for the app and passes the tests. Are there timezone issues?
2) What C integer legalese prevents the current code from working? All the signed/unsigned conversion references I found talk about assignments, not casts in calculations.
Cheers, Stefan
Hi Stefan,
On 12/04/17 17:33, Stefan Dösinger wrote:
- Why go through _Xtime_diff_to_millis at all? If I understand the
server code right NtWaitForKeyedEvent should do the right thing if we pass timeout.QuadPart = sec * 1000 * 1000 * 100 + nsec / 10. And indeed in my quick testing this works for the app and passes the tests. Are there timezone issues?
The timeout is specified in 100's of nanoseconds.
I wonder if native works well if time difference doesn't fit into ULONG, did you check that? If it doesn't - the simplest fix would be to do something like this: timeout.QuadPart = (ULONGLONG)((ULONG)_Xtime_diff_to_millis(xt)) * -10000; Otherwise you can change the code to not use _Xtime_diff_to_millis.
Thanks, Piotr
Am 2017-12-04 um 18:43 schrieb Piotr Caban:
I wonder if native works well if time difference doesn't fit into ULONG, did you check that?
With native the app works fine. I haven't tested if the app passes the same parameters with native. Extending the existing tests in msvcp120/tests also seems to work.
(_Cnd_timedwait just sits there and waits, instead of returning with timeout immediately. I obviously haven't waited 30 days to see if it times out then)
If it doesn't - the simplest fix would be to do something like this> timeout.QuadPart = (ULONGLONG)((ULONG)_Xtime_diff_to_millis(xt)) * -10000;
This works, but I could swear I tried that myself and it didn't work then - hence my wondering of casts vs assignments.
Am 2017-12-04 um 19:08 schrieb Stefan Dösinger:
Am 2017-12-04 um 18:43 schrieb Piotr Caban:
I wonder if native works well if time difference doesn't fit into ULONG, did you check that?
With native the app works fine.
Fwiw, the user-visible bug is that the wait returns with status 2 instantly, and the application restarts it. This causes high CPU use in wineserver and the app process.
On 12/04/17 19:08, Stefan Dösinger wrote:
Am 2017-12-04 um 18:43 schrieb Piotr Caban:
I wonder if native works well if time difference doesn't fit into ULONG, did you check that?
With native the app works fine. I haven't tested if the app passes the same parameters with native. Extending the existing tests in msvcp120/tests also seems to work.
(_Cnd_timedwait just sits there and waits, instead of returning with timeout immediately. I obviously haven't waited 30 days to see if it times out then)
If it doesn't - the simplest fix would be to do something like this> timeout.QuadPart = (ULONGLONG)((ULONG)_Xtime_diff_to_millis(xt)) * -10000;
This works, but I could swear I tried that myself and it didn't work then - hence my wondering of casts vs assignments.
I've done some testing and native behaves badly when waiting for ~49 days (in this case the _Xtime_diff_to_millis overflows ULONG). So it looks that if we want to be bug-to-bug compatible we should use _Xtime_diff_to_millis and cast it to ULONG.
I'm attaching a test I've used. The test waits shortly with native while it's asked to wait for ~49 days.
Thanks, Piotr
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=34591
Your paranoid android.
=== wvistau64 (32 bit msvcp120) === msvcp120.c:1923: Test failed: got 110
=== w2008s64 (32 bit msvcp120) === msvcp120.c:1923: Test failed: got 110
=== wvistau64 (64 bit msvcp120) === msvcp120.c:1923: Test failed: got 110
=== w2008s64 (64 bit msvcp120) === msvcp120.c:1923: Test failed: got 110