Index: clangd/TUScheduler.cpp =================================================================== --- clangd/TUScheduler.cpp +++ clangd/TUScheduler.cpp @@ -634,13 +634,22 @@ } // unlock Mutex { - // FIXME: only emit this status when the Barrier couldn't be acquired. - emitTUStatus({TUAction::Queued, Req.Name}); - std::lock_guard BarrierLock(Barrier); - WithContext Guard(std::move(Req.Ctx)); - trace::Span Tracer(Req.Name); - emitTUStatus({TUAction::RunningAction, Req.Name}); - Req.Action(); + auto ExecuteAction = [&]() { + WithContext Guard(std::move(Req.Ctx)); + trace::Span Tracer(Req.Name); + emitTUStatus({TUAction::RunningAction, Req.Name}); + Req.Action(); + }; + std::unique_lock Lock(Barrier, std::try_to_lock); + if (Lock.owns_lock()) { + ExecuteAction(); + } else { + emitTUStatus({TUAction::Queued, Req.Name}); + { + std::lock_guard BarrierLock(Barrier); + ExecuteAction(); + } + } } bool IsEmpty = false; Index: clangd/Threading.h =================================================================== --- clangd/Threading.h +++ clangd/Threading.h @@ -42,6 +42,7 @@ public: Semaphore(std::size_t MaxLocks); + bool try_lock(); void lock(); void unlock(); Index: clangd/Threading.cpp =================================================================== --- clangd/Threading.cpp +++ clangd/Threading.cpp @@ -28,6 +28,15 @@ Semaphore::Semaphore(std::size_t MaxLocks) : FreeSlots(MaxLocks) {} +bool Semaphore::try_lock() { + std::unique_lock Lock(Mutex); + if (FreeSlots > 0) { + --FreeSlots; + return true; + } + return false; +} + void Semaphore::lock() { trace::Span Span("WaitForFreeSemaphoreSlot"); // trace::Span can also acquire locks in ctor and dtor, we make sure it Index: unittests/clangd/TUSchedulerTests.cpp =================================================================== --- unittests/clangd/TUSchedulerTests.cpp +++ unittests/clangd/TUSchedulerTests.cpp @@ -698,13 +698,11 @@ EXPECT_THAT(CaptureTUStatus.AllStatus, ElementsAre( // Statuses of "Update" action. - TUState(TUAction::Queued, "Update"), TUState(TUAction::RunningAction, "Update"), TUState(TUAction::BuildingPreamble, "Update"), TUState(TUAction::BuildingFile, "Update"), // Statuses of "Definitions" action - TUState(TUAction::Queued, "Definitions"), TUState(TUAction::RunningAction, "Definitions"), TUState(TUAction::Idle, /*No action*/ ""))); }