summaryrefslogtreecommitdiff
path: root/src/build.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/build.cc')
-rw-r--r--src/build.cc136
1 files changed, 86 insertions, 50 deletions
diff --git a/src/build.cc b/src/build.cc
index 081c156..5995fb7 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -4,21 +4,20 @@
#include "build.h"
#include <future>
-#include <vector>
#include <iostream>
#include <chrono>
-#include <set>
#include <thread>
#include <list>
+#include <algorithm>
-#include "libctor.h"
+#include "ctor.h"
using namespace std::chrono_literals;
-int build(const Settings& settings,
+int build(const ctor::settings& settings,
const std::string& name,
- const std::set<std::shared_ptr<Task>>& tasks,
- const std::set<std::shared_ptr<Task>>& all_tasks,
+ const std::vector<std::shared_ptr<Task>>& tasks,
+ const std::vector<std::shared_ptr<Task>>& all_tasks,
bool dryrun)
{
if(settings.verbose > 1)
@@ -26,19 +25,20 @@ int build(const Settings& settings,
std::cout << "Building '" << name << "'\n";
}
- std::set<std::shared_ptr<Task>> dirtyTasks;
+ std::vector<std::shared_ptr<Task>> dirtyTasks;
for(auto task : tasks)
{
- if(task->dirty())
+ if(task->dirty() &&
+ std::find(dirtyTasks.begin(), dirtyTasks.end(), task) == dirtyTasks.end())
{
- dirtyTasks.insert(task);
+ dirtyTasks.push_back(task);
}
}
// Dry-run returns number of dirty tasks but otherwise does nothing.
if(dryrun)
{
- return dirtyTasks.size();
+ return static_cast<int>(dirtyTasks.size());
}
if(dirtyTasks.empty())
@@ -65,7 +65,7 @@ int build(const Settings& settings,
break;
}
- auto task = getNextTask(all_tasks, dirtyTasks);
+ auto task = getNextTask(settings, all_tasks, dirtyTasks);
if(task == nullptr)
{
if(processes.empty() && !dirtyTasks.empty())
@@ -84,7 +84,9 @@ int build(const Settings& settings,
return task->run();
}));
started_one = true;
- std::this_thread::sleep_for(2ms);
+ // Make sure we don't start tasks on top of each other to prevent
+ // straining the disk.
+ std::this_thread::sleep_for(50ms);
}
for(auto process = processes.begin();
@@ -106,27 +108,21 @@ int build(const Settings& settings,
break;
}
- if(started_one)
+ if(!started_one) // prevent polling too fast if no task is yet ready
{
- std::this_thread::sleep_for(2ms);
- }
- else
- {
- std::this_thread::sleep_for(200ms);
+ std::this_thread::sleep_for(10ms);
}
}
- for(auto process = processes.begin();
- process != processes.end();
- ++process)
+ for(auto& process : processes)
{
- if(process->valid() == false)
+ if(process.valid() == false)
{
continue;
}
- process->wait();
- auto ret = process->get();
- if(ret != 0)
+ process.wait();
+ auto ret = process.get();
+ if (ret != 0)
{
return ret;
}
@@ -135,30 +131,50 @@ int build(const Settings& settings,
return 0;
}
-namespace
+std::vector<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task,
+ std::vector<std::shared_ptr<Task>> trace)
{
-std::set<std::shared_ptr<Task>> getDepTasks(std::shared_ptr<Task> task)
-{
- std::set<std::shared_ptr<Task>> tasks;
- tasks.insert(task);
+ std::vector<std::shared_ptr<Task>> tasks;
+ tasks.push_back(task);
+ trace.push_back(task);
auto deps = task->getDependsTasks();
for(const auto& dep : deps)
{
- auto depSet = getDepTasks(dep);
- for(const auto& dep : depSet)
+ if(std::find(trace.begin(), trace.end(), dep) != trace.end())
{
- tasks.insert(dep);
+ trace.push_back(dep);
+ std::cerr << "Error: Cyclic dependency detected: ";
+ bool first{true};
+ for(auto t : trace)
+ {
+ if(!first)
+ {
+ std::cerr << " -> ";
+ }
+
+ first = false;
+ std::cerr << t->target();
+ }
+ std::cerr << '\n';
+ throw 1;
+ }
+ auto depSet = getDepTasks(dep, trace);
+ for(const auto& dep_inner : depSet)
+ {
+ if(std::find(tasks.begin(), tasks.end(), dep_inner) == tasks.end())
+ {
+ tasks.push_back(dep_inner);
+ }
}
}
return tasks;
}
-}
-int build(const Settings& settings,
+int build(const ctor::settings& settings,
const std::string& name,
- const std::set<std::shared_ptr<Task>>& all_tasks,
+ const std::vector<std::shared_ptr<Task>>& all_tasks,
bool dryrun)
{
bool task_found{false};
@@ -168,17 +184,27 @@ int build(const Settings& settings,
{
task_found = true;
- auto depSet = getDepTasks(task);
- std::set<std::shared_ptr<Task>> ts;
- for(const auto& task : depSet)
+ try
{
- ts.insert(task);
- }
+ auto depSet = getDepTasks(task);
+ std::vector<std::shared_ptr<Task>> ts;
+ for(const auto& task_inner : depSet)
+ {
+ if(std::find(ts.begin(), ts.end(), task_inner) == ts.end())
+ {
+ ts.push_back(task_inner);
+ }
+ }
- auto ret = build(settings, name, ts, all_tasks, dryrun);
- if(ret != 0)
+ auto ret = build(settings, name, ts, all_tasks, dryrun);
+ if(ret != 0)
+ {
+ return ret;
+ }
+ }
+ catch(...)
{
- return ret;
+ return 1; // cycle detected
}
break;
@@ -194,14 +220,14 @@ int build(const Settings& settings,
return 0;
}
-int build(const Settings& settings,
+int build(const ctor::settings& settings,
const std::string& name,
const std::vector<Target>& targets,
- const std::set<std::shared_ptr<Task>>& all_tasks,
+ const std::vector<std::shared_ptr<Task>>& all_tasks,
bool dryrun)
{
bool task_found{false};
- std::set<std::shared_ptr<Task>> ts;
+ std::vector<std::shared_ptr<Task>> ts;
for(const auto& target : targets)
{
@@ -212,10 +238,20 @@ int build(const Settings& settings,
{
task_found = true;
- auto depSet = getDepTasks(task);
- for(const auto& task : depSet)
+ try
+ {
+ auto depSet = getDepTasks(task);
+ for(const auto& task_inner : depSet)
+ {
+ if(std::find(ts.begin(), ts.end(), task_inner) == ts.end())
+ {
+ ts.push_back(task_inner);
+ }
+ }
+ }
+ catch(...)
{
- ts.insert(task);
+ return 1; // cycle detected
}
}
}