Skip to content

Commit

Permalink
Implement parallelism singleton (#901)
Browse files Browse the repository at this point in the history
  • Loading branch information
ken-matsui authored Feb 1, 2024
1 parent 033184b commit 937ed79
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 37 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ $(O)/tests/test_BuildConfig: $(O)/tests/test_BuildConfig.o \
$(O)/Logger.o $(O)/TermColor.o $(O)/Manifest.o \
$(O)/Semver.o $(O)/Algos.o $(O)/VersionReq.o $(O)/Git2/Repository.o \
$(O)/Git2/Object.o $(O)/Git2/Oid.o $(O)/Git2/Global.o $(O)/Git2/Config.o \
$(O)/Git2/Exception.o $(O)/Git2/Commit.o $(O)/Git2/Time.o
$(O)/Git2/Exception.o $(O)/Git2/Commit.o $(O)/Git2/Time.o $(O)/Parallel.o
$(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@

$(O)/tests/test_Algos: $(O)/tests/test_Algos.o $(O)/Logger.o \
Expand Down
25 changes: 12 additions & 13 deletions src/BuildConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Git2.hpp"
#include "Logger.hpp"
#include "Manifest.hpp"
#include "Parallel.hpp"
#include "TermColor.hpp"

#include <algorithm>
Expand Down Expand Up @@ -641,12 +642,10 @@ processSrc(
}

static HashSet<String>
processSources(
BuildConfig& config, const Vec<Path>& sourceFilePaths, const bool isParallel
) {
processSources(BuildConfig& config, const Vec<Path>& sourceFilePaths) {
HashSet<String> buildObjTargets;

if (isParallel) {
if (isParallel()) {
tbb::spin_mutex mtx;
tbb::parallel_for(
tbb::blocked_range<usize>(0, sourceFilePaths.size()),
Expand Down Expand Up @@ -721,7 +720,7 @@ processTestSrc(
}

static BuildConfig
configureBuild(const bool isDebug, const bool isParallel) {
configureBuild(const bool isDebug) {
if (!fs::exists("src")) {
throw PoacError("src directory not found");
}
Expand Down Expand Up @@ -755,7 +754,7 @@ configureBuild(const bool isDebug, const bool isParallel) {

// Source Pass
const HashSet<String> buildObjTargets =
processSources(config, sourceFilePaths, isParallel);
processSources(config, sourceFilePaths);

// Project binary target.
const String mainObjTarget = config.buildOutDir / "main.o";
Expand All @@ -770,7 +769,7 @@ configureBuild(const bool isDebug, const bool isParallel) {
// Test Pass
Vec<String> testCommands;
HashSet<String> testTargets;
if (isParallel) {
if (isParallel()) {
tbb::spin_mutex mtx;
tbb::parallel_for(
tbb::blocked_range<usize>(0, sourceFilePaths.size()),
Expand Down Expand Up @@ -815,7 +814,7 @@ configureBuild(const bool isDebug, const bool isParallel) {

/// @returns the directory where the Makefile is generated.
String
emitMakefile(const bool isDebug, const bool isParallel) {
emitMakefile(const bool isDebug) {
setOutDir(isDebug);

// When emitting Makefile, we also build the project. So, we need to
Expand All @@ -830,15 +829,15 @@ emitMakefile(const bool isDebug, const bool isParallel) {
}
Logger::debug("Makefile is NOT up to date");

const BuildConfig config = configureBuild(isDebug, isParallel);
const BuildConfig config = configureBuild(isDebug);
std::ofstream ofs(makefilePath);
config.emitMakefile(ofs);
return outDir;
}

/// @returns the directory where the compilation database is generated.
String
emitCompdb(const bool isDebug, const bool isParallel) {
emitCompdb(const bool isDebug) {
setOutDir(isDebug);

// compile_commands.json also needs INCLUDES, but not LIBS.
Expand All @@ -852,7 +851,7 @@ emitCompdb(const bool isDebug, const bool isParallel) {
}
Logger::debug("compile_commands.json is NOT up to date");

const BuildConfig config = configureBuild(isDebug, isParallel);
const BuildConfig config = configureBuild(isDebug);
std::ofstream ofs(compdbPath);
config.emitCompdb(outDir, ofs);
return outDir;
Expand All @@ -864,15 +863,15 @@ modeString(const bool isDebug) {
}

String
getMakeCommand(const bool isParallel) {
getMakeCommand() {
String makeCommand;
if (isVerbose()) {
makeCommand = "make";
} else {
makeCommand = "make -s --no-print-directory Q=@";
}

if (isParallel) {
if (isParallel()) {
const unsigned int numThreads = std::thread::hardware_concurrency();
if (numThreads > 1) {
makeCommand += " -j" + std::to_string(numThreads);
Expand Down
6 changes: 3 additions & 3 deletions src/BuildConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ inline const HashSet<String> HEADER_FILE_EXTS{
};
// clang-format on

String emitMakefile(bool isDebug, bool isParallel);
String emitCompdb(bool isDebug, bool isParallel);
String emitMakefile(bool isDebug);
String emitCompdb(bool isDebug);
String modeString(bool isDebug);
String getMakeCommand(bool isParallel);
String getMakeCommand();
14 changes: 7 additions & 7 deletions src/Cmd/Build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../Algos.hpp"
#include "../BuildConfig.hpp"
#include "../Logger.hpp"
#include "../Parallel.hpp"

#include <chrono>
#include <cstdlib>
Expand All @@ -27,11 +28,11 @@ const Subcmd BUILD_CMD =
.setMainFn(buildMain);

int
buildImpl(String& outDir, const bool isDebug, const bool isParallel) {
buildImpl(String& outDir, const bool isDebug) {
const auto start = std::chrono::steady_clock::now();

outDir = emitMakefile(isDebug, isParallel);
const String makeCommand = getMakeCommand(isParallel) + " -C " + outDir;
outDir = emitMakefile(isDebug);
const String makeCommand = getMakeCommand() + " -C " + outDir;
const int exitCode = execCmd(makeCommand);

const auto end = std::chrono::steady_clock::now();
Expand All @@ -50,7 +51,6 @@ buildMain(const std::span<const StringRef> args) {
// Parse args
bool isDebug = true;
bool buildCompdb = false;
bool isParallel = true;
for (usize i = 0; i < args.size(); ++i) {
const StringRef arg = args[i];
HANDLE_GLOBAL_OPTS({ { "build" } }) // workaround for std::span until C++26
Expand All @@ -65,7 +65,7 @@ buildMain(const std::span<const StringRef> args) {
buildCompdb = true;
}
else if (arg == "--no-parallel") {
isParallel = false;
setParallel(false);
}
else {
return BUILD_CMD.noSuchArg(arg);
Expand All @@ -74,11 +74,11 @@ buildMain(const std::span<const StringRef> args) {

if (!buildCompdb) {
String outDir;
return buildImpl(outDir, isDebug, isParallel);
return buildImpl(outDir, isDebug);
}

// Build compilation database
const String outDir = emitCompdb(isDebug, isParallel);
const String outDir = emitCompdb(isDebug);
Logger::info("Generated", outDir, "/compile_commands.json");
return EXIT_SUCCESS;
}
2 changes: 1 addition & 1 deletion src/Cmd/Build.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
#include "../Rustify.hpp"

extern const Subcmd BUILD_CMD;
int buildImpl(String& outDir, bool isDebug, bool isParallel);
int buildImpl(String& outDir, bool isDebug);
6 changes: 3 additions & 3 deletions src/Cmd/Run.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "../Cli.hpp"
#include "../Logger.hpp"
#include "../Manifest.hpp"
#include "../Parallel.hpp"
#include "../Rustify.hpp"
#include "Build.hpp"

Expand Down Expand Up @@ -34,7 +35,6 @@ static int
runMain(const std::span<const StringRef> args) {
// Parse args
bool isDebug = true;
bool isParallel = true;
usize i = 0;
for (i = 0; i < args.size(); ++i) {
const StringRef arg = args[i];
Expand All @@ -47,7 +47,7 @@ runMain(const std::span<const StringRef> args) {
isDebug = false;
}
else if (arg == "--no-parallel") {
isParallel = false;
setParallel(false);
}
else {
break;
Expand All @@ -60,7 +60,7 @@ runMain(const std::span<const StringRef> args) {
}

String outDir;
if (buildImpl(outDir, isDebug, isParallel) != EXIT_SUCCESS) {
if (buildImpl(outDir, isDebug) != EXIT_SUCCESS) {
return EXIT_FAILURE;
}

Expand Down
9 changes: 4 additions & 5 deletions src/Cmd/Test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../BuildConfig.hpp"
#include "../Cli.hpp"
#include "../Logger.hpp"
#include "../Parallel.hpp"
#include "../Rustify.hpp"

#include <chrono>
Expand All @@ -30,7 +31,6 @@ static int
testMain(const std::span<const StringRef> args) {
// Parse args
bool isDebug = true;
bool isParallel = true;
for (usize i = 0; i < args.size(); ++i) {
const StringRef arg = args[i];
HANDLE_GLOBAL_OPTS({ { "test" } })
Expand All @@ -46,7 +46,7 @@ testMain(const std::span<const StringRef> args) {
isDebug = false;
}
else if (arg == "--no-parallel") {
isParallel = false;
setParallel(false);
}
else {
return TEST_CMD.noSuchArg(arg);
Expand All @@ -55,9 +55,8 @@ testMain(const std::span<const StringRef> args) {

const auto start = std::chrono::steady_clock::now();

const String outDir = emitMakefile(isDebug, isParallel);
const int exitCode =
execCmd(getMakeCommand(isParallel) + " -C " + outDir + " test");
const String outDir = emitMakefile(isDebug);
const int exitCode = execCmd(getMakeCommand() + " -C " + outDir + " test");

const auto end = std::chrono::steady_clock::now();
const std::chrono::duration<double> elapsed = end - start;
Expand Down
8 changes: 4 additions & 4 deletions src/Cmd/Tidy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../BuildConfig.hpp"
#include "../Cli.hpp"
#include "../Logger.hpp"
#include "../Parallel.hpp"
#include "../Rustify.hpp"

#include <chrono>
Expand Down Expand Up @@ -39,7 +40,6 @@ static int
tidyMain(const std::span<const StringRef> args) {
// Parse args
bool fix = false;
bool isParallel = true;
for (usize i = 0; i < args.size(); ++i) {
const StringRef arg = args[i];
HANDLE_GLOBAL_OPTS({ { "tidy" } })
Expand All @@ -48,7 +48,7 @@ tidyMain(const std::span<const StringRef> args) {
fix = true;
}
else if (arg == "--no-parallel") {
isParallel = false;
setParallel(false);
}
else {
return TIDY_CMD.noSuchArg(arg);
Expand All @@ -60,7 +60,7 @@ tidyMain(const std::span<const StringRef> args) {
return EXIT_FAILURE;
}

const Path outDir = emitMakefile(true /* isDebug */, isParallel);
const Path outDir = emitMakefile(true /* isDebug */);

String tidyFlags = " POAC_TIDY_FLAGS='";
if (!isVerbose()) {
Expand All @@ -75,7 +75,7 @@ tidyMain(const std::span<const StringRef> args) {
}
tidyFlags += '\'';

String makeCmd = getMakeCommand(isParallel);
String makeCmd = getMakeCommand();
makeCmd += " -C ";
makeCmd += outDir.string();
makeCmd += tidyFlags;
Expand Down
37 changes: 37 additions & 0 deletions src/Parallel.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "Parallel.hpp"

struct ParallelState {
// ParallelState is a singleton
ParallelState(const ParallelState&) = delete;
ParallelState& operator=(const ParallelState&) = delete;
ParallelState(ParallelState&&) noexcept = delete;
ParallelState& operator=(ParallelState&&) noexcept = delete;
~ParallelState() noexcept = default;

void set(const bool isParallel) noexcept {
state = isParallel;
}
bool get() const noexcept {
return state;
}

static ParallelState& instance() noexcept {
static ParallelState INSTANCE;
return INSTANCE;
}

private:
bool state = true;

ParallelState() noexcept = default;
};

void
setParallel(const bool isParallel) noexcept {
ParallelState::instance().set(isParallel);
}

bool
isParallel() noexcept {
return ParallelState::instance().get();
}
4 changes: 4 additions & 0 deletions src/Parallel.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once

void setParallel(bool isParallel) noexcept;
bool isParallel() noexcept;

0 comments on commit 937ed79

Please sign in to comment.