diff --git a/.dotnet6.0.metadata b/.dotnet6.0.metadata index 1a855ef..c6b8af0 100644 --- a/.dotnet6.0.metadata +++ b/.dotnet6.0.metadata @@ -1,3 +1 @@ -1aa752efb0102349176045a3262ab4d85961a5e9 SOURCES/dotnet-28be3e9a006d90d8c6e87d4353b77882829df718-x64-bootstrap.tar.xz -24ff251aaded592f67ec3dfaaca63184d3fd0303 SOURCES/dotnet-arm64-prebuilts-2021-10-04.tar.gz -1e391934046ab2857b716526310ffa3f9df8ff28 SOURCES/dotnet-s390x-prebuilts-2021-10-01.tar.gz +4521a07f53136d83916b1a044ed6cba3b8a41813 SOURCES/dotnet-9e8b04bbff820c93c142f99a507a46b976f5c14c.tar.gz diff --git a/.gitignore b/.gitignore index efd9129..faa0263 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -SOURCES/dotnet-28be3e9a006d90d8c6e87d4353b77882829df718-x64-bootstrap.tar.xz -SOURCES/dotnet-arm64-prebuilts-2021-10-04.tar.gz -SOURCES/dotnet-s390x-prebuilts-2021-10-01.tar.gz +SOURCES/dotnet-9e8b04bbff820c93c142f99a507a46b976f5c14c.tar.gz diff --git a/SOURCES/aspnetcore-add-arm64-crossgen-dependencies.patch b/SOURCES/aspnetcore-add-arm64-crossgen-dependencies.patch deleted file mode 100644 index 0bba983..0000000 --- a/SOURCES/aspnetcore-add-arm64-crossgen-dependencies.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/eng/Dependencies.props b/eng/Dependencies.props -index 8a50fb9f21..a13b74fb51 100644 ---- a/eng/Dependencies.props -+++ b/eng/Dependencies.props -@@ -99,6 +99,7 @@ and are generated based on the last package release. - - - -+ - - - diff --git a/SOURCES/aspnetcore-dont-check-eol-targets.patch b/SOURCES/aspnetcore-dont-check-eol-targets.patch deleted file mode 100644 index 7ab712d..0000000 --- a/SOURCES/aspnetcore-dont-check-eol-targets.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/eng/SourceBuild.props -+++ b/eng/SourceBuild.props -@@ -69,6 +69,8 @@ - - - $(InnerBuildArgs) /p:SourceBuildRuntimeIdentifier=$(TargetRuntimeIdentifier) -+ $(InnerBuildArgs) /p:CheckEolTargetFramework=false -+ $(InnerBuildArgs) /p:EnablePreviewFeatures=true - - - diff --git a/SOURCES/aspnetcore-no-shared-compilation.patch b/SOURCES/aspnetcore-no-shared-compilation.patch deleted file mode 100644 index f29acfd..0000000 --- a/SOURCES/aspnetcore-no-shared-compilation.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: source-build-tarball/src/aspnetcore.4ab0cf33ecb1c25a38422f5b11810e4c8a91d8eb/Directory.Build.props -=================================================================== ---- a/Directory.Build.props -+++ b/Directory.Build.props -@@ -48,6 +48,8 @@ - - - true -+ -+ false - - - - $(OtherFlags) --nowarn:1204 - -Index: tests/benchmarks/TaskPerf/TaskPerf.fsproj -=================================================================== + + + $(OtherFlags) --nowarn:1204 + diff --git a/SOURCES/fsharp-no-shared-compilation.patch b/SOURCES/fsharp-no-shared-compilation.patch deleted file mode 100644 index 21ec960..0000000 --- a/SOURCES/fsharp-no-shared-compilation.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: a/FSharpBuild.Directory.Build.props -=================================================================== ---- a/FSharpBuild.Directory.Build.props -+++ b/FSharpBuild.Directory.Build.props -@@ -21,6 +21,7 @@ - 4.4.0 - 1182;0025;$(WarningsAsErrors) - $(OtherFlags) --nowarn:3384 -+ false - - - diff --git a/SOURCES/msbuild-no-systemconfiguration.patch b/SOURCES/msbuild-no-systemconfiguration.patch new file mode 100644 index 0000000..537470d --- /dev/null +++ b/SOURCES/msbuild-no-systemconfiguration.patch @@ -0,0 +1,46 @@ +--- a/src/Build/Definition/ProjectCollection.cs ++++ b/src/Build/Definition/ProjectCollection.cs +@@ -1754,7 +1754,11 @@ namespace Microsoft.Build.Evaluation + #if FEATURE_WIN32_REGISTRY + ToolsetRegistryReader registryReader = null, + #endif ++#if FEATURE_SYSTEM_CONFIGURATION + ToolsetConfigurationReader configReader = null ++#else ++ object configReader = null ++#endif + ) + { + _toolsets = new Dictionary(StringComparer.OrdinalIgnoreCase); +--- a/src/Build/Definition/ToolsetReader.cs ++++ b/src/Build/Definition/ToolsetReader.cs +@@ -101,7 +101,11 @@ namespace Microsoft.Build.Evaluation + #if FEATURE_WIN32_REGISTRY + ToolsetRegistryReader registryReader, + #endif ++#if FEATURE_SYSTEM_CONFIGURATION + ToolsetConfigurationReader configurationReader, ++#else ++ object _configurationReader, ++#endif + PropertyDictionary environmentProperties, + PropertyDictionary globalProperties, + ToolsetDefinitionLocations locations +@@ -120,6 +124,7 @@ namespace Microsoft.Build.Evaluation + + if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile) + { ++#if FEATURE_SYSTEM_CONFIGURATION + if (configurationReader == null) + { + configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties); +@@ -129,6 +134,9 @@ namespace Microsoft.Build.Evaluation + defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties, + initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration, + out defaultOverrideToolsVersionFromConfiguration); ++#else ++ throw new InvalidOperationException("ToolsetDefinitionLocations.ConfigurationFile not supported"); ++#endif + } + + string defaultToolsVersionFromRegistry = null; diff --git a/SOURCES/msbuild-no-systemsecurity.patch b/SOURCES/msbuild-no-systemsecurity.patch new file mode 100644 index 0000000..dcf6809 --- /dev/null +++ b/SOURCES/msbuild-no-systemsecurity.patch @@ -0,0 +1,12 @@ +--- a/src/Shared/ExceptionHandling.cs ++++ b/src/Shared/ExceptionHandling.cs +@@ -153,7 +153,9 @@ namespace Microsoft.Build.Shared + internal static bool IsXmlException(Exception e) + { + return e is XmlException ++#if FEATURE_SECURITY_PERMISSIONS + || e is XmlSyntaxException ++#endif + || e is XmlSchemaException + || e is UriFormatException; // XmlTextReader for example uses this under the covers + } diff --git a/SOURCES/nuget-client-use-work-tree-with-git-apply.patch b/SOURCES/nuget-client-use-work-tree-with-git-apply.patch deleted file mode 100644 index e1785ae..0000000 --- a/SOURCES/nuget-client-use-work-tree-with-git-apply.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 691babb1c8316e2f829fbcf9f2aa14f4b7711960 Mon Sep 17 00:00:00 2001 -From: Omair Majid -Date: Thu, 9 Sep 2021 10:03:36 -0400 -Subject: [PATCH] [ArPow] Use --work-tree with git apply - -This makes things work bettern in a source-tarball build (where there -may not be a .git directory), or there might be a .git directory but -it's for a different repo than the one we are building. ---- - eng/source-build/source-build.proj | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/eng/source-build/source-build.proj b/eng/source-build/source-build.proj -index 6f90f9793..72058ac88 100644 ---- a/eng/source-build/source-build.proj -+++ b/eng/source-build/source-build.proj -@@ -55,7 +55,7 @@ - - - - --- -2.31.1 - diff --git a/SOURCES/roslyn-57003-mono-named-mutex.patch b/SOURCES/roslyn-57003-mono-named-mutex.patch new file mode 100644 index 0000000..c264bff --- /dev/null +++ b/SOURCES/roslyn-57003-mono-named-mutex.patch @@ -0,0 +1,453 @@ +Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs +=================================================================== +--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs ++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Core/Portable/InternalUtilities/PlatformInformation.cs +@@ -31,5 +31,24 @@ namespace Roslyn.Utilities + } + } + } ++ /// ++ /// Are we running on .NET 5 or later using the Mono runtime? ++ /// Will also return true when running on Mono itself; if necessary ++ /// we can use IsRunningOnMono to distinguish. ++ /// ++ public static bool IsUsingMonoRuntime ++ { ++ get ++ { ++ try ++ { ++ return !(Type.GetType("Mono.RuntimeStructs", throwOnError: false) is null); ++ } ++ catch ++ { ++ return false; ++ } ++ } ++ } + } + } +Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs +=================================================================== +--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs ++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/BuildClientTests.cs +@@ -79,7 +79,7 @@ namespace Microsoft.CodeAnalysis.Compile + // to connect. When it fails it should fall back to in-proc + // compilation. + bool holdsMutex; +- using (var serverMutex = new Mutex(initiallyOwned: true, ++ using (var serverMutex = BuildServerConnection.OpenOrCreateMutex( + name: BuildServerConnection.GetServerMutexName(_pipeName), + createdNew: out holdsMutex)) + { +Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs +=================================================================== +--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs ++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerApiTest.cs +@@ -103,7 +103,7 @@ class Hello + var mutexName = BuildServerConnection.GetServerMutexName(pipeName); + + bool holdsMutex; +- using (var mutex = new Mutex(initiallyOwned: true, ++ using (var mutex = BuildServerConnection.OpenOrCreateMutex( + name: mutexName, + createdNew: out holdsMutex)) + { +@@ -119,7 +119,7 @@ class Hello + } + finally + { +- mutex.ReleaseMutex(); ++ mutex.Dispose(); + } + } + } +Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs +=================================================================== +--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs ++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/CompilerServerTests.cs +@@ -304,7 +304,7 @@ End Module") + var newTempDir = _tempDirectory.CreateDirectory(new string('a', 100 - _tempDirectory.Path.Length)); + await ApplyEnvironmentVariables( + new[] { new KeyValuePair("TMPDIR", newTempDir.Path) }, +- async () => ++ async () => await Task.Run(async () => + { + using var serverData = await ServerUtil.CreateServer(_logger); + var result = RunCommandLineCompiler( +@@ -317,7 +317,7 @@ End Module") + + var listener = await serverData.Complete(); + Assert.Equal(CompletionData.RequestCompleted, listener.CompletionDataList.Single()); +- }); ++ })); + } + + [Fact] +Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs +=================================================================== +--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs ++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Server/VBCSCompilerTests/VBCSCompilerServerTests.cs +@@ -101,7 +101,7 @@ namespace Microsoft.CodeAnalysis.Compile + + var thread = new Thread(() => + { +- using (var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created)) ++ using (var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created)) + using (var stream = NamedPipeUtil.CreateServer(pipeName)) + { + readyMre.Set(); +@@ -112,7 +112,7 @@ namespace Microsoft.CodeAnalysis.Compile + stream.Close(); + + doneMre.WaitOne(); +- mutex.ReleaseMutex(); ++ mutex.Dispose(); + } + }); + +@@ -153,7 +153,7 @@ namespace Microsoft.CodeAnalysis.Compile + { + using (var stream = NamedPipeUtil.CreateServer(pipeName)) + { +- var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created); ++ var mutex = BuildServerConnection.OpenOrCreateMutex(name: mutexName, createdNew: out created); + readyMre.Set(); + + stream.WaitForConnection(); +@@ -161,7 +161,6 @@ namespace Microsoft.CodeAnalysis.Compile + + // Client is waiting for a response. Close the mutex now. Then close the connection + // so the client gets an error. +- mutex.ReleaseMutex(); + mutex.Dispose(); + stream.Close(); + +Index: tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs +=================================================================== +--- tarball.6.0.1-rc2-6.0.100-rc2.orig/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs ++++ tarball.6.0.1-rc2-6.0.100-rc2/src/roslyn.8e1779e16298415843e85029d8b52a1ae9bb4c30/src/Compilers/Shared/BuildServerConnection.cs +@@ -543,19 +543,10 @@ namespace Microsoft.CodeAnalysis.Command + { + try + { +- if (PlatformInformation.IsRunningOnMono) ++ if (PlatformInformation.IsUsingMonoRuntime) + { +- IServerMutex? mutex = null; +- bool createdNew = false; +- try +- { +- mutex = new ServerFileMutexPair(mutexName, false, out createdNew); +- return !createdNew; +- } +- finally +- { +- mutex?.Dispose(); +- } ++ using var mutex = new ServerFileMutex(mutexName); ++ return !mutex.CouldLock(); + } + else + { +@@ -572,9 +563,11 @@ namespace Microsoft.CodeAnalysis.Command + + internal static IServerMutex OpenOrCreateMutex(string name, out bool createdNew) + { +- if (PlatformInformation.IsRunningOnMono) ++ if (PlatformInformation.IsUsingMonoRuntime) + { +- return new ServerFileMutexPair(name, initiallyOwned: true, out createdNew); ++ var mutex = new ServerFileMutex(name); ++ createdNew = mutex.TryLock(0); ++ return mutex; + } + else + { +@@ -648,19 +641,22 @@ namespace Microsoft.CodeAnalysis.Command + } + + /// +- /// An interprocess mutex abstraction based on OS advisory locking (FileStream.Lock/Unlock). ++ /// An interprocess mutex abstraction based on file sharing permission (FileShare.None). + /// If multiple processes running as the same user create FileMutex instances with the same name, + /// those instances will all point to the same file somewhere in a selected temporary directory. +- /// The TryLock method can be used to attempt to acquire the mutex, with Unlock or Dispose used to release. ++ /// The TryLock method can be used to attempt to acquire the mutex, with Dispose used to release. ++ /// The CouldLock method can be used to check whether an attempt to acquire the mutex would have ++ /// succeeded at the current time, without actually acquiring it. + /// Unlike Win32 named mutexes, there is no mechanism for detecting an abandoned mutex. The file + /// will simply revert to being unlocked but remain where it is. + /// +- internal sealed class FileMutex : IDisposable ++ internal sealed class ServerFileMutex : IServerMutex + { +- public readonly FileStream Stream; ++ public FileStream? Stream; + public readonly string FilePath; ++ public readonly string GuardPath; + +- public bool IsLocked { get; private set; } ++ public bool IsDisposed { get; private set; } + + internal static string GetMutexDirectory() + { +@@ -670,61 +666,176 @@ namespace Microsoft.CodeAnalysis.Command + return result; + } + +- public FileMutex(string name) ++ public ServerFileMutex(string name) + { +- FilePath = Path.Combine(GetMutexDirectory(), name); +- Stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); ++ var mutexDirectory = GetMutexDirectory(); ++ FilePath = Path.Combine(mutexDirectory, name); ++ GuardPath = Path.Combine(mutexDirectory, ".guard"); + } + +- public bool TryLock(int timeoutMs) ++ /// ++ /// Acquire the guard by opening the guard file with FileShare.None. The guard must only ever ++ /// be held for very brief amounts of time, so we can simply spin until it is acquired. The ++ /// guard must be released by disposing the FileStream returned from this routine. Note the ++ /// guard file is never deleted; this is a leak, but only of a single file. ++ /// ++ internal FileStream LockGuard() + { +- if (IsLocked) +- throw new InvalidOperationException("Lock already held"); +- +- var sw = Stopwatch.StartNew(); +- do ++ // We should be able to acquire the guard quickly. Limit the number of retries anyway ++ // by some arbitrary bound to avoid getting hung up in a possibly infinite loop. ++ for (var i = 0; i < 100; i++) + { + try + { +- Stream.Lock(0, 0); +- IsLocked = true; +- return true; ++ return new FileStream(GuardPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); + } + catch (IOException) + { +- // Lock currently held by someone else. ++ // Guard currently held by someone else. + // We want to sleep for a short period of time to ensure that other processes + // have an opportunity to finish their work and relinquish the lock. + // Spinning here (via Yield) would work but risks creating a priority + // inversion if the lock is held by a lower-priority process. + Thread.Sleep(1); + } ++ } ++ // Handle unexpected failure to acquire guard as error. ++ throw new InvalidOperationException("Unable to acquire guard"); ++ } ++ ++ /// ++ /// Attempt to acquire the lock by opening the lock file with FileShare.None. Sets "Stream" ++ /// and returns true if successful, returns false if the lock is already held by another ++ /// thread or process. Guard must be held when calling this routine. ++ /// ++ internal bool TryLockFile() ++ { ++ Debug.Assert(Stream is null); ++ FileStream? stream = null; ++ try ++ { ++ stream = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); ++ // On some targets, the file locking used to implement FileShare.None may not be ++ // atomic with opening/creating the file. This creates a race window when another ++ // thread holds the lock and is just about to unlock: we may be able to open the ++ // file here, then the other thread unlocks and deletes the file, and then we ++ // acquire the lock on our file handle - but the actual file is already deleted. ++ // To close this race, we verify that the file does in fact still exist now that ++ // we have successfull acquired the locked FileStream. (Note that this check is ++ // safe because we cannot race with an other attempt to create the file since we ++ // hold the guard, and after the FileStream constructor returned we can no race ++ // with file deletion because we hold the lock.) ++ if (!File.Exists(FilePath)) ++ { ++ // To simplify the logic, we treat this case as "unable to acquire the lock" ++ // because it we caught another process while it owned the lock and was just ++ // giving it up. If the caller retries, we'll likely acquire the lock then. ++ stream.Dispose(); ++ return false; ++ } ++ } ++ catch (Exception) ++ { ++ stream?.Dispose(); ++ return false; ++ } ++ Stream = stream; ++ return true; ++ } ++ ++ /// ++ /// Release the lock by deleting the lock file and disposing "Stream". ++ /// ++ internal void UnlockFile() ++ { ++ Debug.Assert(Stream is not null); ++ try ++ { ++ // Delete the lock file while the stream is not yet disposed ++ // and we therefore still hold the FileShare.None exclusion. ++ // There may still be a race with another thread attempting a ++ // TryLockFile in parallel, but that is safely handled there. ++ File.Delete(FilePath); ++ } ++ finally ++ { ++ Stream.Dispose(); ++ Stream = null; ++ } ++ } ++ ++ public bool TryLock(int timeoutMs) ++ { ++ if (IsDisposed) ++ throw new ObjectDisposedException("Mutex"); ++ if (Stream is not null) ++ throw new InvalidOperationException("Lock already held"); ++ ++ var sw = Stopwatch.StartNew(); ++ do ++ { ++ try ++ { ++ // Attempt to acquire lock while holding guard. ++ using var guard = LockGuard(); ++ if (TryLockFile()) ++ return true; ++ } + catch (Exception) + { +- // Something else went wrong. + return false; + } ++ ++ // See comment in LockGuard. ++ Thread.Sleep(1); + } while (sw.ElapsedMilliseconds < timeoutMs); + + return false; + } + +- public void Unlock() ++ public bool CouldLock() + { +- if (!IsLocked) +- return; +- Stream.Unlock(0, 0); +- IsLocked = false; ++ if (IsDisposed) ++ return false; ++ if (Stream is not null) ++ return false; ++ ++ try ++ { ++ // Attempt to acquire lock while holding guard, and if successful ++ // immediately unlock again while still holding guard. This ensures ++ // no other thread will spuriously observe the lock as held due to ++ // the lock attempt here. ++ using var guard = LockGuard(); ++ if (TryLockFile()) ++ { ++ UnlockFile(); ++ return true; ++ } ++ } ++ catch (Exception) ++ { ++ return false; ++ } ++ ++ return false; + } + + public void Dispose() + { +- var wasLocked = IsLocked; +- if (wasLocked) +- Unlock(); +- Stream.Dispose(); +- // We do not delete the lock file here because there is no reliable way to perform a +- // 'delete if no one has the file open' operation atomically on *nix. This is a leak. ++ if (IsDisposed) ++ return; ++ IsDisposed = true; ++ if (Stream is not null) ++ { ++ try ++ { ++ UnlockFile(); ++ } ++ catch (Exception) ++ { ++ } ++ } + } + } + +@@ -792,56 +903,4 @@ namespace Microsoft.CodeAnalysis.Command + } + } + } +- +- /// +- /// Approximates a named mutex with 'locked', 'unlocked' and 'abandoned' states. +- /// There is no reliable way to detect whether a mutex has been abandoned on some target platforms, +- /// so we use the AliveMutex to manually track whether the creator of a mutex is still running, +- /// while the HeldMutex represents the actual lock state of the mutex. +- /// +- internal sealed class ServerFileMutexPair : IServerMutex +- { +- public readonly FileMutex AliveMutex; +- public readonly FileMutex HeldMutex; +- +- public bool IsDisposed { get; private set; } +- +- public ServerFileMutexPair(string mutexName, bool initiallyOwned, out bool createdNew) +- { +- AliveMutex = new FileMutex(mutexName + "-alive"); +- HeldMutex = new FileMutex(mutexName + "-held"); +- createdNew = AliveMutex.TryLock(0); +- if (initiallyOwned && createdNew) +- { +- if (!TryLock(0)) +- throw new Exception("Failed to lock mutex after creating it"); +- } +- } +- +- public bool TryLock(int timeoutMs) +- { +- if (IsDisposed) +- throw new ObjectDisposedException("Mutex"); +- return HeldMutex.TryLock(timeoutMs); +- } +- +- public void Dispose() +- { +- if (IsDisposed) +- return; +- IsDisposed = true; +- +- try +- { +- HeldMutex.Unlock(); +- AliveMutex.Unlock(); +- } +- finally +- { +- AliveMutex.Dispose(); +- HeldMutex.Dispose(); +- } +- } +- } +- + } diff --git a/SOURCES/roslyn-analyzers-no-apphost.patch b/SOURCES/roslyn-analyzers-no-apphost.patch index f4e7f4b..c1fc3dd 100644 --- a/SOURCES/roslyn-analyzers-no-apphost.patch +++ b/SOURCES/roslyn-analyzers-no-apphost.patch @@ -1,11 +1,9 @@ -Index: roslyn-analyzers.e71e518713d6d578569bba6c5d401e405eee6058/src/Tools/ReleaseNotesUtil/ReleaseNotesUtil.csproj -=================================================================== --- a/src/Tools/ReleaseNotesUtil/ReleaseNotesUtil.csproj +++ b/src/Tools/ReleaseNotesUtil/ReleaseNotesUtil.csproj -@@ -3,6 +3,7 @@ - Exe +@@ -4,6 +4,7 @@ netcoreapp3.1 true + true + false diff --git a/SOURCES/roslyn-no-apphost.patch b/SOURCES/roslyn-no-apphost.patch index b2511f9..f1767c7 100644 --- a/SOURCES/roslyn-no-apphost.patch +++ b/SOURCES/roslyn-no-apphost.patch @@ -1,125 +1,10 @@ -Index: a/src/Interactive/csi/csi.csproj -=================================================================== ---- a/src/Interactive/csi/csi.csproj -+++ b/src/Interactive/csi/csi.csproj -@@ -6,6 +6,7 @@ +--- a/src/Workspaces/Remote/ServiceHub.CoreComponents/Microsoft.CodeAnalysis.Remote.ServiceHub.CoreComponents.csproj ++++ b/src/Workspaces/Remote/ServiceHub.CoreComponents/Microsoft.CodeAnalysis.Remote.ServiceHub.CoreComponents.csproj +@@ -5,6 +5,7 @@ Exe - CSharpInteractive - netcoreapp3.1;net472 -+ false - - - -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Interactive/vbi/vbi.vbproj -=================================================================== ---- a/src/Interactive/vbi/vbi.vbproj -+++ b/src/Interactive/vbi/vbi.vbproj -@@ -7,6 +7,7 @@ - Sub Main - netcoreapp3.1;net472 - -+ false - - - -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/CSharpSyntaxGenerator.csproj -=================================================================== ---- a/src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/CSharpSyntaxGenerator.csproj -+++ b/src/Tools/Source/CompilerGeneratorTools/Source/CSharpSyntaxGenerator/CSharpSyntaxGenerator.csproj -@@ -14,6 +14,7 @@ - $(RoslynPortableRuntimeIdentifiers) - false - false -+ false - - - -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/PrepareTests/PrepareTests.csproj -=================================================================== ---- a/src/Tools/PrepareTests/PrepareTests.csproj -+++ b/src/Tools/PrepareTests/PrepareTests.csproj -@@ -7,6 +7,7 @@ - false - false - false -+ false - - - -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator/CompilersBoundTreeGenerator.csproj -=================================================================== ---- a/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator/CompilersBoundTreeGenerator.csproj -+++ b/src/Tools/Source/CompilerGeneratorTools/Source/BoundTreeGenerator/CompilersBoundTreeGenerator.csproj -@@ -11,8 +11,9 @@ - True netcoreapp3.1 - false + + false + false - - -- -\ No newline at end of file -+ -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/CSharpErrorFactsGenerator/CSharpErrorFactsGenerator.csproj -=================================================================== ---- a/src/Tools/Source/CompilerGeneratorTools/Source/CSharpErrorFactsGenerator/CSharpErrorFactsGenerator.csproj -+++ b/src/Tools/Source/CompilerGeneratorTools/Source/CSharpErrorFactsGenerator/CSharpErrorFactsGenerator.csproj -@@ -10,5 +10,6 @@ - True - netcoreapp3.1 - false -+ false - -- -\ No newline at end of file -+ -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/IOperationGenerator/CompilersIOperationGenerator.csproj -=================================================================== ---- a/src/Tools/Source/CompilerGeneratorTools/Source/IOperationGenerator/CompilersIOperationGenerator.csproj -+++ b/src/Tools/Source/CompilerGeneratorTools/Source/IOperationGenerator/CompilersIOperationGenerator.csproj -@@ -8,5 +8,6 @@ - True - net5.0 - false -+ false - - -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicErrorFactsGenerator/VisualBasicErrorFactsGenerator.vbproj -=================================================================== ---- a/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicErrorFactsGenerator/VisualBasicErrorFactsGenerator.vbproj -+++ b/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicErrorFactsGenerator/VisualBasicErrorFactsGenerator.vbproj -@@ -12,5 +12,6 @@ - True - netcoreapp3.1 - false -+ false - -- -\ No newline at end of file -+ -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicSyntaxGenerator/VisualBasicSyntaxGenerator.vbproj -=================================================================== ---- a/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicSyntaxGenerator/VisualBasicSyntaxGenerator.vbproj -+++ b/src/Tools/Source/CompilerGeneratorTools/Source/VisualBasicSyntaxGenerator/VisualBasicSyntaxGenerator.vbproj -@@ -13,6 +13,7 @@ - True - netcoreapp3.1 - false -+ false - - - -Index: roslyn.dae39045cd460ba44053ff2af2217da126c25dbf/src/Tools/Source/RunTests/RunTests.csproj -=================================================================== ---- a/src/Tools/Source/RunTests/RunTests.csproj -+++ b/src/Tools/Source/RunTests/RunTests.csproj -@@ -7,6 +7,7 @@ - true - false - false -+ false - - - diff --git a/SOURCES/roslyn-no-shared-compilation.patch b/SOURCES/roslyn-no-shared-compilation.patch deleted file mode 100644 index 2c1f7c0..0000000 --- a/SOURCES/roslyn-no-shared-compilation.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: source-build-tarball/src/roslyn.2cb3d482e3c09760d1b204c597be93f49dba3349/eng/targets/Settings.props -=================================================================== ---- a/eng/targets/Settings.props -+++ b/eng/targets/Settings.props -@@ -39,6 +39,8 @@ - Microsoft.Common.CurrentVersion.targets to see how it is consumed --> - false - -+ false -+ - false - enable - diff --git a/SOURCES/runtime-bigendian-ilasm-pdb.patch b/SOURCES/runtime-bigendian-ilasm-pdb.patch deleted file mode 100644 index 00c31ec..0000000 --- a/SOURCES/runtime-bigendian-ilasm-pdb.patch +++ /dev/null @@ -1,80 +0,0 @@ -Index: a/src/coreclr/ilasm/writer.cpp -=================================================================== ---- a/src/coreclr/ilasm/writer.cpp -+++ b/src/coreclr/ilasm/writer.cpp -@@ -212,26 +212,28 @@ HRESULT Assembler::CreateDebugDirectory( - param.debugDirData = NULL; - - // get module ID -- DWORD rsds = 0x53445352; -- DWORD pdbAge = 0x1; -+ DWORD rsds = VAL32(0x53445352); -+ DWORD pdbAge = VAL32(0x1); -+ GUID pdbGuid = *m_pPortablePdbWriter->GetGuid(); -+ SwapGuid(&pdbGuid); - DWORD len = sizeof(rsds) + sizeof(GUID) + sizeof(pdbAge) + (DWORD)strlen(m_szPdbFileName) + 1; - BYTE* dbgDirData = new BYTE[len]; - - DWORD offset = 0; - memcpy_s(dbgDirData + offset, len, &rsds, sizeof(rsds)); // RSDS - offset += sizeof(rsds); -- memcpy_s(dbgDirData + offset, len, m_pPortablePdbWriter->GetGuid(), sizeof(GUID)); // PDB GUID -+ memcpy_s(dbgDirData + offset, len, &pdbGuid, sizeof(GUID)); // PDB GUID - offset += sizeof(GUID); - memcpy_s(dbgDirData + offset, len, &pdbAge, sizeof(pdbAge)); // PDB AGE - offset += sizeof(pdbAge); - memcpy_s(dbgDirData + offset, len, m_szPdbFileName, strlen(m_szPdbFileName) + 1); // PDB PATH - - debugDirIDD.Characteristics = 0; -- debugDirIDD.TimeDateStamp = m_pPortablePdbWriter->GetTimestamp(); -- debugDirIDD.MajorVersion = 0x100; -- debugDirIDD.MinorVersion = 0x504d; -- debugDirIDD.Type = IMAGE_DEBUG_TYPE_CODEVIEW; -- debugDirIDD.SizeOfData = len; -+ debugDirIDD.TimeDateStamp = VAL32(m_pPortablePdbWriter->GetTimestamp()); -+ debugDirIDD.MajorVersion = VAL16(0x100); -+ debugDirIDD.MinorVersion = VAL16(0x504d); -+ debugDirIDD.Type = VAL32(IMAGE_DEBUG_TYPE_CODEVIEW); -+ debugDirIDD.SizeOfData = VAL32(len); - debugDirIDD.AddressOfRawData = 0; // will be updated bellow - debugDirIDD.PointerToRawData = 0; // will be updated bellow - -Index: a/src/coreclr/md/enc/pdbheap.cpp -=================================================================== ---- a/src/coreclr/md/enc/pdbheap.cpp -+++ b/src/coreclr/md/enc/pdbheap.cpp -@@ -26,6 +26,16 @@ HRESULT PdbHeap::SetData(PORT_PDB_STREAM - (sizeof(ULONG) * data->typeSystemTableRowsSize); - m_data = new BYTE[m_size]; - -+#if BIGENDIAN -+ PORT_PDB_STREAM swappedData = *data; -+ SwapGuid(&swappedData.id.pdbGuid); -+ swappedData.id.pdbTimeStamp = VAL32(swappedData.id.pdbTimeStamp); -+ swappedData.entryPoint = VAL32(swappedData.entryPoint); -+ swappedData.referencedTypeSystemTables = VAL64(swappedData.referencedTypeSystemTables); -+ // typeSystemTableRows and typeSystemTableRowsSize handled below -+ data = &swappedData; -+#endif -+ - ULONG offset = 0; - if (memcpy_s(m_data + offset, m_size, &data->id, sizeof(data->id))) - return E_FAIL; -@@ -39,9 +49,17 @@ HRESULT PdbHeap::SetData(PORT_PDB_STREAM - return E_FAIL; - offset += sizeof(data->referencedTypeSystemTables); - -+#if !BIGENDIAN - if (memcpy_s(m_data + offset, m_size, data->typeSystemTableRows, sizeof(ULONG) * data->typeSystemTableRowsSize)) - return E_FAIL; - offset += sizeof(ULONG) * data->typeSystemTableRowsSize; -+#else -+ for (int i = 0; i < data->typeSystemTableRowsSize; i++) -+ { -+ SET_UNALIGNED_VAL32(m_data + offset, data->typeSystemTableRows[i]); -+ offset += sizeof(ULONG); -+ } -+#endif - - _ASSERTE(offset == m_size); - diff --git a/SOURCES/runtime-mono-memfunc-cgroup.patch b/SOURCES/runtime-mono-memfunc-cgroup.patch deleted file mode 100644 index b4c8fba..0000000 --- a/SOURCES/runtime-mono-memfunc-cgroup.patch +++ /dev/null @@ -1,755 +0,0 @@ -Index: a/src/mono/mono/utils/memfuncs.c -=================================================================== ---- a/src/mono/mono/utils/memfuncs.c -+++ b/src/mono/mono/utils/memfuncs.c -@@ -343,6 +343,9 @@ mono_determine_physical_ram_available_si - host_page_size (host, &page_size); - return (guint64) vmstat.free_count * page_size; - -+#elif defined (__FreeBSD__) || defined (__linux__) || defined (__APPLE__) -+ return (getPhysicalMemoryAvail()); -+ - #elif defined (HAVE_SYSCONF) - gint64 page_size = -1, num_pages = -1; - -Index: a/src/mono/mono/utils/memfuncs.h -=================================================================== ---- a/src/mono/mono/utils/memfuncs.h -+++ b/src/mono/mono/utils/memfuncs.h -@@ -24,5 +24,10 @@ MONO_COMPONENT_API void mono_gc_memmove_ - void mono_gc_memmove_aligned (void *dest, const void *src, size_t size); - guint64 mono_determine_physical_ram_size (void); - guint64 mono_determine_physical_ram_available_size (void); -+#if defined (__FreeBSD__) || defined (__linux__) || defined (__APPLE__) -+size_t getRestrictedPhysicalMemoryLimit(void); -+gboolean getPhysicalMemoryUsed(size_t *); -+size_t getPhysicalMemoryAvail(void); -+#endif - - #endif -Index: a/src/mono/mono/utils/mono-cgroup.c -=================================================================== ---- /dev/null -+++ b/src/mono/mono/utils/mono-cgroup.c -@@ -0,0 +1,709 @@ -+// Licensed to the .NET Foundation under one or more agreements. -+// The .NET Foundation licenses this file to you under the MIT license. -+ -+/*++ -+ -+Module Name: -+ -+ mono-cgroup.cpp -+ -+Abstract: -+ Read the memory limit for the current process -+--*/ -+#ifdef __FreeBSD__ -+#define _WITH_GETLINE -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if defined(__APPLE__) || defined(__FreeBSD__) -+#include -+#include -+#else -+#include -+#endif -+#include -+#include -+ -+#ifndef SIZE_T_MAX -+# define SIZE_T_MAX (~(size_t)0) -+#endif -+ -+#define CGROUP2_SUPER_MAGIC 0x63677270 -+#define TMPFS_MAGIC 0x01021994 -+ -+#define PROC_MOUNTINFO_FILENAME "/proc/self/mountinfo" -+#define PROC_CGROUP_FILENAME "/proc/self/cgroup" -+#define PROC_STATM_FILENAME "/proc/self/statm" -+#define CGROUP1_MEMORY_LIMIT_FILENAME "/memory.limit_in_bytes" -+#define CGROUP2_MEMORY_LIMIT_FILENAME "/memory.max" -+#define CGROUP_MEMORY_STAT_FILENAME "/memory.stat" -+ -+static void initialize(void); -+static gboolean readMemoryValueFromFile(const char *, guint64 *); -+static gboolean getPhysicalMemoryLimit(guint64 *); -+static gboolean getPhysicalMemoryUsage(size_t *); -+static int findCGroupVersion(void); -+static gboolean isCGroup1MemorySubsystem(const char *); -+static char *findCGroupPath(gboolean (*is_subsystem)(const char *)); -+static void findHierarchyMount(gboolean (*is_subsystem)(const char *), char **, char **); -+static char *findCGroupPathForSubsystem(gboolean (*is_subsystem)(const char *)); -+static gboolean getCGroupMemoryLimit(guint64 *, const char *); -+static gboolean getCGroupMemoryUsage(size_t *); -+static size_t getPhysicalMemoryTotal(guint64); -+ -+size_t getRestrictedPhysicalMemoryLimit(void); -+gboolean getPhysicalMemoryUsed(size_t *); -+size_t getPhysicalMemoryAvail(void); -+ -+// the cgroup version number or 0 to indicate cgroups are not found or not enabled -+static int s_cgroup_version; -+ -+static char *s_memory_cgroup_path = NULL; -+ -+static const char *s_mem_stat_key_names[4]; -+static size_t s_mem_stat_key_lengths[4]; -+static size_t s_mem_stat_n_keys = 0; -+static long pageSize; -+ -+/** -+ * @initialize -+ * -+ * Initialize variables used by the calculation routines. -+ */ -+static void -+initialize() -+{ -+ s_cgroup_version = findCGroupVersion(); -+ s_memory_cgroup_path = findCGroupPath(s_cgroup_version == 1 ? &isCGroup1MemorySubsystem : NULL); -+ -+ if (s_cgroup_version == 1) { -+ s_mem_stat_n_keys = 4; -+ s_mem_stat_key_names[0] = "total_inactive_anon "; -+ s_mem_stat_key_names[1] = "total_active_anon "; -+ s_mem_stat_key_names[2] = "total_dirty "; -+ s_mem_stat_key_names[3] = "total_unevictable "; -+ } else { -+ s_mem_stat_n_keys = 3; -+ s_mem_stat_key_names[0] = "anon "; -+ s_mem_stat_key_names[1] = "file_dirty "; -+ s_mem_stat_key_names[2] = "unevictable "; -+ } -+ -+ for (size_t i = 0; i < s_mem_stat_n_keys; i++) -+ s_mem_stat_key_lengths[i] = strlen(s_mem_stat_key_names[i]); -+ -+ pageSize = sysconf(_SC_PAGE_SIZE); -+} -+ -+/** -+ * @readMemoryValueFromFile -+ * -+ * @param[in] filename - name of file containing value -+ * @param[out] val - pointer to the result area -+ * @returns True or False depending if value was found -+ * -+ * Read a value from a specified /sys/fs/cgroup/memory file -+ */ -+static gboolean -+readMemoryValueFromFile(const char* filename, guint64* val) -+{ -+ gboolean result = FALSE; -+ char *line = NULL; -+ size_t lineLen = 0; -+ char *endptr = NULL; -+ guint64 num = 0, multiplier; -+ FILE *file = NULL; -+ -+ if (val == NULL) { -+ file = fopen(filename, "r"); -+ if (file != NULL) { -+ if (getline(&line, &lineLen, file) != -1) { -+ errno = 0; -+ num = strtoull(line, &endptr, 0); -+ if (line != endptr && errno == 0) { -+ multiplier = 1; -+ -+ switch (*endptr) -+ { -+ case 'g': -+ case 'G': -+ multiplier = 1024; -+ case 'm': -+ case 'M': -+ multiplier = multiplier * 1024; -+ case 'k': -+ case 'K': -+ multiplier = multiplier * 1024; -+ } -+ -+ *val = num * multiplier; -+ result = TRUE; -+ if (*val / multiplier != num) -+ result = FALSE; -+ } -+ } -+ } -+ } -+ -+ if (file) -+ fclose(file); -+ free(line); -+ return result; -+} -+ -+/** -+ * @getPhysicalMemoryLimit -+ * -+ * @param[out] val - pointer to the result area -+ * @returns True or False depending if a limit was found -+ * -+ * Interrogate the cgroup memory values to determine if there's -+ * a limit on physical memory. -+ */ -+static gboolean -+getPhysicalMemoryLimit(guint64 *val) -+{ -+ if (s_mem_stat_n_keys == 0) -+ initialize(); -+ -+ if (s_cgroup_version == 0) -+ return FALSE; -+ else if (s_cgroup_version == 1) -+ return getCGroupMemoryLimit(val, CGROUP1_MEMORY_LIMIT_FILENAME); -+ else if (s_cgroup_version == 2) -+ return getCGroupMemoryLimit(val, CGROUP2_MEMORY_LIMIT_FILENAME); -+ else { -+ g_assert(!"Unknown cgroup version."); -+ return FALSE; -+ } -+} -+ -+/** -+ * @getPhysicalMemoryUsage -+ * -+ * @param[out] val - pointer to the result area -+ * @returns True or False depending if a usage value was found -+ * -+ * Interrogate the cgroup memory values to determine how much -+ * memory is in use. -+ */ -+static gboolean -+getPhysicalMemoryUsage(size_t *val) -+{ -+ if (s_cgroup_version == 0) -+ return FALSE; -+ else if (s_cgroup_version == 1) -+ return getCGroupMemoryUsage(val); -+ else if (s_cgroup_version == 2) -+ return getCGroupMemoryUsage(val); -+ else { -+ g_assert(!"Unknown cgroup version."); -+ return FALSE; -+ } -+} -+ -+/** -+ * @findGroupVersion -+ * -+ * @returns cgroup version -+ * -+ * Inspect the /sys/fs/cgroup hierachy to determine what version of -+ * group we are using -+ */ -+static int -+findCGroupVersion() -+{ -+ // It is possible to have both cgroup v1 and v2 enabled on a system. -+ // Most non-bleeding-edge Linux distributions fall in this group. We -+ // look at the file system type of /sys/fs/cgroup to determine which -+ // one is the default. For more details, see: -+ // https://systemd.io/CGROUP_DELEGATION/#three-different-tree-setups- -+ // We dont care about the difference between the "legacy" and "hybrid" -+ // modes because both of those involve cgroup v1 controllers managing -+ // resources. -+ -+ -+ struct statfs stats; -+ int result = statfs("/sys/fs/cgroup", &stats); -+ if (result != 0) -+ return 0; -+ -+ switch (stats.f_type) { -+ case TMPFS_MAGIC: return 1; -+ case CGROUP2_SUPER_MAGIC: return 2; -+ default: -+ g_assert(!"Unexpected file system type for /sys/fs/cgroup"); -+ return 0; -+ } -+} -+ -+/** -+ * @isCGroup1MemorySubsystem -+ * -+ * @param[in] strTok - Token for comparison -+ * @returns True if token matches "memory" -+ * -+ * Check if we've found the memory component of /sys/fs/cgroup -+ */ -+static gboolean -+isCGroup1MemorySubsystem(const char *strTok) -+{ -+ return strcmp("memory", strTok) == 0; -+} -+ -+/** -+ * @findCGroupPath -+ * -+ * @param[in] is_subsystem - Function used to compare tokens -+ * @returns Path to cgroup -+ * -+ * Navigate the /sys/fs/cgroup to try and find the correct cgroup path -+ */ -+static char * -+findCGroupPath(gboolean (*is_subsystem)(const char *)) -+{ -+ char *cgroup_path = NULL; -+ char *hierarchy_mount = NULL; -+ char *hierarchy_root = NULL; -+ char *cgroup_path_relative_to_mount = NULL; -+ size_t common_path_prefix_len; -+ -+ findHierarchyMount(is_subsystem, &hierarchy_mount, &hierarchy_root); -+ if (hierarchy_mount != NULL && hierarchy_root != NULL) { -+ -+ cgroup_path_relative_to_mount = findCGroupPathForSubsystem(is_subsystem); -+ if (cgroup_path_relative_to_mount != NULL) { -+ -+ cgroup_path = (char*)malloc(strlen(hierarchy_mount) + strlen(cgroup_path_relative_to_mount) + 1); -+ if (cgroup_path != NULL) { -+ -+ strcpy(cgroup_path, hierarchy_mount); -+ // For a host cgroup, we need to append the relative path. -+ // The root and cgroup path can share a common prefix of the path that should not be appended. -+ // Example 1 (docker): -+ // hierarchy_mount: /sys/fs/cgroup/cpu -+ // hierarchy_root: /docker/87ee2de57e51bc75175a4d2e81b71d162811b179d549d6601ed70b58cad83578 -+ // cgroup_path_relative_to_mount: /docker/87ee2de57e51bc75175a4d2e81b71d162811b179d549d6601ed70b58cad83578/my_named_cgroup -+ // append do the cgroup_path: /my_named_cgroup -+ // final cgroup_path: /sys/fs/cgroup/cpu/my_named_cgroup -+ // -+ // Example 2 (out of docker) -+ // hierarchy_mount: /sys/fs/cgroup/cpu -+ // hierarchy_root: / -+ // cgroup_path_relative_to_mount: /my_named_cgroup -+ // append do the cgroup_path: /my_named_cgroup -+ // final cgroup_path: /sys/fs/cgroup/cpu/my_named_cgroup -+ common_path_prefix_len = strlen(hierarchy_root); -+ if ((common_path_prefix_len == 1) || -+ (strncmp(hierarchy_root, cgroup_path_relative_to_mount, common_path_prefix_len) != 0)) -+ common_path_prefix_len = 0; -+ -+ g_assert((cgroup_path_relative_to_mount[common_path_prefix_len] == '/') || -+ (cgroup_path_relative_to_mount[common_path_prefix_len] == '\0')); -+ -+ strcat(cgroup_path, cgroup_path_relative_to_mount + common_path_prefix_len); -+ } -+ } -+ } -+ -+ free(hierarchy_mount); -+ free(hierarchy_root); -+ free(cgroup_path_relative_to_mount); -+ return cgroup_path; -+} -+ -+/** -+ * @findHierarchyMount -+ * -+ * @param[in] is_subsystem - Comparison function -+ * @param[out] pmountpath - -+ * @param[out] pmountroot - -+ * -+ * Check the /proc filesystem to determine the root and mount path of /sys/fs/cgroup data -+ */ -+static void -+findHierarchyMount(gboolean (*is_subsystem)(const char *), char** pmountpath, char** pmountroot) -+{ -+ char *line = NULL; -+ size_t lineLen = 0, maxLineLen = 0; -+ char *filesystemType = NULL; -+ char *options = NULL; -+ char *mountpath = NULL; -+ char *mountroot = NULL; -+ -+ FILE *mountinfofile = fopen(PROC_MOUNTINFO_FILENAME, "r"); -+ if (mountinfofile == NULL) -+ goto done; -+ -+ while (getline(&line, &lineLen, mountinfofile) != -1) { -+ if (filesystemType == NULL || lineLen > maxLineLen) { -+ free(filesystemType); -+ filesystemType = NULL; -+ free(options); -+ options = NULL; -+ filesystemType = (char*)malloc(lineLen+1); -+ if (filesystemType == NULL) -+ goto done; -+ options = (char*)malloc(lineLen+1); -+ if (options == NULL) -+ goto done; -+ maxLineLen = lineLen; -+ } -+ -+ char *separatorChar = strstr(line, " - "); -+ -+ // See man page of proc to get format for /proc/self/mountinfo file -+ int sscanfRet = sscanf(separatorChar, -+ " - %s %*s %s", -+ filesystemType, -+ options); -+ if (sscanfRet != 2) { -+ g_assert(!"Failed to parse mount info file contents with sscanf."); -+ goto done; -+ } -+ -+ if (strncmp(filesystemType, "cgroup", 6) == 0) { -+ gboolean isSubsystemMatch = is_subsystem == NULL; -+ if (!isSubsystemMatch) { -+ char *context = NULL; -+ char *strTok = strtok_r(options, ",", &context); -+ while (!isSubsystemMatch && strTok != NULL) -+ { -+ isSubsystemMatch = is_subsystem(strTok); -+ strTok = strtok_r(NULL, ",", &context); -+ } -+ } -+ if (isSubsystemMatch) { -+ mountpath = (char*)malloc(lineLen+1); -+ if (mountpath == NULL) -+ goto done; -+ mountroot = (char*)malloc(lineLen+1); -+ if (mountroot == NULL) -+ goto done; -+ -+ sscanfRet = sscanf(line, -+ "%*s %*s %*s %s %s ", -+ mountroot, -+ mountpath); -+ if (sscanfRet != 2) -+ g_assert(!"Failed to parse mount info file contents with sscanf."); -+ -+ // assign the output arguments and clear the locals so we don't free them. -+ *pmountpath = mountpath; -+ *pmountroot = mountroot; -+ mountpath = mountroot = NULL; -+ } -+ } -+ } -+done: -+ free(mountpath); -+ free(mountroot); -+ free(filesystemType); -+ free(options); -+ free(line); -+ if (mountinfofile) -+ fclose(mountinfofile); -+} -+ -+/** -+ * @findCGroupPathForSubsystem -+ * -+ * @param[in] is_subsystem - Comparison function -+ * @returns cgroup path for the memory subsystem -+ * -+ * Check the /proc filesystem to determine the root and mount path of /sys/fs/cgroup data -+ */ -+static char * -+findCGroupPathForSubsystem(gboolean (*is_subsystem)(const char *)) -+{ -+ char *line = NULL; -+ size_t lineLen = 0; -+ size_t maxLineLen = 0; -+ char *subsystem_list = NULL; -+ char *cgroup_path = NULL; -+ gboolean result = FALSE; -+ -+ FILE *cgroupfile = fopen(PROC_CGROUP_FILENAME, "r"); -+ if (cgroupfile == NULL) -+ goto done; -+ -+ while (!result && getline(&line, &lineLen, cgroupfile) != -1) { -+ if (subsystem_list == NULL || lineLen > maxLineLen) { -+ free(subsystem_list); -+ subsystem_list = NULL; -+ free(cgroup_path); -+ cgroup_path = NULL; -+ subsystem_list = (char*)malloc(lineLen+1); -+ if (subsystem_list == NULL) -+ goto done; -+ cgroup_path = (char*)malloc(lineLen+1); -+ if (cgroup_path == NULL) -+ goto done; -+ maxLineLen = lineLen; -+ } -+ -+ if (s_cgroup_version == 1) { -+ // See man page of proc to get format for /proc/self/cgroup file -+ int sscanfRet = sscanf(line, -+ "%*[^:]:%[^:]:%s", -+ subsystem_list, -+ cgroup_path); -+ if (sscanfRet != 2) { -+ g_assert(!"Failed to parse cgroup info file contents with sscanf."); -+ goto done; -+ } -+ -+ char* context = NULL; -+ char* strTok = strtok_r(subsystem_list, ",", &context); -+ while (strTok != NULL) { -+ if (is_subsystem(strTok)) { -+ result = TRUE; -+ break; -+ } -+ strTok = strtok_r(NULL, ",", &context); -+ } -+ } else if (s_cgroup_version == 2) { -+ // See https://www.kernel.org/doc/Documentation/cgroup-v2.txt -+ // Look for a "0::/some/path" -+ int sscanfRet = sscanf(line, -+ "0::%s", -+ cgroup_path); -+ if (sscanfRet == 1) -+ { -+ result = TRUE; -+ } -+ } else { -+ g_assert(!"Unknown cgroup version in mountinfo."); -+ goto done; -+ } -+ } -+done: -+ free(subsystem_list); -+ if (!result) { -+ free(cgroup_path); -+ cgroup_path = NULL; -+ } -+ free(line); -+ if (cgroupfile) -+ fclose(cgroupfile); -+ return cgroup_path; -+} -+ -+/** -+ * @getCGroupMemoryLimit -+ * -+ * @param[out] val - Memory limit -+ * @param[in] filename - name of file from which to extract limit -+ * @returns True if value found -+ * -+ * Extract memory limit from specified /sys/fs/cgroup/memory file -+ */ -+static gboolean -+getCGroupMemoryLimit(guint64 *val, const char *filename) -+{ -+ if (s_memory_cgroup_path == NULL) -+ return FALSE; -+ -+ char* mem_limit_filename = NULL; -+ if (asprintf(&mem_limit_filename, "%s%s", s_memory_cgroup_path, filename) < 0) -+ return FALSE; -+ -+ gboolean result = readMemoryValueFromFile(mem_limit_filename, val); -+ free(mem_limit_filename); -+ return result; -+} -+ -+/** -+ * @getCGroupMemoryUsage -+ * -+ * @param[out] val - Memory limit -+ * @returns True if value found -+ * -+ * Extract memory usage from /sys/fs/cgroup/memory.stat file -+ */ -+static gboolean -+getCGroupMemoryUsage(size_t *val) -+{ -+ if (s_memory_cgroup_path == NULL) -+ return FALSE; -+ -+ char *stat_filename = NULL; -+ if (asprintf(&stat_filename, "%s%s", s_memory_cgroup_path, CGROUP_MEMORY_STAT_FILENAME) < 0) -+ return FALSE; -+ -+ FILE *stat_file = fopen(stat_filename, "r"); -+ free(stat_filename); -+ if (stat_file == NULL) -+ return FALSE; -+ -+ char *line = NULL; -+ size_t lineLen = 0; -+ size_t readValues = 0; -+ char *endptr; -+ -+ *val = 0; -+ while (getline(&line, &lineLen, stat_file) != -1 && readValues < s_mem_stat_n_keys) { -+ for (size_t i = 0; i < s_mem_stat_n_keys; i++) { -+ if (strncmp(line, s_mem_stat_key_names[i], s_mem_stat_key_lengths[i]) == 0) { -+ errno = 0; -+ const char *startptr = line + s_mem_stat_key_lengths[i]; -+ *val += strtoll(startptr, &endptr, 10); -+ if (endptr != startptr && errno == 0) -+ readValues++; -+ -+ break; -+ } -+ } -+ } -+ -+ fclose(stat_file); -+ free(line); -+ -+ if (readValues == s_mem_stat_n_keys) -+ return TRUE; -+ -+ return FALSE; -+} -+ -+/** -+ * @getRestrictedPhysicalMemoryLimit -+ * -+ * @returns Physical memory limit -+ * -+ * Determine if there are any limits on memory and return the value -+ * if so. Zero represents no limit. -+ */ -+size_t -+getRestrictedPhysicalMemoryLimit() -+{ -+ guint64 physical_memory_limit = 0; -+ -+ if (s_mem_stat_n_keys == 0) -+ initialize(); -+ -+ if (!getPhysicalMemoryLimit(&physical_memory_limit)) -+ return 0; -+ -+ // If there's no memory limit specified on the container this -+ // actually returns 0x7FFFFFFFFFFFF000 (2^63-1 rounded down to -+ // 4k which is a common page size). So we know we are not -+ // running in a memory restricted environment. -+ if (physical_memory_limit > 0x7FFFFFFF00000000) -+ return 0; -+ -+ return (getPhysicalMemoryTotal(physical_memory_limit)); -+} -+ -+/** -+ * @getPhysicalMemoryTotal -+ * -+ * @param[in] physical_memory_limit - The max memory on the system -+ * @returns Physical memory total -+ * -+ * Check the input limit against any system limits or actual memory on system -+ */ -+static size_t -+getPhysicalMemoryTotal(size_t physical_memory_limit) -+{ -+ struct rlimit curr_rlimit; -+ size_t rlimit_soft_limit = (size_t)RLIM_INFINITY; -+ if (getrlimit(RLIMIT_AS, &curr_rlimit) == 0) -+ rlimit_soft_limit = curr_rlimit.rlim_cur; -+ physical_memory_limit = (physical_memory_limit < rlimit_soft_limit) ? -+ physical_memory_limit : rlimit_soft_limit; -+ -+ // Ensure that limit is not greater than real memory size -+ long pages = sysconf(_SC_PHYS_PAGES); -+ if (pages != -1) { -+ if (pageSize != -1) { -+ physical_memory_limit = (physical_memory_limit < (size_t)pages * pageSize) ? -+ physical_memory_limit : (size_t)pages * pageSize; -+ } -+ } -+ -+ if (physical_memory_limit > ULONG_MAX) { -+ // It is observed in practice when the memory is unrestricted, Linux control -+ // group returns a physical limit that is bigger than the address space -+ return ULONG_MAX; -+ } else -+ return (size_t)physical_memory_limit; -+} -+ -+/** -+ * @getPhysicalMemoryUsed -+ * -+ * @param[out] val - pointer to the memory usage value -+ * @returns True if we are able to determine usage -+ * -+ * Determine the amount of memory in use -+ */ -+gboolean -+getPhysicalMemoryUsed(size_t *val) -+{ -+ gboolean result = FALSE; -+ size_t linelen; -+ char *line = NULL; -+ -+ if (val == NULL) -+ return FALSE; -+ -+ // Linux uses cgroup usage to trigger oom kills. -+ if (getPhysicalMemoryUsage(val)) -+ return TRUE; -+ -+ // process resident set size. -+ FILE* file = fopen(PROC_STATM_FILENAME, "r"); -+ if (file != NULL && getline(&line, &linelen, file) != -1) { -+ char* context = NULL; -+ char* strTok = strtok_r(line, " ", &context); -+ strTok = strtok_r(NULL, " ", &context); -+ -+ errno = 0; -+ *val = strtoull(strTok, NULL, 0); -+ if (errno == 0) { -+ if (pageSize != -1) { -+ *val = *val * pageSize; -+ result = TRUE; -+ } -+ } -+ } -+ -+ if (file) -+ fclose(file); -+ free(line); -+ return result; -+} -+ -+/** -+ * @getPhysicalMemoryAvail -+ * -+ * @returns Amount of memory available -+ * -+ * Determine the amount of memory available by examininig any limits and -+ * checking what memory is in use. -+ */ -+size_t -+getPhysicalMemoryAvail() -+{ -+ size_t max, used, avail, sysAvail; -+ -+ max = getRestrictedPhysicalMemoryLimit(); -+ -+ if (max == 0) -+ max = getPhysicalMemoryTotal(ULONG_MAX); -+ -+ if (getPhysicalMemoryUsed(&used)) -+ avail = max - used; -+ else -+ avail = max; -+ -+ sysAvail = sysconf(_SC_AVPHYS_PAGES) * pageSize; -+ return (avail < sysAvail ? avail : sysAvail); -+} -Index: a/src/mono/mono/utils/CMakeLists.txt -=================================================================== ---- a/src/mono/mono/utils/CMakeLists.txt -+++ b/src/mono/mono/utils/CMakeLists.txt -@@ -32,6 +32,7 @@ set(utils_common_sources - mono-sha1.c - mono-logger.c - mono-logger-internals.h -+ mono-cgroup.c - mono-codeman.c - mono-counters.c - mono-compiler.h diff --git a/SOURCES/runtime-mono-remove-ilstrip.patch b/SOURCES/runtime-mono-remove-ilstrip.patch new file mode 100644 index 0000000..9a711f8 --- /dev/null +++ b/SOURCES/runtime-mono-remove-ilstrip.patch @@ -0,0 +1,33 @@ +diff --git a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj +index 724b704f864..3dabdc81dae 100644 +--- a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj ++++ b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Microsoft.NET.Runtime.MonoTargets.Sdk.pkgproj +@@ -6,7 +6,7 @@ + + + +- ++ + + + +@@ -15,7 +15,7 @@ + + + +- ++ + + + +diff --git a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props +index 8a7ede79242..cfd515eeca9 100644 +--- a/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props ++++ b/src/mono/nuget/Microsoft.NET.Runtime.MonoTargets.Sdk/Sdk/Sdk.props +@@ -1,5 +1,5 @@ + +- ++ + + + diff --git a/SOURCES/runtime-no-shared-compilation.patch b/SOURCES/runtime-no-shared-compilation.patch deleted file mode 100644 index fefe89e..0000000 --- a/SOURCES/runtime-no-shared-compilation.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: source-build-tarball/src/runtime.826f81a11ad17f415668fe1cb934bdaf00d36ea2/Directory.Build.props -=================================================================== ---- a/Directory.Build.props -+++ b/Directory.Build.props -@@ -7,6 +7,7 @@ - For offline builds we still set OfficialBuildId but we need to build all the packages for a single - leg only, so we also take DotNetBuildFromSource into account. --> - true -+ false - - - diff --git a/SOURCES/sdk-enable-preview.patch b/SOURCES/sdk-enable-preview.patch deleted file mode 100644 index 7a452a2..0000000 --- a/SOURCES/sdk-enable-preview.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/eng/SourceBuild.props -+++ b/eng/SourceBuild.props -@@ -8,6 +8,7 @@ - - - $(InnerBuildArgs) /p:Projects="$(InnerSourceBuildRepoRoot)\source-build.slnf" -+ $(InnerBuildArgs) /p:EnablePreviewFeatures=true - - - diff --git a/SOURCES/source-build-reference-packages-no-shared-compilation.patch b/SOURCES/source-build-reference-packages-no-shared-compilation.patch deleted file mode 100644 index b2932d9..0000000 --- a/SOURCES/source-build-reference-packages-no-shared-compilation.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: a/src/Directory.Build.props -=================================================================== ---- a/src/Directory.Build.props -+++ b/src/Directory.Build.props -@@ -9,6 +9,7 @@ - - true - true -+ false -