Browse Source

logging thread

feature/dependency-graph
Martin Dørum 3 years ago
parent
commit
1125d2f2b6
6 changed files with 91 additions and 10 deletions
  1. 2
    2
      Makefile
  2. 2
    1
      src/SourceFile.cc
  3. 54
    0
      src/logger.cc
  4. 15
    0
      src/logger.h
  5. 5
    2
      src/main.cc
  6. 13
    5
      src/sys.cc

+ 2
- 2
Makefile View File

@@ -1,8 +1,8 @@
SRCS = \
src/BBBParser.cc src/SourceFile.cc src/toolchain.cc src/globals.cc \
src/sys.cc src/parallel.cc src/main.cc
src/logger.cc src/sys.cc src/parallel.cc src/main.cc
HDRS = src/BBBParser.h src/SourceFile.h src/toolchain.h src/globals.h \
src/sys.h src/parallel.h
src/logger.h src/sys.h src/parallel.h
BUILD = build
OBJS = $(patsubst %,$(BUILD)/%.o,$(SRCS))
CFLAGS = -g -Wall -Wextra -Wno-unused-parameter

+ 2
- 1
src/SourceFile.cc View File

@@ -6,6 +6,7 @@
#include <string.h>

#include "toolchain.h"
#include "logger.h"

static bool startsWith(BBBParser &parser, const char *str) {
for (size_t i = 0; str[i] != '\0'; ++i) {
@@ -166,7 +167,7 @@ bool SourceFile::needsRecompile(const std::string &outDir) const {
void SourceFile::compile(const std::string &outDir) const {
// TODO: Send this as a message to some printer thread instead,
// because this happens in multiple threads
std::cerr << "Compile " << objectPath(outDir) << '\n';
logger::log("Compile " + objectPath(outDir));
toolchain::compile(compileFlags(), type_, dir_, name_, outDir);

// Nothing will need compile flags after it's compiled, so no reason to

+ 54
- 0
src/logger.cc View File

@@ -0,0 +1,54 @@
#include "logger.h"

#include <mutex>
#include <vector>
#include <condition_variable>
#include <thread>
#include <iostream>
#include <atomic>

namespace logger {

static std::vector<std::string> queue;
static std::mutex mut;
static std::condition_variable cond;
static std::thread thread;
static std::atomic_bool running;

static void print(const std::string &msg) {
std::cerr << msg << '\n';
}

LogContext::~LogContext() {
running.store(false);
cond.notify_one();
thread.join();
}

void log(std::string msg) {
std::unique_lock<std::mutex> lock(mut);
queue.emplace_back(std::move(msg));
lock.unlock();
cond.notify_one();
}

LogContext init() {
running = true;

thread = std::thread([&] {
std::unique_lock<std::mutex> lock(mut);
while (running.load()) {
cond.wait(lock, [&] { return !queue.empty() || !running.load(); });

for (std::string &msg: queue) {
print(msg);
}

queue.clear();
}
});

return LogContext{};
}

}

+ 15
- 0
src/logger.h View File

@@ -0,0 +1,15 @@
#pragma once

#include <string>

namespace logger {

struct LogContext {
~LogContext();
};

void log(std::string msg);

LogContext init();

}

+ 5
- 2
src/main.cc View File

@@ -16,6 +16,7 @@
#include "parallel.h"
#include "toolchain.h"
#include "globals.h"
#include "logger.h"

static void readDir(std::string dir, std::vector<SourceFile> &sources,
BBBParser::Variables vars);
@@ -113,7 +114,7 @@ static void link(
const std::vector<SourceFile> &sources,
const std::string &outDir, const std::string &name,
toolchain::TargetType targetType) {
std::cerr << "Link " << outDir << '/' << name << '\n';
logger::log("Link " + outDir + '/' + name);

std::vector<std::string> ldFlags;
std::unordered_set<std::string> ldFlagsSet;
@@ -175,6 +176,8 @@ static bool compileAndLink(
}

int main(int argc, char **argv) {
logger::LogContext logCtx = logger::init();

std::vector<std::string> srcDirs;
std::string outDir = "bbbuild";
int jobs = parallel::coreCount();
@@ -301,7 +304,7 @@ int main(int argc, char **argv) {
case Action::BUILD:
// TODO: Support more types than BINARY
if (!compileAndLink(sources, outDir, jobs, target, toolchain::TargetType::BINARY)) {
std::cerr << "Nothing to do.\n";
logger::log("Nothing to do.\n");
}
break;


+ 13
- 5
src/sys.cc View File

@@ -10,6 +10,7 @@
#include <stdexcept>

#include "globals.h"
#include "logger.h"

namespace sys {

@@ -51,14 +52,16 @@ void mkdirp(const std::string &path) {

void execute(std::vector<const char *> &args, std::string *output) {
if (global::verbose) {
std::string str;
for (size_t i = 0; i < args.size(); ++i) {
if (i == 0) {
fprintf(stderr, " %s", args[i]);
str += " ";
} else {
fprintf(stderr, " %s", args[i]);
str += " ";
}
str += args[i];
}
fprintf(stderr, "\n");
logger::log(str);
}

// argv[0] should be interpreted as a shell command, because being able to run
@@ -90,6 +93,9 @@ void execute(std::vector<const char *> &args, std::string *output) {
perror(argv[0]);
abort();
}

// This shouldn't happen
exit(0);
} else if (child < 0) {
throw std::runtime_error(std::string("fork: ") + strerror(errno));
}
@@ -104,13 +110,15 @@ void execute(std::vector<const char *> &args, std::string *output) {
ssize_t num = read(fds[0], buf, sizeof(buf) - 1);
if (num < 0 && errno != EAGAIN) {
close(fds[0]);
throw std::runtime_error(std::string("read: ") + strerror(errno));
throw std::runtime_error(
std::string("read: ") + strerror(errno) +
" (fd: " + std::to_string(fds[0]) + ")");
} else if (num < 0) {
continue;
}

if (num == 0) {
close(fds[1]);
close(fds[0]);
break;
}


Loading…
Cancel
Save