AW: BUG #17448: In Windows 10, version 1703 and later, huge_pages doesn't work. - Mailing list pgsql-hackers

From Wilm Hoyer
Subject AW: BUG #17448: In Windows 10, version 1703 and later, huge_pages doesn't work.
Date
Msg-id 6389b5a88e114bee85593af2853c08cd@dental-vision.de
Whole thread Raw
In response to Re: BUG #17448: In Windows 10, version 1703 and later, huge_pages doesn't work.  (Julien Rouhaud <rjuju123@gmail.com>)
List pgsql-hackers
On Wed, Apr 27, 2022 at 03:04:23PM +0000, Wilm Hoyer wrote:
>>
>> 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.

> Thanks for sharing.

You are welcome.

> Having to compile another tool just for that seems like a very high price to pay, especially since we don't have any
C#code in the tree.  I'm not even sure that compiling this wouldn't need additional  requirements and/or if it would
workon our oldest supported Windows versions. 

With "translate it into C" I meant "tread it as pseudo code, for a solution in plain C" (e.g. substitude
Environment.OSVersionwith IsWindowsVersionOrGreater or GetVersion ) 

On Wed, Apr 27, 2022 at 05:13:12PM +0900, Michael Paquier wrote:
> On Tue, Apr 26, 2022 at 12:54:35PM +0800, Julien Rouhaud wrote:
> > so I'm still on the opinion that we should unconditionally use the
> > FILE_MAP_LARGE_PAGES flag if it's defined and call it a day.
>
> Are we sure that this is not going to cause failures in environments
> where the flag is not supported?

I'm not that familiar with the Microsoft OS or C (that's why I haven't migrated the c# code to C in the first place) to
havea clear answer to that question. 

If there is any risk and you want to avoid it, I can share a search result when I faced the same issue for our
application.I declined this solution in favor of the previously shared one. 
It's from NUnit (and needs migration to C as well - but since it just involves the Registry this should be pretty
forward).
Just in case the Framework is not known: NUnit is the most popular .Net port of the Unit Testing Framework JUnit. There
exitsa C port too (CUnit) Maybe in there you can find an OS Version check too. 

// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt
[...]
namespace NUnit.Framework.Internal
{
    [SecuritySafeCritical]
    public class OSPlatform
    {
[...]
        /// <summary>
        /// Gets the actual OS Version, not the incorrect value that might be
        /// returned for Win 8.1 and Win 10
        /// </summary>
        /// <remarks>
        /// If an application is not manifested as Windows 8.1 or Windows 10,
        /// the version returned from Environment.OSVersion will not be 6.3 and 10.0
        /// respectively, but will be 6.2 and 6.3. The correct value can be found in
        /// the registry.
        /// </remarks>
        /// <param name="version">The original version</param>
        /// <returns>The correct OS version</returns>
        private static Version GetWindows81PlusVersion(Version version)
        {
            try
            {
                using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion"))
                {
                    if (key != null)
                    {
                        var buildStr = key.GetValue("CurrentBuildNumber") as string;
                        int.TryParse(buildStr, out var build);

                        // These two keys are in Windows 10 only and are DWORDS
                        var major = key.GetValue("CurrentMajorVersionNumber") as int?;
                        var minor = key.GetValue("CurrentMinorVersionNumber") as int?;
                        if (major.HasValue && minor.HasValue)
                        {
                            return new Version(major.Value, minor.Value, build);
                        }

                        // If we get here, we are not Windows 10, so we are Windows 8
                        // or 8.1. 8.1 might report itself as 6.2, but will have 6.3
                        // in the registry. We can't do this earlier because for backwards
                        // compatibility, Windows 10 also has 6.3 for this key.
                        var currentVersion = key.GetValue("CurrentVersion") as string;
                        if(currentVersion == "6.3")
                        {
                            return new Version(6, 3, build);
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
            return version;
        }
[...]
   }
}

Finally, my reasoning to use the executable solution in favor of the NUnit one:
I found no guarantee from Microsoft regarding the keys and values in the registry - hence a change with an update or in
anewer Windows is not likely, but still possible. That's no problem for a heavily used and supported framework like
NUnit- they are likely to adopt within days of a new Windows release. I on the other hand wanted a solution with small
tono support. That's why I decided to implement a solution that's as in line as possible with the official Microsoft
advicefor targeting newer OS Versions. 

Best regards
Wilm.



pgsql-hackers by date:

Previous
From: "kuroda.hayato@fujitsu.com"
Date:
Subject: RE: Multi-Master Logical Replication
Next
From: "houzj.fnst@fujitsu.com"
Date:
Subject: RE: Logical replication timeout problem