Jit/threaded_compile.h (70 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) #pragma once #include "Python.h" #include "Jit/ref.h" #include <cassert> #include <mutex> #include <vector> namespace jit { // Threaded-compile state for the whole process. class ThreadedCompileContext { public: void startCompile(std::vector<BorrowedRef<>>&& work_queue) { // Can't use JIT_CHECK because we're included by log.h assert(!compile_running_); work_queue_ = std::move(work_queue); compile_running_ = true; } std::vector<BorrowedRef<>>&& endCompile() { compile_running_ = false; return std::move(retry_list_); } BorrowedRef<> nextUnit() { lock(); if (work_queue_.empty()) { unlock(); return nullptr; } BorrowedRef<> unit = std ::move(work_queue_.back()); work_queue_.pop_back(); unlock(); return unit; } // Assumes we have the lock void retryUnit(BorrowedRef<> unit) { lock(); retry_list_.emplace_back(unit); unlock(); } bool compileRunning() const { return compile_running_; } private: friend class ThreadedCompileSerialize; void lock() { if (compile_running_) { mutex_.lock(); } } void unlock() { if (compile_running_) { mutex_.unlock(); } } bool compile_running_{false}; // This needs to be recursive because we allow recursive compilation via // jit::hir::tryRecursiveCompile std::recursive_mutex mutex_; std::vector<BorrowedRef<>> work_queue_; std::vector<BorrowedRef<>> retry_list_; }; extern ThreadedCompileContext g_threaded_compile_context; // RAII device for acquiring the global threaded-compile lock. class ThreadedCompileSerialize { public: ThreadedCompileSerialize() { g_threaded_compile_context.lock(); } ~ThreadedCompileSerialize() { g_threaded_compile_context.unlock(); } }; // Acquire the global threaded-compile lock for the execution of an expression. #define THREADED_COMPILE_SERIALIZED_CALL(expr) \ ([&]() { \ jit::ThreadedCompileSerialize guard; \ return expr; \ })() } // namespace jit