From d5673c535ea6ce81e87e891746ac14088aee0184 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Sun, 6 Nov 2022 19:29:57 -0800 Subject: Implement cab thread count Closes 6978 --- .../Bind/CreateCabinetsCommand.cs | 29 ++++++++++++---------- .../WixToolset.Core/CommandLine/BuildCommand.cs | 27 +++++++++++++++++--- .../WixToolsetTest.CoreIntegration/CabFixture.cs | 1 + 3 files changed, 41 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs index 1ed2ba79..bf215623 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs @@ -83,17 +83,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind public void Execute() { - // If the cabbing thread count wasn't provided, default the number of cabbing threads to the number of processors. - if (this.CabbingThreadCount <= 0) - { - this.CabbingThreadCount = this.CalculateCabbingThreadCount(); - - this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(this.CabbingThreadCount.ToString())); - } + var calculatedCabbingThreadCount = this.CalculateCabbingThreadCount(); this.GetMediaTemplateAttributes(out var maximumCabinetSizeForLargeFileSplitting, out var maximumUncompressedMediaSize); - var cabinetBuilder = new CabinetBuilder(this.Messaging, this.CabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize); + var cabinetBuilder = new CabinetBuilder(this.Messaging, calculatedCabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize); var hashesByFileId = this.Section.Symbols.OfType().ToDictionary(s => s.Id.Id); @@ -130,16 +124,25 @@ namespace WixToolset.Core.WindowsInstaller.Bind private int CalculateCabbingThreadCount() { - var cabbingThreadCount = Environment.ProcessorCount; + var processorCount = Environment.ProcessorCount; - if (cabbingThreadCount <= 0) + // If the number of processors is invalid, default to a single processor. + if (processorCount == 0) { - cabbingThreadCount = 1; // reset to 1 when the environment variable is invalid. + processorCount = 1; - this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), cabbingThreadCount.ToString())); + this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), processorCount.ToString())); } - return cabbingThreadCount; + // If the cabbing thread count was provided, and it isn't more than double the number of processors, use it. + if (this.CabbingThreadCount > 0 && processorCount < this.CabbingThreadCount * 2) + { + processorCount = this.CabbingThreadCount; + } + + this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(processorCount.ToString())); + + return processorCount; } private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable fileFacades, Dictionary hashesByFileId) diff --git a/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs b/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs index 4cc2227c..53c4f798 100644 --- a/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs +++ b/src/wix/WixToolset.Core/CommandLine/BuildCommand.cs @@ -52,6 +52,7 @@ namespace WixToolset.Core.CommandLine new CommandLineHelpSwitch("-bindpath:target", "-bt", "Bind path to search for target package's content files. Only used when building a patch."), new CommandLineHelpSwitch("-bindpath:update", "-bu", "Bind path to search for update package's content files. Only used when building a patch."), new CommandLineHelpSwitch("-cabcache", "-cc", "Set a folder to cache cabinets across builds."), + new CommandLineHelpSwitch("-cabthreads", "-ct", "Override the number of threads used to create cabinets."), new CommandLineHelpSwitch("-culture", "Adds a culture to filter localization files."), new CommandLineHelpSwitch("-define", "-d", "Sets a preprocessor variable."), new CommandLineHelpSwitch("-defaultcompressionlevel", "-dcl", "Default compression level; see Compression levels below."), @@ -147,7 +148,7 @@ namespace WixToolset.Core.CommandLine { using (new IntermediateFieldContext("wix.bind")) { - this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.BindPaths, inputsOutputs, cancellationToken); + this.BindPhase(wixipl, wxls, filterCultures, this.commandLine.CabCachePath, this.commandLine.CabbingThreadCount, this.commandLine.BindPaths, inputsOutputs, cancellationToken); } } } @@ -265,7 +266,7 @@ namespace WixToolset.Core.CommandLine return linker.Link(context); } - private void BindPhase(Intermediate output, IReadOnlyCollection localizations, IReadOnlyCollection filterCultures, string cabCachePath, IReadOnlyCollection bindPaths, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken) + private void BindPhase(Intermediate output, IReadOnlyCollection localizations, IReadOnlyCollection filterCultures, string cabCachePath, int cabbingThreadCount, IReadOnlyCollection bindPaths, InputsAndOutputs inputsOutputs, CancellationToken cancellationToken) { IResolveResult resolveResult; { @@ -295,7 +296,7 @@ namespace WixToolset.Core.CommandLine { var context = this.ServiceProvider.GetService(); context.BindPaths = bindPaths; - //context.CabbingThreadCount = this.CabbingThreadCount; + context.CabbingThreadCount = cabbingThreadCount; context.CabCachePath = cabCachePath; context.ResolvedCodepage = resolveResult.Codepage; context.ResolvedSummaryInformationCodepage = resolveResult.SummaryInformationCodepage; @@ -467,6 +468,8 @@ namespace WixToolset.Core.CommandLine public string CabCachePath { get; private set; } + public int CabbingThreadCount { get; private set; } + public List Cultures { get; } = new List(); public List Defines { get; } = new List(); @@ -566,6 +569,24 @@ namespace WixToolset.Core.CommandLine this.CabCachePath = parser.GetNextArgumentOrError(arg); return true; + case "ct": + case "cabthreads": + { + var value = parser.GetNextArgumentOrError(arg); + if (Int32.TryParse(value, out var cabbingThreads)) + { + this.CabbingThreadCount = cabbingThreads; + } + else if (!String.IsNullOrEmpty(value)) + { + var processorCount = Environment.ProcessorCount == 0 ? 1 : Environment.ProcessorCount; + var range = Enumerable.Range(1, processorCount * 2).Select(i => i.ToString()); + parser.ReportErrorArgument(arg, ErrorMessages.IllegalCommandLineArgumentValue(arg, value, range)); + } + + return true; + } + case "culture": parser.GetNextArgumentOrError(arg, this.Cultures); return true; diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs index da1d47df..690937d2 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/CabFixture.cs @@ -28,6 +28,7 @@ namespace WixToolsetTest.CoreIntegration "build", Path.Combine(folder, "Package.wxs"), Path.Combine(folder, "PackageComponents.wxs"), + "-ct", "1000000", "-d", "MediaTemplateCompressionLevel", "-loc", Path.Combine(folder, "Package.en-us.wxl"), "-bindpath", Path.Combine(folder, "data"), -- cgit v1.2.3-55-g6feb