@joebigelow / wix / commits / fb769130

Moved CalculateCabbingThreadCount() to BindDatabaseCommand because we need the capped value in both CreateCabinetsCommand and UpdateFileFacadesCommand.

Fixed bug in capping the thread count between 1 and processor count times 2. The "-ct 1000000" value was wrongly passed thru in the test CabinetFilesSequencedCorrectly Added ThreadCount to UpdateFileFacadesCommand

Martin Broholm Andersen committed Aug 31, 2024 at 12:23 UTC fb769130df465bca45c520c27baf85343881ef14
3 files changed +35 -31
src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+28 -3
@@ -105,6 +105,29 @@ namespace WixToolset.Core.WindowsInstaller.Bind
105
106 private CancellationToken CancellationToken { get; }
107
108 + private int CalculateCabbingThreadCount()
109 + {
110 + var processorCount = Environment.ProcessorCount;
111 +
112 + // If the number of processors is invalid, default to a single processor.
113 + if (processorCount == 0)
114 + {
115 + processorCount = 1;
116 +
117 + this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), processorCount.ToString()));
118 + }
119 +
120 + // If the cabbing thread count was provided, and it isn't more than double the number of processors, use it.
121 + if (0 < this.CabbingThreadCount && this.CabbingThreadCount < processorCount * 2)
122 + {
123 + processorCount = this.CabbingThreadCount;
124 + }
125 +
126 + this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(processorCount.ToString()));
127 +
128 + return processorCount;
129 + }
130 +
131 public IBindResult Execute()
132 {
133 if (!this.Intermediate.HasLevel(Data.IntermediateLevels.Linked) || !this.Intermediate.HasLevel(Data.IntermediateLevels.Resolved))
@@ -123,6 +146,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
146
147 var containsMergeModules = false;
148
149 + int calculatedCabbingThreadCount = this.CalculateCabbingThreadCount();
150 +
151 // Load standard tables, authored custom tables, and extension custom tables.
152 TableDefinitionCollection tableDefinitions;
153 {
@@ -280,7 +305,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
305
306 // Gather information about files that do not come from merge modules.
307 {
283 - var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, fileFacadesFromIntermediate, variableCache, overwriteHash: true, this.CancellationToken);
308 + var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, fileFacadesFromIntermediate, variableCache, overwriteHash: true, this.CancellationToken, calculatedCabbingThreadCount);
309 command.Execute();
310 }
311
@@ -324,7 +349,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
349 {
350 var updatedFacades = reresolvedFiles.Select(f => allFileFacades.First(ff => ff.Id == f.Id?.Id));
351
327 - var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, updatedFacades, variableCache, overwriteHash: false, this.CancellationToken);
352 + var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, updatedFacades, variableCache, overwriteHash: false, this.CancellationToken, calculatedCabbingThreadCount);
353 command.Execute();
354 }
355 }
@@ -442,7 +467,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
467 {
468 this.Messaging.Write(VerboseMessages.CreatingCabinetFiles());
469
445 - var command = new CreateCabinetsCommand(this.ServiceProvider, this.Messaging, this.WindowsInstallerBackendHelper, this.BackendExtensions, section, this.CabCachePath, this.CabbingThreadCount, this.OutputPath, this.IntermediateFolder, this.DefaultCompressionLevel, compressed, modularizationSuffix, filesByCabinetMedia, data, tableDefinitions, this.ResolveMedia);
470 + var command = new CreateCabinetsCommand(this.ServiceProvider, this.Messaging, this.WindowsInstallerBackendHelper, this.BackendExtensions, section, this.CabCachePath, calculatedCabbingThreadCount, this.OutputPath, this.IntermediateFolder, this.DefaultCompressionLevel, compressed, modularizationSuffix, filesByCabinetMedia, data, tableDefinitions, this.ResolveMedia);
471 command.Execute();
472
473 fileTransfers.AddRange(command.FileTransfers);
src/wix/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+1 -26
@@ -83,11 +83,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
83
84 public void Execute()
85 {
86 - var calculatedCabbingThreadCount = this.CalculateCabbingThreadCount();
87 -
86 this.GetMediaTemplateAttributes(out var maximumCabinetSizeForLargeFileSplitting, out var maximumUncompressedMediaSize);
87
90 - var cabinetBuilder = new CabinetBuilder(this.Messaging, calculatedCabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize);
88 + var cabinetBuilder = new CabinetBuilder(this.Messaging, this.CabbingThreadCount, maximumCabinetSizeForLargeFileSplitting, maximumUncompressedMediaSize);
89
90 var hashesByFileId = this.Section.Symbols.OfType<MsiFileHashSymbol>().ToDictionary(s => s.Id.Id);
91
@@ -122,29 +120,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
120 this.UpdateMediaWithSpannedCabinets(cabinetBuilder.CompletedCabinets);
121 }
122
125 - private int CalculateCabbingThreadCount()
126 - {
127 - var processorCount = Environment.ProcessorCount;
128 -
129 - // If the number of processors is invalid, default to a single processor.
130 - if (processorCount == 0)
131 - {
132 - processorCount = 1;
133 -
134 - this.Messaging.Write(WarningMessages.InvalidEnvironmentVariable("NUMBER_OF_PROCESSORS", Environment.ProcessorCount.ToString(), processorCount.ToString()));
135 - }
136 -
137 - // If the cabbing thread count was provided, and it isn't more than double the number of processors, use it.
138 - if (this.CabbingThreadCount > 0 && processorCount < this.CabbingThreadCount * 2)
139 - {
140 - processorCount = this.CabbingThreadCount;
141 - }
142 -
143 - this.Messaging.Write(VerboseMessages.SetCabbingThreadCount(processorCount.ToString()));
144 -
145 - return processorCount;
146 - }
147 -
123 private CabinetWorkItem CreateCabinetWorkItem(WindowsInstallerData data, string cabinetDir, MediaSymbol mediaSymbol, CompressionLevel compressionLevel, IEnumerable<IFileFacade> fileFacades, Dictionary<string, MsiFileHashSymbol> hashesByFileId)
124 {
125 CabinetWorkItem cabinetWorkItem = null;
src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
+6 -2
@@ -22,7 +22,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
22 /// </summary>
23 internal class UpdateFileFacadesCommand
24 {
25 - public UpdateFileFacadesCommand(IMessaging messaging, IFileSystem fileSystem, IntermediateSection section, IEnumerable<IFileFacade> allFileFacades, IEnumerable<IFileFacade> updateFileFacades, IDictionary<string, string> variableCache, bool overwriteHash, CancellationToken cancellationToken)
25 + public UpdateFileFacadesCommand(IMessaging messaging, IFileSystem fileSystem, IntermediateSection section, IEnumerable<IFileFacade> allFileFacades, IEnumerable<IFileFacade> updateFileFacades, IDictionary<string, string> variableCache, bool overwriteHash, CancellationToken cancellationToken, int threadCount)
26 {
27 this.Messaging = messaging;
28 this.FileSystem = fileSystem;
@@ -32,6 +32,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
32 this.VariableCache = variableCache;
33 this.OverwriteHash = overwriteHash;
34 this.CancellationToken = cancellationToken;
35 + this.ThreadCount = threadCount;
36 }
37
38 private IMessaging Messaging { get; }
@@ -50,6 +51,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
51
52 private CancellationToken CancellationToken { get; }
53
54 + private int ThreadCount { get; }
55 +
56 public void Execute()
57 {
58 try
@@ -74,7 +77,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
77
78 Parallel.ForEach(facades,
79 new ParallelOptions{
77 - CancellationToken = this.CancellationToken
80 + CancellationToken = this.CancellationToken,
81 + MaxDegreeOfParallelism = this.ThreadCount
82 },
83 () =>
84 {