mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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
96 lines
3.3 KiB
C++
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;
|
|
}
|