10b57cec5SDimitry Andric //===-- llvm/Support/Threading.cpp- Control multithreading mode --*- C++ -*-==// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines helper functions for running LLVM in a multi-threaded 100b57cec5SDimitry Andric // environment. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/Support/Threading.h" 15480093f4SDimitry Andric #include "llvm/ADT/Optional.h" 160b57cec5SDimitry Andric #include "llvm/Config/config.h" 170b57cec5SDimitry Andric #include "llvm/Support/Host.h" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric #include <cassert> 200b57cec5SDimitry Andric #include <errno.h> 210b57cec5SDimitry Andric #include <stdlib.h> 220b57cec5SDimitry Andric #include <string.h> 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric using namespace llvm; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 270b57cec5SDimitry Andric //=== WARNING: Implementation here must contain only TRULY operating system 280b57cec5SDimitry Andric //=== independent code. 290b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 300b57cec5SDimitry Andric llvm_is_multithreaded()310b57cec5SDimitry Andricbool llvm::llvm_is_multithreaded() { 320b57cec5SDimitry Andric #if LLVM_ENABLE_THREADS != 0 330b57cec5SDimitry Andric return true; 340b57cec5SDimitry Andric #else 350b57cec5SDimitry Andric return false; 360b57cec5SDimitry Andric #endif 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric #if LLVM_ENABLE_THREADS == 0 || \ 400b57cec5SDimitry Andric (!defined(_WIN32) && !defined(HAVE_PTHREAD_H)) get_threadid()410b57cec5SDimitry Andricuint64_t llvm::get_threadid() { return 0; } 420b57cec5SDimitry Andric get_max_thread_name_length()430b57cec5SDimitry Andricuint32_t llvm::get_max_thread_name_length() { return 0; } 440b57cec5SDimitry Andric set_thread_name(const Twine & Name)450b57cec5SDimitry Andricvoid llvm::set_thread_name(const Twine &Name) {} 460b57cec5SDimitry Andric get_thread_name(SmallVectorImpl<char> & Name)470b57cec5SDimitry Andricvoid llvm::get_thread_name(SmallVectorImpl<char> &Name) { Name.clear(); } 480b57cec5SDimitry Andric get_thread_affinity_mask()495ffd83dbSDimitry Andricllvm::BitVector llvm::get_thread_affinity_mask() { return {}; } 505ffd83dbSDimitry Andric compute_thread_count() const515ffd83dbSDimitry Andricunsigned llvm::ThreadPoolStrategy::compute_thread_count() const { 525ffd83dbSDimitry Andric // When threads are disabled, ensure clients will loop at least once. 535ffd83dbSDimitry Andric return 1; 545ffd83dbSDimitry Andric } 555ffd83dbSDimitry Andric 560b57cec5SDimitry Andric #else 570b57cec5SDimitry Andric 585ffd83dbSDimitry Andric int computeHostNumHardwareThreads(); 590b57cec5SDimitry Andric compute_thread_count() const605ffd83dbSDimitry Andricunsigned llvm::ThreadPoolStrategy::compute_thread_count() const { 615ffd83dbSDimitry Andric int MaxThreadCount = UseHyperThreads ? computeHostNumHardwareThreads() 625ffd83dbSDimitry Andric : sys::getHostNumPhysicalCores(); 635ffd83dbSDimitry Andric if (MaxThreadCount <= 0) 645ffd83dbSDimitry Andric MaxThreadCount = 1; 655ffd83dbSDimitry Andric if (ThreadsRequested == 0) 665ffd83dbSDimitry Andric return MaxThreadCount; 675ffd83dbSDimitry Andric if (!Limit) 685ffd83dbSDimitry Andric return ThreadsRequested; 695ffd83dbSDimitry Andric return std::min((unsigned)MaxThreadCount, ThreadsRequested); 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric // Include the platform-specific parts of this class. 730b57cec5SDimitry Andric #ifdef LLVM_ON_UNIX 740b57cec5SDimitry Andric #include "Unix/Threading.inc" 750b57cec5SDimitry Andric #endif 760b57cec5SDimitry Andric #ifdef _WIN32 770b57cec5SDimitry Andric #include "Windows/Threading.inc" 780b57cec5SDimitry Andric #endif 790b57cec5SDimitry Andric 80*5f7ddb14SDimitry Andric // Must be included after Threading.inc to provide definition for llvm::thread 81*5f7ddb14SDimitry Andric // because FreeBSD's condvar.h (included by user.h) misuses the "thread" 82*5f7ddb14SDimitry Andric // keyword. 83*5f7ddb14SDimitry Andric #include "llvm/Support/thread.h" 84480093f4SDimitry Andric 85*5f7ddb14SDimitry Andric #if defined(__APPLE__) 86*5f7ddb14SDimitry Andric // Darwin's default stack size for threads except the main one is only 512KB, 87*5f7ddb14SDimitry Andric // which is not enough for some/many normal LLVM compilations. This implements 88*5f7ddb14SDimitry Andric // the same interface as std::thread but requests the same stack size as the 89*5f7ddb14SDimitry Andric // main thread (8MB) before creation. 90*5f7ddb14SDimitry Andric const llvm::Optional<unsigned> llvm::thread::DefaultStackSize = 8 * 1024 * 1024; 91*5f7ddb14SDimitry Andric #else 92*5f7ddb14SDimitry Andric const llvm::Optional<unsigned> llvm::thread::DefaultStackSize = None; 93*5f7ddb14SDimitry Andric #endif 94480093f4SDimitry Andric 95480093f4SDimitry Andric 960b57cec5SDimitry Andric #endif 975ffd83dbSDimitry Andric 985ffd83dbSDimitry Andric Optional<ThreadPoolStrategy> get_threadpool_strategy(StringRef Num,ThreadPoolStrategy Default)995ffd83dbSDimitry Andricllvm::get_threadpool_strategy(StringRef Num, ThreadPoolStrategy Default) { 1005ffd83dbSDimitry Andric if (Num == "all") 1015ffd83dbSDimitry Andric return llvm::hardware_concurrency(); 1025ffd83dbSDimitry Andric if (Num.empty()) 1035ffd83dbSDimitry Andric return Default; 1045ffd83dbSDimitry Andric unsigned V; 1055ffd83dbSDimitry Andric if (Num.getAsInteger(10, V)) 1065ffd83dbSDimitry Andric return None; // malformed 'Num' value 1075ffd83dbSDimitry Andric if (V == 0) 1085ffd83dbSDimitry Andric return Default; 1095ffd83dbSDimitry Andric 1105ffd83dbSDimitry Andric // Do not take the Default into account. This effectively disables 1115ffd83dbSDimitry Andric // heavyweight_hardware_concurrency() if the user asks for any number of 1125ffd83dbSDimitry Andric // threads on the cmd-line. 1135ffd83dbSDimitry Andric ThreadPoolStrategy S = llvm::hardware_concurrency(); 1145ffd83dbSDimitry Andric S.ThreadsRequested = V; 1155ffd83dbSDimitry Andric return S; 1165ffd83dbSDimitry Andric } 117