Files
UnrealEngine/Engine/Source/Programs/UnrealBuildAccelerator/Common/Public/UbaBottleneck.h
2025-05-18 13:04:45 +08:00

81 lines
1.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "UbaEvent.h"
#include "UbaPlatform.h"
#include "UbaSynchronization.h"
#include "UbaTimer.h"
namespace uba
{
struct BottleneckTicket
{
Event ev;
BottleneckTicket* next = nullptr;
};
struct Bottleneck
{
Bottleneck(u32 mc) : m_maxCount(mc) {}
void Enter(BottleneckTicket& ticket, Timer& timer)
{
SCOPED_FUTEX(m_lock, lock);
if (m_activeCount < m_maxCount)
{
UBA_ASSERT(!m_first);
++m_activeCount;
return;
}
if (!m_first)
m_first = &ticket;
else
m_last->next = &ticket;
m_last = &ticket;
if (!ticket.ev.IsCreated())
ticket.ev.Create(true);
lock.Leave();
TimerScope ts(timer);
ticket.ev.IsSet();
}
void Leave(BottleneckTicket& ticket)
{
SCOPED_FUTEX(m_lock, lock);
BottleneckTicket* first = m_first;
if (!first)
{
UBA_ASSERT(m_activeCount > 0);
--m_activeCount;
return;
}
m_first = first->next;
if (!m_first)
m_last = nullptr;
first->ev.Set();
}
private:
Futex m_lock;
BottleneckTicket* m_first = nullptr;
BottleneckTicket* m_last = nullptr;
u32 m_activeCount = 0;
u32 m_maxCount;
};
struct BottleneckScope
{
BottleneckScope(Bottleneck& b, Timer& timer) : bottleneck(b) { b.Enter(ticket, timer); }
~BottleneckScope() { bottleneck.Leave(ticket); }
Bottleneck& bottleneck;
BottleneckTicket ticket;
};
}