Skip to content

Commit

Permalink
windows: emulate uname
Browse files Browse the repository at this point in the history
Only our Cygwin builds supported the Unix-like uname() but its
output was more Cygwin info than Windows info.

Use GetVersionEx() to get Windows version numbers
(it's deprecated but it works and it's more convenient than IsWindows10OrGreater() etc)

Use GetComputerName() like we did in lstopo when missing a hostname.

Use GetNativeSystemInfo() to get the architecture (and make it a Unix-like string).

Add a WindowsBuildEnvironment info attr for cygwin/mingw.

Closes #208

Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
  • Loading branch information
bgoglin committed Oct 17, 2020
1 parent 72ddda3 commit 52231d0
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 3 deletions.
3 changes: 3 additions & 0 deletions doc/hwloc.doxy
Expand Up @@ -1795,6 +1795,9 @@ architecture name, as reported by the Unix <tt>uname</tt> command.
<dd>The name the Linux control group where the calling process is
placed.
</dd>
<dt>WindowsBuildEnvironment</dt>
<dd>Either MinGW or Cygwin when one of these environments was used during build.
</dd>
</dl>


Expand Down
63 changes: 62 additions & 1 deletion hwloc/topology-windows.c
Expand Up @@ -753,13 +753,21 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
DWORD length;
int gotnuma = 0;
int gotnumamemory = 0;
OSVERSIONINFOEX osvi;
char versionstr[20];
char hostname[122] = "";
unsigned hostname_size = sizeof(hostname);

assert(dstatus->phase == HWLOC_DISC_PHASE_CPU);

if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return -1;

ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
GetVersionEx((LPOSVERSIONINFO)&osvi);

hwloc_alloc_root_sets(topology->levels[0][0]);

GetSystemInfo(&SystemInfo);
Expand Down Expand Up @@ -1095,8 +1103,61 @@ hwloc_look_windows(struct hwloc_backend *backend, struct hwloc_disc_status *dsta
}

out:
/* emulate uname instead of calling hwloc_add_uname_info() */
hwloc_obj_add_info(topology->levels[0][0], "Backend", "Windows");
hwloc_add_uname_info(topology, NULL);
hwloc_obj_add_info(topology->levels[0][0], "OSName", "Windows");

#if defined(__CYGWIN__)
hwloc_obj_add_info(topology->levels[0][0], "WindowsBuildEnvironment", "Cygwin");
#elif defined(__MINGW32__)
hwloc_obj_add_info(topology->levels[0][0], "WindowsBuildEnvironment", "MinGW");
#endif

/* see https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-osversioninfoexa */
if (osvi.dwMajorVersion == 10) {
if (osvi.dwMinorVersion == 0)
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "10");
} else if (osvi.dwMajorVersion == 6) {
if (osvi.dwMinorVersion == 3)
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "8.1"); /* or "Server 2012 R2" */
else if (osvi.dwMinorVersion == 2)
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "8"); /* or "Server 2012" */
else if (osvi.dwMinorVersion == 1)
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "7"); /* or "Server 2008 R2" */
else if (osvi.dwMinorVersion == 0)
hwloc_obj_add_info(topology->levels[0][0], "OSRelease", "Vista"); /* or "Server 2008" */
} /* earlier versions are ignored */

snprintf(versionstr, sizeof(versionstr), "%u.%u.%u", osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
hwloc_obj_add_info(topology->levels[0][0], "OSVersion", versionstr);

#if !defined(__CYGWIN__)
GetComputerName(hostname, &hostname_size);
#else
gethostname(hostname, hostname_size);
#endif
if (*hostname)
hwloc_obj_add_info(topology->levels[0][0], "Hostname", hostname);

/* convert to unix-like architecture strings */
switch (SystemInfo.wProcessorArchitecture) {
case 0:
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "i686");
break;
case 9:
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "x86_64");
break;
case 5:
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "arm");
break;
case 12:
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "arm64");
break;
case 6:
hwloc_obj_add_info(topology->levels[0][0], "Architecture", "ia64");
break;
}

return 0;
}

Expand Down
39 changes: 37 additions & 2 deletions tests/hwloc/ports/include/windows/windows.h
Expand Up @@ -96,6 +96,7 @@ typedef int HANDLE;
#define _ANONYMOUS_STRUCT
#endif /* __GNUC__ */
#define DUMMYUNIONNAME
#define DUMMYSTRUCTNAME
#define WINAPI

#define ANYSIZE_ARRAY 1
Expand Down Expand Up @@ -124,9 +125,24 @@ PVOID WINAPI VirtualAlloc(PVOID,DWORD,DWORD,DWORD);
BOOL GetNumaAvailableMemoryNode(UCHAR Node, PULONGLONG AvailableBytes);

typedef struct _SYSTEM_INFO {
DWORD dwPageSize;
_ANONYMOUS_UNION
union {
DWORD dwOemId;
_ANONYMOUS_STRUCT
struct {
WORD wProcessorArchitecture;
WORD wReserved;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD_PTR dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
} SYSTEM_INFO, *LPSYSTEM_INFO;

void WINAPI GetSystemInfo(LPSYSTEM_INFO lpSystemInfo);
Expand Down Expand Up @@ -173,6 +189,25 @@ BOOL TranslateMessage(const MSG *lpMsg);
BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);
VOID WINAPI PostQuitMessage(int nExitCode);

typedef struct _OSVERSIONINFOEX {
DWORD dwOSVersionInfoSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformId;
CHAR szCSDVersion[128];
WORD wServicePackMajor;
WORD wServicePackMinor;
WORD wSuiteMask;
BYTE wProductType;
BYTE wReserved;
} OSVERSIONINFOEX;
typedef OSVERSIONINFOEX* LPOSVERSIONINFO;
BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInformation);
void ZeroMemory(PVOID Destination, SIZE_T Length);

BOOL GetComputerName(LPSTR lpBuffer, LPDWORD nSize);

#define WM_DESTROY 2
#define WM_SIZE 5
#define WM_PAINT 15
Expand Down

0 comments on commit 52231d0

Please sign in to comment.