#pragma once #ifndef _WIN32 #include #include #include #endif #include #include #include #include #include #include #include namespace c10d { namespace test { class Semaphore { public: void post(int n = 1) { std::unique_lock lock(m_); n_ += n; cv_.notify_all(); } void wait(int n = 1) { std::unique_lock lock(m_); while (n_ < n) { cv_.wait(lock); } n_ -= n; } protected: int n_ = 0; std::mutex m_; std::condition_variable cv_; }; #ifdef _WIN32 std::string autoGenerateTmpFilePath() { char tmp[L_tmpnam_s]; errno_t err; err = tmpnam_s(tmp, L_tmpnam_s); if (err != 0) { throw std::system_error(errno, std::system_category()); } return std::string(tmp); } std::string tmppath() { const char* tmpfile = getenv("TMPFILE"); if (tmpfile) { return std::string(tmpfile); } else { return autoGenerateTmpFilePath(); } } #else std::string tmppath() { // TMPFILE is for manual test execution during which the user will specify // the full temp file path using the environmental variable TMPFILE const char* tmpfile = getenv("TMPFILE"); if (tmpfile) { return std::string(tmpfile); } const char* tmpdir = getenv("TMPDIR"); if (tmpdir == nullptr) { tmpdir = "/tmp"; } // Create template std::vector tmp(256); auto len = snprintf(tmp.data(), tmp.size(), "%s/testXXXXXX", tmpdir); tmp.resize(len); // Create temporary file auto fd = mkstemp(&tmp[0]); if (fd == -1) { throw std::system_error(errno, std::system_category()); } close(fd); return std::string(tmp.data(), tmp.size()); } #endif bool isTSANEnabled() { auto s = std::getenv("PYTORCH_TEST_WITH_TSAN"); return s && strcmp(s, "1") == 0; } struct TemporaryFile { std::string path; TemporaryFile() { path = tmppath(); } ~TemporaryFile() { unlink(path.c_str()); } }; #ifndef _WIN32 struct Fork { pid_t pid; Fork() { pid = fork(); if (pid < 0) { throw std::system_error(errno, std::system_category(), "fork"); } } ~Fork() { if (pid > 0) { kill(pid, SIGKILL); waitpid(pid, nullptr, 0); } } bool isChild() { return pid == 0; } }; #endif } // namespace test } // namespace c10d