Skip to content

Use semaphoreslim in incremental builder #14904

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 29, 2023
Merged
4 changes: 4 additions & 0 deletions src/Compiler/Facilities/BuildGraph.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ type NodeCode =

static member Parallel: computations: (NodeCode<'T> seq) -> NodeCode<'T[]>

static member AwaitTask: task: Task<'T> -> NodeCode<'T>

static member AwaitTask: task: Task -> NodeCode<unit>

/// Execute the cancellable computation synchronously using the ambient cancellation token of
/// the NodeCode.
static member FromCancellable: computation: Cancellable<'T> -> NodeCode<'T>
Expand Down
20 changes: 13 additions & 7 deletions src/Compiler/Service/IncrementalBuild.fs
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ type FrameworkImportsCache(size) =
lazyWork
)
node


/// This function strips the "System" assemblies from the tcConfig and returns a age-cached TcImports for them.
member this.Get(tcConfig: TcConfig) =
Expand Down Expand Up @@ -1248,19 +1249,24 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc
let t2 = MaxTimeStampInDependencies state.logicalStampedFileNames fileSlot
max t1 t2

let gate = obj()
let semaphore = new SemaphoreSlim(1,1)

let mutable currentState = state

let setCurrentState state cache (ct: CancellationToken) =
lock gate (fun () ->
ct.ThrowIfCancellationRequested()
currentState <- computeStampedFileNames initialState state cache
)
node {
do! semaphore.WaitAsync(ct) |> NodeCode.AwaitTask
try
ct.ThrowIfCancellationRequested()
currentState <- computeStampedFileNames initialState state cache
finally
semaphore.Release() |> ignore
}

let checkFileTimeStamps (cache: TimeStampCache) =
node {
let! ct = NodeCode.CancellationToken
setCurrentState currentState cache ct
do! setCurrentState currentState cache ct
}

do IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBECreated)
Expand Down Expand Up @@ -1443,7 +1449,7 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc
let newState = { currentState with notifiedStampedFileNames = currentState.notifiedStampedFileNames.SetItem(slotOfFile, timeStamp) }
let cache = TimeStampCache defaultTimeStamp
let! ct = NodeCode.CancellationToken
setCurrentState newState cache ct
do! setCurrentState newState cache ct
}

member _.SourceFiles = fileNames |> Seq.map (fun f -> f.Source.FilePath) |> List.ofSeq
Expand Down