Skip to content

Commit

Permalink
Fixes for high CPU counts
Browse files Browse the repository at this point in the history
Allow any number of build threads.

Use _SC_NPROCESSORS_ONLN to find online CPUs only:

Some Linux kernels are configured to allow "CPU hotswap" which means
they pretend to have some huge array (128) of CPUs that might come
online. This is weird. If we ask for the number of online CPUs that
should be a saner value.

std::thread::hardware_concurrency() has the same issue, I think it uses the total
count, which seems like a pretty bad bug in itself but outside the scope
of this project.
  • Loading branch information
deplinenoise committed Aug 4, 2024
1 parent e48e03b commit 3bb6133
Show file tree
Hide file tree
Showing 8 changed files with 17 additions and 29 deletions.
14 changes: 6 additions & 8 deletions src/BuildQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,15 +735,10 @@ namespace t2
queue->m_ExpensiveWaitCount = 0;
queue->m_ExpensiveWaitList = HeapAllocateArray<NodeState*>(heap, capacity);

CHECK(queue->m_Queue);

if (queue->m_Config.m_ThreadCount > kMaxBuildThreads)
{
Log(kWarning, "too many build threads (%d) - clamping to %d",
queue->m_Config.m_ThreadCount, kMaxBuildThreads);
queue->m_Threads = HeapAllocateArrayZeroed<ThreadId>(config->m_Heap, config->m_ThreadCount);
queue->m_ThreadState = HeapAllocateArrayZeroed<ThreadState>(config->m_Heap, config->m_ThreadCount);

queue->m_Config.m_ThreadCount = kMaxBuildThreads;
}
CHECK(queue->m_Queue);

Log(kDebug, "build queue initialized; ring buffer capacity = %u", queue->m_QueueCapacity);

Expand Down Expand Up @@ -797,6 +792,9 @@ namespace t2
CondDestroy(&queue->m_WorkAvailable);
MutexDestroy(&queue->m_Lock);

HeapFree(config->m_Heap, queue->m_ThreadState);
HeapFree(config->m_Heap, queue->m_Threads);

// Unblock all signals on the main thread.
SignalHandlerSetCondition(nullptr);
SignalBlockThread(false);
Expand Down
9 changes: 2 additions & 7 deletions src/BuildQueue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ namespace t2
struct StatCache;
struct DigestCache;

enum
{
kMaxBuildThreads = 64
};

struct BuildQueueConfig
{
enum
Expand Down Expand Up @@ -73,8 +68,8 @@ namespace t2
int32_t m_PendingNodeCount;
int32_t m_FailedNodeCount;
int32_t m_CurrentPassIndex;
ThreadId m_Threads[kMaxBuildThreads];
ThreadState m_ThreadState[kMaxBuildThreads];
ThreadId *m_Threads;
ThreadState *m_ThreadState;
int32_t m_ExpensiveRunning;
int32_t m_ExpensiveWaitCount;
NodeState **m_ExpensiveWaitList;
Expand Down
8 changes: 1 addition & 7 deletions src/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@
#include <sys/sysctl.h>
#endif

#if defined(TUNDRA_LINUX)
#include <thread>
#endif

#if defined(TUNDRA_WIN32)
#include <windows.h>
#include <ctype.h>
Expand Down Expand Up @@ -346,9 +342,7 @@ int GetCpuCount()
GetSystemInfo(&si);
return (int) si.dwNumberOfProcessors;
#elif defined(TUNDRA_LINUX)
return (int)std::thread::hardware_concurrency();
#else
long nprocs_max = sysconf(_SC_NPROCESSORS_CONF);
long nprocs_max = sysconf(_SC_NPROCESSORS_ONLN);
if (nprocs_max < 0)
CroakErrno("couldn't get CPU count");
return (int) nprocs_max;
Expand Down
2 changes: 1 addition & 1 deletion src/Exec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace t2
bool m_WasSignalled;
};

void ExecInit(void);
void ExecInit(int thread_count);

ExecResult ExecuteProcess(
const char* cmd_line,
Expand Down
2 changes: 1 addition & 1 deletion src/ExecUnix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static void SetFdNonBlocking(int fd)
CroakErrno("couldn't unblock fd %d", fd);
}

void ExecInit(void)
void ExecInit(int thread_count)
{
TerminalIoInit();
}
Expand Down
5 changes: 3 additions & 2 deletions src/ExecWin32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static char s_TemporaryDir[MAX_PATH];
static DWORD s_TundraPid;
static Mutex s_FdMutex;

static HANDLE s_TempFiles[kMaxBuildThreads];
static HANDLE *s_TempFiles;

static HANDLE AllocFd(int job_id)
{
Expand Down Expand Up @@ -176,8 +176,9 @@ static char UTF8_WindowsEnvironment[128*1024];

static size_t g_Win32EnvCount;

void ExecInit(void)
void ExecInit(int thread_count)
{
s_TempFiles = (HANDLE*) calloc(thread_count, sizeof s_TempFiles[0]);
s_TundraPid = GetCurrentProcessId();

if (0 == GetTempPathA(sizeof(s_TemporaryDir), s_TemporaryDir))
Expand Down
4 changes: 2 additions & 2 deletions src/Hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ void HashAddStringFoldCase(HashState* self, const char* path)
char c = *path++;
if (c == 0)
return;
c = FoldCase(c);
HashUpdate(self, &c, 1);
c = FoldCase(c);
HashUpdate(self, &c, 1);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ int main(int argc, char* argv[])

uint64_t start_time = TimerGet();

ExecInit();
ExecInit(options.m_ThreadCount);

if (options.m_WorkingDir)
{
Expand Down

0 comments on commit 3bb6133

Please sign in to comment.