1313#ifndef SWIFT_BASIC_TASKQUEUE_H
1414#define SWIFT_BASIC_TASKQUEUE_H
1515
16+ #include " swift/Basic/JSONSerialization.h"
1617#include " swift/Basic/LLVM.h"
1718#include " llvm/ADT/ArrayRef.h"
1819#include " llvm/Config/config.h"
2223#include < memory>
2324#include < queue>
2425
26+ #if defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
27+ struct rusage ;
28+ #endif
29+
2530namespace swift {
2631class UnifiedStatsReporter ;
2732namespace sys {
@@ -39,6 +44,62 @@ enum class TaskFinishedResponse {
3944 StopExecution,
4045};
4146
47+ // / TaskProcessInformation is bound to a task and contains information about the
48+ // / process that ran this task. This is especially useful to find out which
49+ // / tasks ran in the same process (in multifile-mode or when WMO is activated
50+ // / e.g.). If available, it also contains information about the usage of
51+ // / resources like CPU time or memory the process used in the system. How ever,
52+ // / this could differ from platform to platform and is therefore optional.
53+
54+ // / One process could handle multiple tasks in some modes of the Swift compiler
55+ // / (multifile, WMO). To not break existing tools, the driver does use unique
56+ // / identifiers for the tasks that are not the process identifier. To still be
57+ // / able to reason about tasks that ran in the same process the
58+ // / TaskProcessInformation struct contains information about the actual process
59+ // / of the operating system. The OSPid is the actual process identifier and is
60+ // / therefore not guaranteed to be unique over all tasks. The ProcessUsage
61+ // / contains optional usage information about the operating system process. It
62+ // / could be used by tools that take those information as input for analyzing
63+ // / the Swift compiler on a process-level. It will be `None` if the execution
64+ // / has been skipped or one of the following symbols are not available on the
65+ // / system: `rusage`, `wait4`.
66+ struct TaskProcessInformation {
67+
68+ struct ResourceUsage {
69+ // user time in µs
70+ uint64_t Utime;
71+ // system time in µs
72+ uint64_t Stime;
73+ // maximum resident set size in Bytes
74+ uint64_t Maxrss;
75+
76+ ResourceUsage (uint64_t Utime, uint64_t Stime, uint64_t Maxrss)
77+ : Utime(Utime), Stime(Stime), Maxrss(Maxrss) {}
78+
79+ virtual ~ResourceUsage () = default ;
80+ virtual void provideMapping (json::Output &out);
81+ };
82+
83+ private:
84+ // the process identifier of the operating system
85+ ProcessId OSPid;
86+ // usage information about the process, if available
87+ Optional<ResourceUsage> ProcessUsage;
88+
89+ public:
90+ TaskProcessInformation (ProcessId Pid, uint64_t utime, uint64_t stime,
91+ uint64_t maxrss)
92+ : OSPid(Pid), ProcessUsage(ResourceUsage(utime, stime, maxrss)) {}
93+
94+ TaskProcessInformation (ProcessId Pid) : OSPid(Pid), ProcessUsage(None) {}
95+
96+ #if defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
97+ TaskProcessInformation (ProcessId Pid, struct rusage Usage);
98+ #endif // defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
99+ virtual ~TaskProcessInformation () = default ;
100+ virtual void provideMapping (json::Output &out);
101+ };
102+
42103// / \brief A class encapsulating the execution of multiple tasks in parallel.
43104class TaskQueue {
44105 // / Tasks which have not begun execution.
@@ -81,13 +142,15 @@ class TaskQueue {
81142 // / \param Errors the errors from the task which finished execution, if
82143 // / available and SeparateErrors was true. (This may not be available on all
83144 // / platforms.)
145+ // / \param ProcInfo contains information like the operating process identifier
146+ // / and resource usage if available
84147 // / \param Context the context which was passed when the task was added
85148 // /
86149 // / \returns true if further execution of tasks should stop,
87150 // / false if execution should continue
88151 using TaskFinishedCallback = std::function<TaskFinishedResponse(
89152 ProcessId Pid, int ReturnCode, StringRef Output, StringRef Errors,
90- void *Context)>;
153+ TaskProcessInformation ProcInfo, void *Context)>;
91154
92155 // / \brief A callback which will be executed if a task exited abnormally due
93156 // / to a signal.
@@ -100,16 +163,18 @@ class TaskQueue {
100163 // / \param Errors the errors from the task which exited abnormally, if
101164 // / available and SeparateErrors was true. (This may not be available on all
102165 // / platforms.)
166+ // / \param ProcInfo contains information like the operating process identifier
167+ // / and resource usage if available
103168 // / \param Context the context which was passed when the task was added
104- // / \param Signal the terminating signal number, if available.
105- // / This may not be available on all platforms. If it is ever provided,
106- // / it should not be removed in future versions of the compiler.
169+ // / \param Signal the terminating signal number, if available. This may not be
170+ // / available on all platforms. If it is ever provided, it should not be
171+ // / removed in future versions of the compiler.
107172 // /
108173 // / \returns a TaskFinishedResponse indicating whether or not execution
109174 // / should proceed
110175 using TaskSignalledCallback = std::function<TaskFinishedResponse(
111176 ProcessId Pid, StringRef ErrorMsg, StringRef Output, StringRef Errors,
112- void *Context, Optional<int > Signal)>;
177+ void *Context, Optional<int > Signal, TaskProcessInformation ProcInfo )>;
113178#pragma clang diagnostic pop
114179
115180 // / \brief Indicates whether TaskQueue supports buffering output on the
@@ -202,6 +267,22 @@ class DummyTaskQueue : public TaskQueue {
202267};
203268
204269} // end namespace sys
270+
271+ namespace json {
272+ template <> struct ObjectTraits <sys::TaskProcessInformation> {
273+ static void mapping (Output &out, sys::TaskProcessInformation &value) {
274+ value.provideMapping (out);
275+ }
276+ };
277+
278+ template <> struct ObjectTraits <sys::TaskProcessInformation::ResourceUsage> {
279+ static void mapping (Output &out,
280+ sys::TaskProcessInformation::ResourceUsage &value) {
281+ value.provideMapping (out);
282+ }
283+ };
284+ } // end namespace json
285+
205286} // end namespace swift
206287
207288#endif // SWIFT_BASIC_TASKQUEUE_H
0 commit comments