Files
swift-mirror/lib/Basic/TaskQueue.cpp
Benjamin Herzog ac10fb3462 [Driver] Added process information to emitted messages
When providing the -parseable-output flag to the swift compiler, it will provide json formatted messages about tasks that run.
I added some optional usage information in form of user time, system time and maxrss to the output. This can be used by other tools using the compiler to get some insights about time and memory usage.
Since the output does not longer match processes run (in batch mode), I also added a real_pid field so the client could reason about jobs that belong together if needed.

rdar://39798231
2018-05-25 13:12:57 -07:00

96 lines
3.3 KiB
C++

//===--- TaskQueue.cpp - Task Execution Work Queue ------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file includes the appropriate platform-specific TaskQueue
/// implementation (or the default serial fallback if one is not available),
/// as well as any platform-agnostic TaskQueue functionality.
///
//===----------------------------------------------------------------------===//
#include "swift/Basic/TaskQueue.h"
using namespace swift;
using namespace swift::sys;
// Include the correct TaskQueue implementation.
#if LLVM_ON_UNIX && !defined(__CYGWIN__) && !defined(__HAIKU__)
#include "Unix/TaskQueue.inc"
#else
#include "Default/TaskQueue.inc"
#endif
TaskQueue::TaskQueue(unsigned NumberOfParallelTasks,
UnifiedStatsReporter *USR)
: NumberOfParallelTasks(NumberOfParallelTasks),
Stats(USR){}
TaskQueue::~TaskQueue() = default;
// DummyTaskQueue implementation
DummyTaskQueue::DummyTaskQueue(unsigned NumberOfParallelTasks)
: TaskQueue(NumberOfParallelTasks) {}
DummyTaskQueue::~DummyTaskQueue() = default;
void DummyTaskQueue::addTask(const char *ExecPath, ArrayRef<const char *> Args,
ArrayRef<const char *> Env, void *Context,
bool SeparateErrors) {
QueuedTasks.emplace(std::unique_ptr<DummyTask>(
new DummyTask(ExecPath, Args, Env, Context, SeparateErrors)));
}
bool DummyTaskQueue::execute(TaskQueue::TaskBeganCallback Began,
TaskQueue::TaskFinishedCallback Finished,
TaskQueue::TaskSignalledCallback Signalled) {
using PidTaskPair = std::pair<ProcessId, std::unique_ptr<DummyTask>>;
std::queue<PidTaskPair> ExecutingTasks;
bool SubtaskFailed = false;
static ProcessId Pid = 0;
unsigned MaxNumberOfParallelTasks = getNumberOfParallelTasks();
while ((!QueuedTasks.empty() && !SubtaskFailed) ||
!ExecutingTasks.empty()) {
// Enqueue additional tasks if we have additional tasks, we aren't already
// at the parallel limit, and no earlier subtasks have failed.
while (!SubtaskFailed && !QueuedTasks.empty() &&
ExecutingTasks.size() < MaxNumberOfParallelTasks) {
std::unique_ptr<DummyTask> T(QueuedTasks.front().release());
QueuedTasks.pop();
if (Began)
Began(++Pid, T->Context);
ExecutingTasks.push(PidTaskPair(Pid, std::move(T)));
}
// Finish the first scheduled task.
PidTaskPair P = std::move(ExecutingTasks.front());
ExecutingTasks.pop();
if (Finished) {
std::string Output = "Output placeholder\n";
std::string Errors =
P.second->SeparateErrors ? "Error placeholder\n" : "";
if (Finished(P.first, 0, Output, Errors, TaskProcessInformation(Pid),
P.second->Context) == TaskFinishedResponse::StopExecution)
SubtaskFailed = true;
}
}
return false;
}