Skip to content

Commit a20c98e

Browse files
author
Ayden Meng
committed
BaseTools: Cap thread count to avoid file descriptor exhaustion
When the number of build threads multiplied by per-thread file descriptor usage exceeds the system's open file descriptor limit, some threads may fail to acquire necessary resources (e.g., pipes or semaphores), leading to deadlocks or hangs during parallel builds. To prevent this situation, calculate the safety upper limit of concurrency by dividing the system's maximum file descriptor limit by 4 (multi-processing pipelines use three file descriptors, and POSIX named semaphores use one file descriptor). The actual thread count is then clamped to this safe value. This ensures stable parallel builds even under constrained resource limits. Signed-off-by: Ayden Meng <[email protected]>
1 parent 31d5b37 commit a20c98e

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

BaseTools/Source/Python/build/build.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import traceback
2626
import multiprocessing
2727
import errno
28+
import resource
2829
from threading import Thread,Event,BoundedSemaphore
2930
import threading
3031
from linecache import getlines
@@ -838,13 +839,15 @@ def StartAutoGen(self,mqueue, DataPipe,SkipAutoGen,PcdMaList,cqueue):
838839
try:
839840
if SkipAutoGen:
840841
return True,0
842+
soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
841843
feedback_q = mp.Queue()
842844
error_event = mp.Event()
843845
FfsCmd = DataPipe.Get("FfsCommand")
844846
if FfsCmd is None:
845847
FfsCmd = {}
846848
GlobalData.FfsCmd = FfsCmd
847-
auto_workers = [AutoGenWorkerInProcess(mqueue,DataPipe.dump_file,feedback_q,GlobalData.file_lock,cqueue,self.log_q,error_event) for _ in range(self.ThreadNumber)]
849+
850+
auto_workers = [AutoGenWorkerInProcess(mqueue,DataPipe.dump_file,feedback_q,GlobalData.file_lock,cqueue,self.log_q,error_event) for _ in range(min(self.ThreadNumber, soft // 4))]
848851
self.AutoGenMgr = AutoGenManager(auto_workers,feedback_q,error_event)
849852
self.AutoGenMgr.start()
850853
for w in auto_workers:

0 commit comments

Comments
 (0)