msbuild
msbuild copied to clipboard
Avoid lock when setting project entry point
Context
There's a good amount of contention inside of BuildManager.PendBuildRequest() coming from the lock in the body:
private BuildSubmissionBase<TRequestData, TResultData> PendBuildRequest<TRequestData, TResultData>(
TRequestData requestData)
where TRequestData : BuildRequestData<TRequestData, TResultData>
where TResultData : BuildResultBase
{
lock (_syncLock)
{
ErrorUtilities.VerifyThrowArgumentNull(requestData);
ErrorIfState(BuildManagerState.WaitingForBuildToComplete, "WaitingForEndOfBuild");
ErrorIfState(BuildManagerState.Idle, "NoBuildInProgress");
VerifyStateInternal(BuildManagerState.Building);
var newSubmission = requestData.CreateSubmission(this, GetNextSubmissionId(), requestData,
_buildParameters!.LegacyThreadingSemantics);
if (_buildTelemetry != null)
{
// Project graph can have multiple entry points, for purposes of identifying event for same build project,
// we believe that including only one entry point will provide enough precision.
_buildTelemetry.ProjectPath ??= requestData.EntryProjectsFullPath.FirstOrDefault();
_buildTelemetry.BuildTarget ??= string.Join(",", requestData.TargetNames);
}
_buildSubmissions.Add(newSubmission.SubmissionId, newSubmission);
_noActiveSubmissionsEvent!.Reset();
return newSubmission;
}
}
There's a small amount of CPU time caused by hitting the lock too.
Looks like this can be switched over to use some low-lock patterns to mitigate this. The results after the changes show the contention is essentially eliminated