Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add new apis proposed in #4137 to System.Runtime.InteropServices.RuntimeInformation #4334

Merged
merged 1 commit into from
Dec 7, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Sys
{
[DllImport(Libraries.SystemNative)]
internal static extern int GetUnixArchitecture();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete SetLastError - the implementation does not set last error


internal enum ProcessorArchitecture
{
x86,
x64,
ARM
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add ARM64 too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now we are not supported Arm64, it'll be there in enum unused. When we start supporting for Arm64, we can change this since it's a OOB assembly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other existing runtimes (mono, Unity) do support arm64 already. You should add it to the public contract at least so that this contract can be implemented by other runtimes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jkotas In the API review it was decided to not add Arm64 right now. Adding Arm64 will require a new API Review, not in the scope of this PR. Will file a new issue for this, #4384

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using System.Text;

internal static partial class Interop
{
internal static partial class Sys
{
[DllImport(Libraries.SystemNative, CharSet = CharSet.Ansi, SetLastError = true)]
private static extern int GetUnixVersion(StringBuilder version, out int capacity);

internal static string GetUnixVersion()
{
// max value of _UTSNAME_LENGTH on known Unix platforms is 1024.
const int _UTSNAME_LENGTH = 1024;
int capacity = _UTSNAME_LENGTH * 3 + 2;
StringBuilder version = new StringBuilder(capacity);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer var? Or more keystrokes 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, the guidelines says we use var only for cases where it's simple to guess the type, but it doesn't say it's preferred or compulsory. And personally everywhere else in code I have not used var, changing this, will not put me in peace until i change every other instance. So keeping as is.

And on keystrokes, i use intellisense heavily. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also prefer to avoid var except for extremely long/pointless type declarations. And like you said, our guidelines allow either.


if (GetUnixVersion(version, out capacity) != 0)
{
// Check if the function failed due to insufficient buffer.
if (capacity > version.Capacity)
{
version.Capacity = capacity;
GetUnixVersion(version, out capacity);
}
}

return version.ToString();
}
}
}
3 changes: 2 additions & 1 deletion src/Common/src/Interop/Windows/Interop.Libraries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ internal static class Libraries
internal const string ServiceCore = "api-ms-win-service-core-l1-1-1.dll";
internal const string Sspi = "sspicli.dll";
internal const string Synch = "api-ms-win-core-synch-l1-1-0.dll";
internal const string SystemInfo = "api-ms-win-core-sysinfo-l1-1-0.dll";
internal const string SystemInfo_L1_1 = "api-ms-win-core-sysinfo-l1-1-0.dll";
internal const string SystemInfo_L1_2 = "api-ms-win-core-sysinfo-l1-2-0.dll";
internal const string User32 = "user32.dll";
internal const string Version = "api-ms-win-core-version-l1-1-0.dll";
internal const string WinHttp = "winhttp.dll";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class NtDll
{
[StructLayout(LayoutKind.Sequential)]
internal struct RTL_OSVERSIONINFOEX
{
internal uint dwOSVersionInfoSize;
internal uint dwMajorVersion;
internal uint dwMinorVersion;
internal uint dwBuildNumber;
internal uint dwPlatformId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
internal string szCSDVersion;
}
}
}
31 changes: 31 additions & 0 deletions src/Common/src/Interop/Windows/NtDll/Interop.RtlGetVersion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;
using System.Security;

internal partial class Interop
{
internal partial class NtDll
{
[DllImport(Libraries.NtDll)]
private static extern int RtlGetVersion(out RTL_OSVERSIONINFOEX lpVersionInformation);

internal static string RtlGetVersion()
{
RTL_OSVERSIONINFOEX osvi = new RTL_OSVERSIONINFOEX();
osvi.dwOSVersionInfoSize = (uint)Marshal.SizeOf(osvi);
const string version = "Microsoft Windows";
if (RtlGetVersion(out osvi) == 0)
{
return string.Format("{0} {1}.{2}.{3} {4}",
version, osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber, osvi.szCSDVersion);
}
else
{
return version;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class mincore
{
[DllImport(Libraries.SystemInfo_L1_2)]
internal extern static void GetNativeSystemInfo(out SYSTEM_INFO lpSystemInfo);
}
}
17 changes: 1 addition & 16 deletions src/Common/src/Interop/Windows/mincore/Interop.GetSystemInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,7 @@ internal partial class Interop
{
internal partial class mincore
{
[DllImport(Libraries.SystemInfo)]
[DllImport(Libraries.SystemInfo_L1_1)]
internal extern static void GetSystemInfo(out SYSTEM_INFO lpSystemInfo);

[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
internal int dwOemId;
internal int dwPageSize;
internal IntPtr lpMinimumApplicationAddress;
internal IntPtr lpMaximumApplicationAddress;
internal IntPtr dwActiveProcessorMask;
internal int dwNumberOfProcessors;
internal int dwProcessorType;
internal int dwAllocationGranularity;
internal short wProcessorLevel;
internal short wProcessorRevision;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal partial class Interop
{
internal partial class mincore
{
[DllImport(Libraries.SystemInfo)]
[DllImport(Libraries.SystemInfo_L1_1)]
internal extern static int GlobalMemoryStatusEx(out MEMORYSTATUSEX lpBuffer);
}
}
36 changes: 36 additions & 0 deletions src/Common/src/Interop/Windows/mincore/Interop.SYSTEM_INFO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Runtime.InteropServices;

internal partial class Interop
{
internal partial class mincore
{
[StructLayout(LayoutKind.Sequential)]
internal struct SYSTEM_INFO
{
internal ushort wProcessorArchitecture;
internal ushort wReserved;
internal int dwPageSize;
internal IntPtr lpMinimumApplicationAddress;
internal IntPtr lpMaximumApplicationAddress;
internal IntPtr dwActiveProcessorMask;
internal int dwNumberOfProcessors;
internal int dwProcessorType;
internal int dwAllocationGranularity;
internal short wProcessorLevel;
internal short wProcessorRevision;
}

internal enum ProcessorArchitecture : ushort
{
Processor_Architecture_INTEL = 0,
Processor_Architecture_ARM = 5,
Processor_Architecture_IA64 = 6,
Processor_Architecture_AMD64 = 9,
Processor_Architecture_UNKNOWN = 0xFFFF
}
}
}
2 changes: 2 additions & 0 deletions src/Native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ endif ()

if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL amd64)
add_definitions(-DBIT64=1)
add_definitions(-DX64=1)
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL armv7l)
add_definitions(-DBIT32=1)
add_definitions(-DARM=1)
add_definitions(-D_FILE_OFFSET_BITS=64)
# Because we don't use CMAKE_C_COMPILER/CMAKE_CXX_COMPILER to use clang
# we have to set the triple by adding a compiler argument
Expand Down
1 change: 1 addition & 0 deletions src/Native/System.Native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(NATIVE_SOURCES
pal_networking.cpp
pal_networkstatistics.cpp
pal_process.cpp
pal_runtimeinformation.cpp
pal_string.cpp
pal_tcpstate.cpp
pal_time.cpp
Expand Down
39 changes: 39 additions & 0 deletions src/Native/System.Native/pal_runtimeinformation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "pal_runtimeinformation.h"
#include "pal_types.h"
#include <stdio.h>
#include <sys/utsname.h>

extern "C" int32_t GetUnixVersion(char* version, int* capacity)
{
struct utsname _utsname;
if (uname(&_utsname) != -1)
{
int r = snprintf(version, static_cast<size_t>(*capacity), "%s %s %s", _utsname.sysname, _utsname.release, _utsname.version);
if (r > *capacity)
{
*capacity = r + 1;
return -1;
}
}

return 0;
}

/* Returns an int representing the OS Architecture:
0 - x86
1 - x64
2 - ARM */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define a PAL enum in the .h and return it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

extern "C" int32_t GetUnixArchitecture()
{
#if defined(ARM)
return ARCH_ARM;
#elif defined(X64)
return ARCH_X64;
#elif defined(X86)
return ARCH_X86;
#error Unidentified Architecture
#endif
}
17 changes: 17 additions & 0 deletions src/Native/System.Native/pal_runtimeinformation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#pragma once

#include "pal_types.h"

extern "C" int32_t GetUnixVersion(char* version, int* capacity);

extern "C" int32_t GetUnixArchitecture();

enum
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use the scoped enumeration (i.e. enum class)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scoped enumeration cannot implicitly convert to underlying intergral types, needs static_cast everywhere, where we only intend to use this enum to represent a name for the integrals. unscoped enumeration serves the purpose here with less complexity.

{
ARCH_X86,
ARCH_X64,
ARCH_ARM
};
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@
<Compile Include="$(CommonPath)\Interop\Windows\mincore\Interop.GetSystemInfo.cs">
<Link>Common\Interop\Windows\Interop.GetSystemInfo.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\mincore\Interop.SYSTEM_INFO.cs">
<Link>Common\Interop\Windows\Interop.SYSTEM_INFO.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Windows\mincore\Interop.GlobalMemoryStatusEx.cs">
<Link>Common\Interop\Windows\Interop.GlobalMemoryStatusEx.cs</Link>
</Compile>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22609.0
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime.InteropServices.RuntimeInformation", "src\System.Runtime.InteropServices.RuntimeInformation.csproj", "{F9DF2357-81B4-4317-908E-512DA9395583}"
EndProject
Expand All @@ -21,6 +21,7 @@ Global
Windows_Release|Any CPU = Windows_Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F9DF2357-81B4-4317-908E-512DA9395583}.Debug|Any CPU.ActiveCfg = Windows_Debug|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.FreeBSD_Debug|Any CPU.ActiveCfg = FreeBSD_Debug|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.FreeBSD_Debug|Any CPU.Build.0 = FreeBSD_Debug|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.FreeBSD_Release|Any CPU.ActiveCfg = FreeBSD_Release|Any CPU
Expand All @@ -33,10 +34,12 @@ Global
{F9DF2357-81B4-4317-908E-512DA9395583}.OSX_Debug|Any CPU.Build.0 = OSX_Debug|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.OSX_Release|Any CPU.ActiveCfg = OSX_Release|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.OSX_Release|Any CPU.Build.0 = OSX_Release|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.Release|Any CPU.ActiveCfg = Windows_Release|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.Windows_Debug|Any CPU.ActiveCfg = Windows_Debug|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.Windows_Debug|Any CPU.Build.0 = Windows_Debug|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.Windows_Release|Any CPU.ActiveCfg = Windows_Release|Any CPU
{F9DF2357-81B4-4317-908E-512DA9395583}.Windows_Release|Any CPU.Build.0 = Windows_Release|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.FreeBSD_Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.FreeBSD_Debug|Any CPU.Build.0 = Debug|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.FreeBSD_Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -49,6 +52,7 @@ Global
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.OSX_Debug|Any CPU.Build.0 = Debug|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.OSX_Release|Any CPU.ActiveCfg = Release|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.OSX_Release|Any CPU.Build.0 = Release|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.Windows_Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.Windows_Debug|Any CPU.Build.0 = Debug|Any CPU
{9B4D1DA9-AA4C-428F-9F66-D45C924025A5}.Windows_Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,20 @@ public partial struct OSPlatform : System.IEquatable<System.Runtime.InteropServi
public static bool operator !=(System.Runtime.InteropServices.OSPlatform left, System.Runtime.InteropServices.OSPlatform right) { return default(bool); }
public override string ToString() { return default(string); }
}

public enum Architecture
{
X86,
X64,
Arm
}

public static partial class RuntimeInformation
{
public static Architecture ProcessArchitecture { get { return default(Architecture); } }
public static Architecture OSArchitecture { get { return default(Architecture); } }
public static string OSDescription { get { return default(string); } }
public static string FrameworkDescription { get { return default(string); } }
public static bool IsOSPlatform(System.Runtime.InteropServices.OSPlatform osPlatform) { return default(bool); }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace System.Runtime.InteropServices
{
public enum Architecture
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be defined in just one place? There is a copy in the ref... Also may be add a comment that this definition needs to be consistent with the native counterpart?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scratch the last part - I see there is one more enum type for architecture - ProcessorArchitecture - still the question why you can't have just one definition in managed code stands.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To separate the interop layer with the lib code. We may reuse GetUnixArchitecture() elsewhere without having to reference RuntimeInformation for Architecture.

{
X86,
X64,
Arm
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace System.Runtime.InteropServices
{
public static class RuntimeInformation
public static partial class RuntimeInformation
{
private static OSPlatform s_freeBSD = OSPlatform.Create("FREEBSD");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace System.Runtime.InteropServices
{
public static class RuntimeInformation
public static partial class RuntimeInformation
{
public static bool IsOSPlatform(OSPlatform osPlatform)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace System.Runtime.InteropServices
{
public static class RuntimeInformation
public static partial class RuntimeInformation
{
public static bool IsOSPlatform(OSPlatform osPlatform)
{
Expand Down
Loading