AW: BUG #17448: In Windows 10, version 1703 and later, huge_pages doesn't work.

From: Wilm Hoyer <W(dot)Hoyer(at)dental-vision(dot)de>
To: Michael Paquier <michael(at)paquier(dot)xyz>, Julien Rouhaud <rjuju123(at)gmail(dot)com>
Cc: "pgsql-hackers(at)lists(dot)postgresql(dot)org" <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: AW: BUG #17448: In Windows 10, version 1703 and later, huge_pages doesn't work.
Date: 2022-04-27 15:04:23
Message-ID: 9178d683d05d420a887369ffb38d8fbd@dental-vision.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs pgsql-hackers


On Tue, Apr 26, 2022 at 12:54:35PM +0800, Julien Rouhaud wrote:
>> I searched a bit and apparently some people are using this function
>> directly opening some dll, which seems wrong.

> I was wondering about this whole business, and the manifest approach is a *horrible* design for an API where the goal is to know if your run-time environment is greater than a given threshold.

Agreed for the use case at hand, where you want to use one core API Function or another depending on the OS Version.

One Blog from Microsoft, I remember, told that one reason for the change were the increase of false installation error messages "Install Error - Your system does not meet the minimum supported operating system and service pack level."
where the software in question was written for Windows XP and the user tried to install it on, say, Windows 8.
That is just a Developer-Pilot error, where the Developers forgot to anticipate future OS Versions and instead of checking for Version at least, where checking for Version equality of all at design time known Windows Version.
Since you can develop only against OS APIs known at design time, and Microsoft claims to be pretty good at maintaining backward compatible facades for their APIs, there is some reason in that decision.
(To only see the Versions and APIs you told the OS with the manifest, you knew about at compile time).
The core Problem at hand is, that ms broke the promise of backward compatibility, since the function in question is working differently, depending on windows version, although with the above reasoning we should get the exact same behavior on windows 10 as on windows 8.1 (as PostgreSql, per default, only claims to know about Windows 8.1 features).

That said, I can understand the design decision. Personally, I still don't like it a bit, since developers should be allowed to make some stupid mistakes.

>>> Another Idea on windows machines would be to use the commandline to
>>> execute ver in a separate Process and store the result in a file.
>>
>> That also seems hackish, I don't think that we want to rely on
>> something like that.

>Hmm. That depends on the dependency set, I guess. We do that on Linux at some extent to for large pages in sysv_shmem.c. Perhaps this could work for Win10 if this avoids the extra loopholes with the >manifests.

I used the following hack to get the "real" Major and Minor Version of Windows - it's in C# (.Net) and needs to be adjusted (you can compile as x64 and use a long-long as return value ) to return the Service Number too and translated it into C.
I share it anyways, as it might help - please be kind, as it really is a little hack.

Situation:
Main Application can't or is not willing to add a manifest file into its resources.

Solution:
Start a small executable (which has a manifest file compiled into its resources), let it read the OS Version and code the Version into its return Code.

CInt32 is basically an integer redefinition, where one can access the lower and higher Int16 separately.

The Main Programm eventually calls this (locate the executable, adjust the Process startup to be minimal, call the executable as separate process and interpret the return value as Version):
private static Version ReadModernOsVersionInternal()
{
String codeBase = Assembly.GetExecutingAssembly().CodeBase;
Uri uri = new Uri(codeBase);

String localPath = uri.LocalPath;
String pathDirectory = Path.GetDirectoryName(localPath);

if (pathDirectory != null)
{
String fullCombinePath = Path.Combine(pathDirectory, "Cf.Utilities.ReadModernOSVersion");

ProcessStartInfo processInfo = new ProcessStartInfo
{
FileName = fullCombinePath,
CreateNoWindow = true,
UseShellExecute = false
};

Process process = new Process
{
StartInfo = processInfo
};

process.Start();

if (process.WaitForExit(TimeSpan.FromSeconds(1).Milliseconds))
{
CInt32 versionInteger = process.ExitCode;
return new Version(versionInteger.HighValue, versionInteger.LowValue);
}
}

return new Version();
}

The small Version Check executable:

static Int32 Main(String[] args)
{
return OsVersionErmittler.ErmittleOsVersion();
}

and

static class OsVersionErmittler
{
/// <summary>
/// Ermittelt die OsVersion und übergibt diese als High und LowWord.
/// </summary>
/// <returns></returns>
public static CInt32 ErmittleOsVersion()
{
OperatingSystem version = Environment.OSVersion;
if (version.Platform == PlatformID.Win32NT && version.Version >= new Version(6, 3))
{
String versionString = version.VersionString;
return new CInt32((Int16) version.Version.Major, (Int16) version.Version.Minor);
}
return 0;
}
}

The shortened manifest of the small executable:
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Eine Liste der Windows-Versionen, unter denen diese Anwendung getestet
und für die sie entwickelt wurde. Wenn Sie die Auskommentierung der entsprechenden Elemente aufheben,
wird von Windows automatisch die kompatibelste Umgebung ausgewählt. -->

<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->

<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->

<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->

<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />

</application>
</compatibility>

</assembly>

I hope I'm not intrusive, otherwise, feel free to ignore this mail,
Wilm.

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Loïc Revest 2022-04-27 15:19:30 Re: lag() default value ignored for some window partition depending on table records count?
Previous Message David G. Johnston 2022-04-27 15:03:20 Re: psql emit WARNING if built with option --with-extra-version and the option only contains numbers

Browse pgsql-hackers by date

  From Date Subject
Next Message Junwang Zhao 2022-04-27 15:11:26 remove redundant check of item pointer
Previous Message Justin Pryzby 2022-04-27 14:53:58 cirrus: run macos with COPY_PARSE_PLAN_TREES etc