Closed LinqLover closed 4 years ago
PS: Also, after keeping an empty Squeak image open for ~15 minutes, it breaks itself inside Delay class>>handlerTimerEvent
with a primitive failure from #primSignal:atUTCMicroseconds:
. However, this is most likely only a consequence of the above error ...
Hi Christoph,
first it's not true that Time is broken on Windows:
Smalltalk os platformName 'Win32' Smalltalk getSystemAttribute: 1007 'CoInterpreter VMMaker.oscog-eem.2850 uuid: 4d7fc8a4-2c7d-4bad-8aeb-5f8c5766e12a Oct 21 2020' DateAndTime now 2020-10-22T23:06:29.983933-07:00 Time utcMicrosecondClock 3780886299961528
It is true that unless you have 8.1 or later and have GetSystemTimePreciseAsFileTime in kernel32 then Time will not work. Here:
$ git diff 712cfe6c3e29667b56e668d7641daced18efb666 platforms/win32/vm/sqWin32Heartbeat.c | more
diff --git a/platforms/win32/vm/sqWin32Heartbeat.c b/platforms/win32/vm/sqWin32H
eartbeat.c
old mode 100644
new mode 100755
index 85d27674a..70c430889
--- a/platforms/win32/vm/sqWin32Heartbeat.c
+++ b/platforms/win32/vm/sqWin32Heartbeat.c
@@ -14,6 +14,7 @@
#include <mmsystem.h>
#include "sq.h"
+#undef EXPORT
#include "sqAssert.h"
#include "sqMemoryFence.h"
@@ -76,19 +77,41 @@ sqLong ioHighResClock(void) {
return value;
}
+#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
+
+/* Compute the current VM time basis, the number of microseconds from 1901.
+ *
+ * As of Windows 8 there is a FILETIME wall clock interface which is high
+ * precision and so does not have to be combined with the millisecond clock.
+ */
+# define currentUTCMicroseconds(a,b,c) currentUTCMicrosecondsImplementation()
+static inline unsigned __int64
+currentUTCMicrosecondsImplementation(void)
+{
+ union { // got to love little-endian architectures...
+ FILETIME utcNowFiletime;
+ unsigned __int64 utcNow;
+ } un;
+
+ // cannot fail...
+ GetSystemTimePreciseAsFileTime(&un.utcNowFiletime);
+ return un.utcNow / TocksPerMicrosecond - MicrosecondsFrom1601To1901;
+}
+#else // _WIN32_WINNT >= _WIN32_WINNT_WIN8
+
Now, that said, I am happy to work with anyone to write this code such that it works on older versions. But the use of GetSystemTimePreciseAsFileTime is a huge improvement over the previous code. I apologise for breaking your setup, but I'm curious to understand why it did, given that GetSystemTimePreciseAsFileTime has been around since 8.0.
BTW, I've been running this VM on Windows for hours using Terf without any issues with delays.
HTH
Hi Eliot,
I don't think this is a backward compatibility issue. As mentioned, I'm using Windows 2004 (Build 19041.572), which is definitely a younger Windows version than 8.1 (which was released in 2013 compared to 2020). Microsofts and its versioning chaos :-)
And on my machine, time is definitively broken, or at least returning wrong values:
Smalltalk os platformName. "'Win32'"
Smalltalk getSystemAttribute: 1007. "'CoInterpreter VMMaker.oscog-eem.2850 uuid: 4d7fc8a4-2c7d-4bad-8aeb-5f8c5766e12a Oct 21 2020'"
DateAndTime now. "586455-01-18T10:21:42.099068+02:00"
Time utcMicrosecondClock. "1194520452"
GetSystemTimePreciseAsFileTime
per se works on my machine when I try to run this code example:
> HighResolutionDateTime.UtcNow
[2020-10-23 12:20:19]
Should it be relevant that I am using the 64-bit edition of Windows? However, I can reproduce the issue using both the 32-bit and the 64-bit version of OSVM.
That's weird. What's the definition for Time class>>utcMicrosecondClock? It should be primitive 240. Also, if you write a C program to print out the result of GetSystemTimePreciseAsFileTime, and to convert it to the Smalltalk epoch via WindowsTime / 10 + (microseconds from 1601 to 1901), what does that look like?
What's the definition for Time class>>utcMicrosecondClock? It should be primitive 240.
It is. I'm using a fresh trunk image.
Also, if you write a C program to print out the result of GetSystemTimePreciseAsFileTime, and to convert it to the Smalltalk epoch via WindowsTime / 10 + (microseconds from 1601 to 1901), what does that look like?
Did I mention that my C is very rudimentary? 😅 This is what I wrote:
#include <stdio.h>
#include <windows.h>
int main(void) {
FILETIME ft;
ULARGE_INTEGER ui;
GetSystemTimePreciseAsFileTime(&ft);
ui.LowPart=ft.dwLowDateTime;
ui.HighPart=ft.dwHighDateTime;
printf("%i", ui.QuadPart / 10 - 9467020800000000);
}
And it outputs:
❯ .\timeTest.exe
718860433
Does this help? :-)
Note that WINVER is defined differently in Makefile.tools and Makefile.msvc.tools... https://github.com/OpenSmalltalk/opensmalltalk-vm/search?q=WINVER
That explains why cygwin/mingw compilation took a different path.
Ah, thanks a lot, Nicolas! I confirm that the issues do no longer occur with the 202010232046 build. :-)
Today I tried to update my Squeak VM for Win10, 2004, and found out that the hearbeat primitives (primitiveUtcWithOffset/utcMicrosecondClock) are broken on Windows:
The issue occurs both on 32-bit and 64-bit platforms, using a fresh Squeak Trunk image. I tried to narrow down the origin of this issue, but because bintray builds were defect or incomplete between 202010191814 and 202010200140, I can only tell that the issue was born somewhere in the interval (202009300634, 202010210155].
Without ever having read the relevant implementation, I would assume that the issue was introduced in
sqWin32Heartbeat.c
via fae0d31cd52341977d37d150d8d2c9272f9864bf. @eliotmiranda Would this plausible? Can anyone else reproduce the issue?