Skip to content
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

[PATCH] introduce PL_w32_osver #14424

Closed
p5pRT opened this issue Jan 18, 2015 · 9 comments
Closed

[PATCH] introduce PL_w32_osver #14424

p5pRT opened this issue Jan 18, 2015 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 18, 2015

Migrated from rt.perl.org#123620 (status was 'open')

Searchable as RT123620$

@p5pRT
Copy link
Author

p5pRT commented Jan 18, 2015

From @bulk88

Created by @bulk88

This patch has POD problems I haven't been able to solve.

  ..\miniperl.exe -I..\lib ..\autodoc.pl ..
Unable to place PL_w32_osver!
Unable to place dW32OSVER!
Unable to place w32_osver!
Function 'w32_osver', documented in win32/win32.h, not listed in
embed.fnc at ..
\autodoc.pl line 370.
  ..\miniperl.exe -I..\lib ..\pod\perlmodlib.PL -q ..
  ..\perl.exe -f ..\pod\buildtoc -q

The flags in autodoc.pl are undocumented.

+
+/*
+=for apidoc AM|osver|PL_w32_osver
+
+This is a global that contains an Win32 C<OSVERSIONINFOEX> struct that

I picked AM for all 3 POD entries. Using embed.fnc language, A=public,
M=may change. So IDK what I am doing wrong.

This patch also needs opinions/coordination from jdb and to be
eventually split into a CPAN side for Win32​:: and core side, since it
currently patches /cpan. A decision on Windows 8.1 will also have to be
made, and if to switch to RtlGetVersion (see example
http​://code.google.com/p/dynamorio/issues/detail?id=1419 ) or do an
incrementing for loop with IsWindowsVersionOrGreater AKA
VerifyVersionInfo /
http​://msdn.microsoft.com/en-us/library/windows/desktop/ms725492%28v=vs.85%29.aspx
(I dont like the 2nd idea). To use RtlGetVersion, instead of the
traditional GetProcAddress algo, static dynamic linking to ntdll is a
choice, since the latest version of the WIP patch #12370 has ntdll static dll linking.

Perl Info

Flags:
              category=core
              severity=low

Site configuration information for perl 5.21.4:

Configured by Owner at Thu Sep 18 12:08:58 2014.

Summary of my perl5 (revision 5 version 21 subversion 4) configuration:
            Derived from: 7d2b2edb94ab56333b9049a3e26d15ea18445512
            Ancestor: 19be3be6968e2337bcdfe480693fff795ecd1304
            Platform:
              osname=MSWin32, osvers=5.1, archname=MSWin32-x86-multi-thread
              uname=''
              config_args='undef'
              hint=recommended, useposix=true, d_sigaction=undef
              useithreads=define, usemultiplicity=define
              use64bitint=undef, use64bitall=undef, uselongdouble=undef
              usemymalloc=n, bincompat5005=undef
            Compiler:
              cc='cl', ccflags ='-nologo -GF -W3 -O1 -MD -Zi -DNDEBUG
-DWIN32
-D_CONSOLE -DNO_STRICT  -DPERL_TEXTMODE_SCRIPTS
-DPERL_HASH_FUNC_ONE_AT_A_TIME -DPERL_IMPLICIT_CONTEXT
-DPERL_IMPLICIT_SYS -DUSE_PERLIO -D_USE_32BIT_TIME_T',
              optimize='-O1 -MD -Zi -DNDEBUG',
              cppflags='-DWIN32'
              ccversion='12.00.8168', gccversion='', gccosandvers=''
              intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
              d_longlong=undef, longlongsize=8, d_longdbl=define,
longdblsize=8,
longdblkind=0
              ivtype='long', ivsize=4, nvtype='double', nvsize=8,
Off_t='__int64',
lseeksize=8
              alignbytes=8, prototype=define
            Linker and Libraries:
              ld='link', ldflags ='-nologo -nodefaultlib -debug -opt:ref,icf
-libpath:"c:\perl521\lib\CORE"  -machine:x86'
              libpth=C:\PROGRA~1\MIAF9D~1\VC98\lib
              libs=oldnames.lib kernel32.lib user32.lib gdi32.lib
winspool.lib
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib
netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib  version.lib
odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
              perllibs=oldnames.lib kernel32.lib user32.lib gdi32.lib
winspool.lib  comdlg32.lib advapi32.lib shell32.lib ole32.lib
oleaut32.lib  netapi32.lib uuid.lib ws2_32.lib mpr.lib winmm.lib
version.lib odbc32.lib odbccp32.lib comctl32.lib msvcrt.lib
              libc=msvcrt.lib, so=dll, useshrplib=true, libperl=perl521.lib
              gnulibc_version=''
            Dynamic Linking:
              dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
              cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -debug
-opt:ref,icf  -libpath:"c:\perl521\lib\CORE"  -machine:x86'

Locally applied patches:
              uncommitted-changes
              a0fe7a7e75de29e59f1da0d6822dc06e5be658fe
              a261faffee83d0145642ab5d1d046c9f813bc497
              6506ab86ad1602a9ca720fcd30446dce1461d23d
              7d2b2edb94ab56333b9049a3e26d15ea18445512


@INC for perl 5.21.4:
              lib
              C:/perl521/srcnew/lib
              .


Environment for perl 5.21.4:
              HOME (unset)
              LANG (unset)
              LANGUAGE (unset)
              LD_LIBRARY_PATH (unset)
              LOGDIR (unset)
              PATH=
              PERL_BADLANG (unset)
              PERL_JSON_BACKEND=Cpanel::JSON::XS
              PERL_YAML_BACKEND=YAML
              SHELL (unset)















@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2015

From @tonycoz

On Sat Jan 17 23​:11​:42 2015, bulk88 wrote​:

This patch has POD problems I haven't been able to solve.

There is no patch.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2015

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2015

From @bulk88

On Mon Jan 26 19​:50​:09 2015, tonyc wrote​:

On Sat Jan 17 23​:11​:42 2015, bulk88 wrote​:

This patch has POD problems I haven't been able to solve.

There is no patch.

Tony

attached

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Jan 27, 2015

From @bulk88

0001-introduce-PL_w32_osver.patch
From cdef49c25f503790241b62e5e73ccfd280844eee Mon Sep 17 00:00:00 2001
From: Daniel Dragan <bulk88@hotmail.com>
Date: Sun, 18 Jan 2015 01:31:24 -0500
Subject: [PATCH] introduce PL_w32_osver

Calling GetVersionEx in an XS module is a common activity according to CPAN
grep. The only RW static global var in Win32:: is an OSVERSIONINFO struct.
Win32:: is often loaded by Win32 Perl users for various reasons. So to
decrease its load time, and remove all perl caused (non-CC caused) RW
static data from Win32::, export core's OSVERSIONINFO struct as a data
export. For XS modules in general, the DLL overhead of the perl core data
export and overhead of using GetVersionEx are the same. 2 ptr sized values
and 1 null terminated string (symbol name). So if a XS module stops
importing GetVersionEx and instead imports PL_w32_osver, the space usage
in the DLL is basically identical. If for that XS module, OSVERSIONINFO was
the only RW global data, then it is a win in memory. Obviously it is a win
in execution time to not call GetVersionEx and do pointer derefs instead.
The DLL loader will have the same work to do resolving GetVersionEx and
PL_w32_osver symbols, but GetVersionEx has to execute later but
PL_w32_osver doesn't. Since this data can never change between reboots,
it is process global and not interp global for ithreads/psuedofork
purposes. An unimplemented idea would be to prefill the OSVERSIONINFOEX
struct with the data from PC that the perl core was built on, and use
.data section symbol ordering (a "map" file) to stick PL_check, PL_ppaddr
and PL_w32_osver in 1 DLL/OS page and have Windows do interprocess COW
on that page. VC doesn't treat the imported data * in the IAT as const
and will reread the IAT entry of the DLL between function calls. To avoid
double indirection over and over (something like
"eax = *(U32*)(eip+__imp__PL_w32_osver);
if(*(U32*)(eax+dwMajorVersion) >= 6) {")
create dW32OSVER and w32_osver as C auto caches of PL_w32_osver.

It has not been decided what to do with Windows 8.1's freezing of the data
GetVersionEx reports. This API is designed to be possibly included in
ppport.h. See how Win32:: chooses to use its per module GetVersionEx or
the global one.
---
 cpan/Win32/Win32.xs         |   56 ++++++++++++++++++++++++++++++-------------
 cpan/Win32/t/GetOSVersion.t |    2 +-
 embedvar.h                  |    2 +
 perlapi.h                   |    2 +
 perlvars.h                  |   22 +++++++++++++++++
 win32/win32.c               |   24 ++++++++++--------
 win32/win32.h               |   43 +++++++++++++++++++++++++++++++++
 7 files changed, 122 insertions(+), 29 deletions(-)

diff --git a/cpan/Win32/Win32.xs b/cpan/Win32/Win32.xs
index a5d6c6a..8de7c65 100644
--- a/cpan/Win32/Win32.xs
+++ b/cpan/Win32/Win32.xs
@@ -109,6 +109,7 @@ typedef void (WINAPI *PFNGetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
 #   define CSIDL_FLAG_CREATE          0x8000
 #endif
 
+#if !((PERL_VERSION >= 5) && (PERL_VERSION >= 21) && (PERL_SUBVERSION >= 8))
 /* Use explicit struct definition because wSuiteMask and
  * wProductType are not defined in the VC++ 6.0 headers.
  * WORD type has been replaced by unsigned short because
@@ -127,25 +128,37 @@ struct {
     BYTE  wProductType;
     BYTE  wReserved;
 }   g_osver = {0, 0, 0, 0, 0, "", 0, 0, 0, 0, 0};
-BOOL g_osver_ex = TRUE;
+/* by the default being null bytes instead of sizeof(g_osver), this var doesn't
+   require on disk storage in the DLL */
+#  define dW32MOD_OSVER dNOOP
+#else
+/* this stops multiple reads of IAT entry for PL_w32_osver */
+#  define dW32MOD_OSVER dW32OSVER
+#  define g_osver w32_osver
+#endif
+
+#define OSVER_HAVE_EX (g_osver.dwOSVersionInfoSize == sizeof(g_osver))
 
 #define ONE_K_BUFSIZE	1024
 
 int
 IsWin95(void)
 {
+    dW32MOD_OSVER;
     return (g_osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
 }
 
 int
 IsWinNT(void)
 {
+    dW32MOD_OSVER;
     return (g_osver.dwPlatformId == VER_PLATFORM_WIN32_NT);
 }
 
 int
 IsWin2000(void)
 {
+    dW32MOD_OSVER;
     return (g_osver.dwMajorVersion > 4);
 }
 
@@ -1296,20 +1309,27 @@ XS(w32_GetOSVersion)
 {
     dXSARGS;
 
-    if (GIMME_V == G_SCALAR) {
-        XSRETURN_IV(g_osver.dwPlatformId);
-    }
-    XPUSHs(sv_2mortal(newSVpvn(g_osver.szCSDVersion, strlen(g_osver.szCSDVersion))));
-
-    XPUSHs(sv_2mortal(newSViv(g_osver.dwMajorVersion)));
-    XPUSHs(sv_2mortal(newSViv(g_osver.dwMinorVersion)));
-    XPUSHs(sv_2mortal(newSViv(g_osver.dwBuildNumber)));
-    XPUSHs(sv_2mortal(newSViv(g_osver.dwPlatformId)));
-    if (g_osver_ex) {
-        XPUSHs(sv_2mortal(newSViv(g_osver.wServicePackMajor)));
-        XPUSHs(sv_2mortal(newSViv(g_osver.wServicePackMinor)));
-        XPUSHs(sv_2mortal(newSViv(g_osver.wSuiteMask)));
-        XPUSHs(sv_2mortal(newSViv(g_osver.wProductType)));
+    XSprePUSH;
+    EXTEND(SP, 9);
+    {
+	const I32 gimme = GIMME_V;
+	dW32MOD_OSVER;
+	if (gimme == G_SCALAR) {
+	    PUSHs(sv_2mortal(newSViv(g_osver.dwPlatformId)));
+	}
+	else {
+	    PUSHs(sv_2mortal(newSVpvn(g_osver.szCSDVersion, strlen(g_osver.szCSDVersion))));
+	    PUSHs(sv_2mortal(newSViv(g_osver.dwMajorVersion)));
+	    PUSHs(sv_2mortal(newSViv(g_osver.dwMinorVersion)));
+	    PUSHs(sv_2mortal(newSViv(g_osver.dwBuildNumber)));
+	    PUSHs(sv_2mortal(newSViv(g_osver.dwPlatformId)));
+	    if (OSVER_HAVE_EX) {
+		PUSHs(sv_2mortal(newSViv(g_osver.wServicePackMajor)));
+		PUSHs(sv_2mortal(newSViv(g_osver.wServicePackMinor)));
+		PUSHs(sv_2mortal(newSViv(g_osver.wSuiteMask)));
+		PUSHs(sv_2mortal(newSViv(g_osver.wProductType)));
+	    }
+	}
     }
     PUTBACK;
 }
@@ -1451,6 +1471,7 @@ XS(w32_GetFullPathName)
     dXSARGS;
     char *fullname;
     char *ansi = NULL;
+    dW32MOD_OSVER;
 
 /* The code below relies on the fact that PerlDir_mapX() returns an
  * absolute path, which is only true under PERL_IMPLICIT_SYS when
@@ -1800,15 +1821,16 @@ PROTOTYPES: DISABLE
 BOOT:
 {
     char *file = __FILE__;
-
+#if !((PERL_VERSION >= 5) && (PERL_VERSION >= 21) && (PERL_SUBVERSION >= 8))
     if (g_osver.dwOSVersionInfoSize == 0) {
         g_osver.dwOSVersionInfoSize = sizeof(g_osver);
         if (!GetVersionExA((OSVERSIONINFOA*)&g_osver)) {
-            g_osver_ex = FALSE;
+/* OSVERSIONINFOEXA only works on NT SP6 or newer NT, no Dos Windows and no CE */
             g_osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
             GetVersionExA((OSVERSIONINFOA*)&g_osver);
         }
     }
+#endif
 
     newXS("Win32::LookupAccountName", w32_LookupAccountName, file);
     newXS("Win32::LookupAccountSID", w32_LookupAccountSID, file);
diff --git a/cpan/Win32/t/GetOSVersion.t b/cpan/Win32/t/GetOSVersion.t
index cb3f364..3e8d1e5 100644
--- a/cpan/Win32/t/GetOSVersion.t
+++ b/cpan/Win32/t/GetOSVersion.t
@@ -5,7 +5,7 @@ use Win32;
 plan tests => 1;
 
 my $scalar = Win32::GetOSVersion();
-my @array  = Win32::GetOSVersion();
+my @array  = Win32::GetOSVersion("bad arg1", "bad arg2");
 
 print "not " unless $scalar == $array[4];
 print "ok 1\n";
diff --git a/embedvar.h b/embedvar.h
index da3c331..cabf666 100644
--- a/embedvar.h
+++ b/embedvar.h
@@ -434,6 +434,8 @@
 #define PL_Guse_safe_putenv	(my_vars->Guse_safe_putenv)
 #define PL_veto_cleanup		(my_vars->Gveto_cleanup)
 #define PL_Gveto_cleanup	(my_vars->Gveto_cleanup)
+#define PL_w32_osver		(my_vars->Gw32_osver)
+#define PL_Gw32_osver		(my_vars->Gw32_osver)
 #define PL_watch_pvx		(my_vars->Gwatch_pvx)
 #define PL_Gwatch_pvx		(my_vars->Gwatch_pvx)
 
diff --git a/perlapi.h b/perlapi.h
index 910f789..5268c2c 100644
--- a/perlapi.h
+++ b/perlapi.h
@@ -169,6 +169,8 @@ END_EXTERN_C
 #define PL_use_safe_putenv	(*Perl_Guse_safe_putenv_ptr(NULL))
 #undef  PL_veto_cleanup
 #define PL_veto_cleanup		(*Perl_Gveto_cleanup_ptr(NULL))
+#undef  PL_w32_osver
+#define PL_w32_osver		(*Perl_Gw32_osver_ptr(NULL))
 #undef  PL_watch_pvx
 #define PL_watch_pvx		(*Perl_Gwatch_pvx_ptr(NULL))
 
diff --git a/perlvars.h b/perlvars.h
index 7bafa40..1d94c43 100644
--- a/perlvars.h
+++ b/perlvars.h
@@ -237,3 +237,25 @@ PERLVAR(G, malloc_mutex, perl_mutex)	/* Mutex for malloc */
 
 PERLVARI(G, hash_seed_set, bool, FALSE)	/* perl.c */
 PERLVARA(G, hash_seed, PERL_HASH_SEED_BYTES, unsigned char) /* perl.c and hv.h */
+
+/*
+=for apidoc AM|osver|PL_w32_osver
+
+This is a global that contains an Win32 C<OSVERSIONINFOEX> struct that contains
+the OS version.  Type C<osver> is identical to C<OSVERSIONINFOEX>.  This global
+is a struct, not a struct pointer, use C<.> not C<-&gt;>.  C<osver> exists
+because older Win32 compilers might not have C<OSVERSIONINFOEX> in their
+headers.  If C<PL_w32_osver.dwOSVersionInfoSize != sizeof(osver)>, then the
+later elements of C<OSVERSIONINFOEX> are uninitialized, and only the subset
+of C<OSVERSIONINFO> members are valid.  It has not been decided what version
+number this will contain for Windows 8.1 and up due to recent changes by
+Microsoft to the Windows API.  For efficiency, if you will use C<PL_w32_osver>
+more than once in a function, use L</dW32OSVER> and L</w32_osver> instead of
+multiple references to C<PL_w32_osver>.
+
+=cut
+*/
+
+#ifdef WIN32
+PERLVARI(G, w32_osver, osver, {sizeof(osver)})
+#endif
diff --git a/win32/win32.c b/win32/win32.c
index d4c98e4..55a09e2 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -188,8 +188,6 @@ Size_t	w32_ioinfo_size;/* avoid 0 extend op b4 mul, otherwise could be a U8 */
 #endif
 END_EXTERN_C
 
-static OSVERSIONINFO g_osver = {0, 0, 0, 0, 0, ""};
-
 #ifdef SET_INVALID_PARAMETER_HANDLER
 static BOOL silent_invalid_parameter_handler = FALSE;
 
@@ -523,7 +521,7 @@ Perl_my_pclose(pTHX_ PerlIO *fp)
 DllExport unsigned long
 win32_os_id(void)
 {
-    return (unsigned long)g_osver.dwPlatformId;
+    return (unsigned long)PL_w32_osver.dwPlatformId;
 }
 
 DllExport int
@@ -2049,7 +2047,7 @@ win32_uname(struct utsname *name)
     STRLEN nodemax = sizeof(name->nodename)-1;
 
     /* sysname */
-    switch (g_osver.dwPlatformId) {
+    switch (PL_w32_osver.dwPlatformId) {
     case VER_PLATFORM_WIN32_WINDOWS:
         strcpy(name->sysname, "Windows");
         break;
@@ -2066,15 +2064,15 @@ win32_uname(struct utsname *name)
 
     /* release */
     sprintf(name->release, "%d.%d",
-            g_osver.dwMajorVersion, g_osver.dwMinorVersion);
+            PL_w32_osver.dwMajorVersion, PL_w32_osver.dwMinorVersion);
 
     /* version */
     sprintf(name->version, "Build %d",
-            g_osver.dwPlatformId == VER_PLATFORM_WIN32_NT
-            ? g_osver.dwBuildNumber : (g_osver.dwBuildNumber & 0xffff));
-    if (g_osver.szCSDVersion[0]) {
+            PL_w32_osver.dwPlatformId == VER_PLATFORM_WIN32_NT
+            ? PL_w32_osver.dwBuildNumber : (PL_w32_osver.dwBuildNumber & 0xffff));
+    if (PL_w32_osver.szCSDVersion[0]) {
         char *buf = name->version + strlen(name->version);
-        sprintf(buf, " (%s)", g_osver.szCSDVersion);
+        sprintf(buf, " (%s)", PL_w32_osver.szCSDVersion);
     }
 
     /* nodename */
@@ -4469,8 +4467,12 @@ Perl_win32_init(int *argcp, char ***argvp)
      */
     //InitCommonControls();
 
-    g_osver.dwOSVersionInfoSize = sizeof(g_osver);
-    GetVersionEx(&g_osver);
+    if (PL_w32_osver.dwOSVersionInfoSize == 0) {
+/* no CE or DOS Windows, so no need to try again with the smaller
+  OSVERSIONINFOA struct */
+        PL_w32_osver.dwOSVersionInfoSize = sizeof(osver);
+        GetVersionExA((OSVERSIONINFOA*)&PL_w32_osver);
+    }
 
 #ifdef WIN32_DYN_IOINFO_SIZE
     {
diff --git a/win32/win32.h b/win32/win32.h
index f49a4b0..502649b 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -538,6 +538,49 @@ void win32_wait_for_children(pTHX);
 #  define PERL_WAIT_FOR_CHILDREN win32_wait_for_children(aTHX)
 #endif
 
+/* Use explicit struct definition because wSuiteMask and
+ * wProductType are not defined in the VC++ 6.0 headers.
+ * WORD type has been replaced by unsigned short because
+ * WORD is already used by Perl itself.
+ */
+typedef struct {
+    DWORD dwOSVersionInfoSize;
+    DWORD dwMajorVersion;
+    DWORD dwMinorVersion;
+    DWORD dwBuildNumber;
+    DWORD dwPlatformId;
+    CHAR  szCSDVersion[128];
+    unsigned short wServicePackMajor;
+    unsigned short wServicePackMinor;
+    unsigned short wSuiteMask;
+    BYTE  wProductType;
+    BYTE  wReserved;
+} osver;
+
+/*
+=for apidoc AM|void|dW32OSVER
+
+Declares a local copy of L</PL_w32_osver>.  This is more efficienct than multiple
+references to L</PL_w32_osver>.  The local copy should be accessed through
+L</w32_osver>.
+
+=cut
+*/
+#define dW32OSVER const osver * const w32_osver_p = &PL_w32_osver
+
+/*
+=for apidoc AM||w32_osver
+
+A macro to access a local copy of L</PL_w32_osver> declared with L</dW32OSVER>.
+This is more efficient than multiple references to L</PL_w32_osver>. This macro
+is a struct, not a struct pointer, use C<.> not C<-&gt;>.
+
+=cut
+*/
+
+#define w32_osver (*w32_osver_p)
+
+
 #ifdef PERL_CORE
 /* C doesn't like repeat struct definitions */
 #if defined(__MINGW32__) && (__MINGW32_MAJOR_VERSION>=3)
-- 
1.7.9.msysgit.0

@p5pRT
Copy link
Author

p5pRT commented Feb 3, 2015

From @tonycoz

On Mon Jan 26 21​:30​:48 2015, bulk88 wrote​:

On Mon Jan 26 19​:50​:09 2015, tonyc wrote​:

On Sat Jan 17 23​:11​:42 2015, bulk88 wrote​:

This patch has POD problems I haven't been able to solve.

There is no patch.

Tony

attached

Thanks.

I'd like to see comments from jdb on this.

I can see this (very slightly) slowing down calls into Win32​::* functions that use the version structure, since rather than using the module global g_osver, they need to look up the perl defined structure in the import table and then use that pointer to fetch the value.

Any gain in space/time from moving the only r/w static storage out of Win32.xs could be lost easily if a new static variable was added.

Wouldn't​:

#if !((PERL_VERSION >= 5) && (PERL_VERSION >= 21) && (PERL_SUBVERSION >= 8))

be simpler as just​:

#if !defined(dW32OSVER)

?

Tony

@p5pRT
Copy link
Author

p5pRT commented Feb 3, 2015

From @bulk88

On Mon Feb 02 17​:20​:17 2015, tonyc wrote​:

Thanks.

I'd like to see comments from jdb on this.

I can see this (very slightly) slowing down calls into Win32​::*
functions that use the version structure, since rather than using the
module global g_osver, they need to look up the perl defined structure
in the import table and then use that pointer to fetch the value.

2 derefs vs 1, but less startup overhead (not callingGetVersionEx), plus Perl XS should be a better "standard library" than it is now, plus this centralizes the Win 8.1 problem. threaded perl uses my_perl, but unthreaded perl uses data exports, which always have 2 derefs due to to IAT (and so does ELF), so I don't think its a perf problem since unthreaded perl is supposedly faster than unthreaded. A ptr deref is faster than executing any C function (GetVersionEx) anyway. This patch is part of an unpublished patch that makes many the core modules free of RW C globals on Win32. I've been chopping parts of that patch off over the last 2 months as various "const" C globals in ______ XS module. Since I can't const the version struct in Win32​::, I can make it faux-RO by storing it in the core (core already privately stored it before). Cpan grep is down ATM, but GetVersionEx had a couple more Perl XS modules using it other than Win32​::, so I thought it should be part of Perl XS standard library, instead of each module rolling their own.

Any gain in space/time from moving the only r/w static storage out of
Win32.xs could be lost easily if a new static variable was added.

Wouldn't​:

#if !((PERL_VERSION >= 5) && (PERL_VERSION >= 21) && (PERL_SUBVERSION

= 8))

be simpler as just​:

#if !defined(dW32OSVER)

?

Tony

My style is to use version comparisons.

#if !defined(dFOOVER)

doesn't make it clear if dFOOVER doesn't exist because

A. the perl or module is too old

B. compile time user option, the perl src tree supports the feature, but either the OS doesn't support it, or the user didn't turn it on/off in Configure or in config.h or didn't do a magical -DENABLE_FOO

Writing explicit versions makes it clear when the feature is available only based on age, vs thinking its a Configure-time option or a posix libc feature probe.

--
bulk88 ~ bulk88 at hotmail.com

@p5pRT
Copy link
Author

p5pRT commented Aug 3, 2015

From @bulk88

The C code in this patch has a bug somewhere. Windows XP is Win95. I'll get around to fixing it at some point in the future.

--
bulk88 ~ bulk88 at hotmail.com

@toddr
Copy link
Member

toddr commented Feb 13, 2020

This patch no longer applies. Could it be re-submitted as a PR if you're interested in working on it further please?

@toddr toddr closed this as completed Feb 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants