13
13
#ifndef SWIFT_BASIC_TASKQUEUE_H
14
14
#define SWIFT_BASIC_TASKQUEUE_H
15
15
16
+ #include " swift/Basic/JSONSerialization.h"
16
17
#include " swift/Basic/LLVM.h"
17
18
#include " llvm/ADT/ArrayRef.h"
18
19
#include " llvm/Config/config.h"
22
23
#include < memory>
23
24
#include < queue>
24
25
26
+ #if defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
27
+ struct rusage ;
28
+ #endif
29
+
25
30
namespace swift {
26
31
class UnifiedStatsReporter ;
27
32
namespace sys {
@@ -39,6 +44,62 @@ enum class TaskFinishedResponse {
39
44
StopExecution,
40
45
};
41
46
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
+
42
103
// / \brief A class encapsulating the execution of multiple tasks in parallel.
43
104
class TaskQueue {
44
105
// / Tasks which have not begun execution.
@@ -81,13 +142,15 @@ class TaskQueue {
81
142
// / \param Errors the errors from the task which finished execution, if
82
143
// / available and SeparateErrors was true. (This may not be available on all
83
144
// / platforms.)
145
+ // / \param ProcInfo contains information like the operating process identifier
146
+ // / and resource usage if available
84
147
// / \param Context the context which was passed when the task was added
85
148
// /
86
149
// / \returns true if further execution of tasks should stop,
87
150
// / false if execution should continue
88
151
using TaskFinishedCallback = std::function<TaskFinishedResponse(
89
152
ProcessId Pid, int ReturnCode, StringRef Output, StringRef Errors,
90
- void *Context)>;
153
+ TaskProcessInformation ProcInfo, void *Context)>;
91
154
92
155
// / \brief A callback which will be executed if a task exited abnormally due
93
156
// / to a signal.
@@ -100,16 +163,18 @@ class TaskQueue {
100
163
// / \param Errors the errors from the task which exited abnormally, if
101
164
// / available and SeparateErrors was true. (This may not be available on all
102
165
// / platforms.)
166
+ // / \param ProcInfo contains information like the operating process identifier
167
+ // / and resource usage if available
103
168
// / \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.
107
172
// /
108
173
// / \returns a TaskFinishedResponse indicating whether or not execution
109
174
// / should proceed
110
175
using TaskSignalledCallback = std::function<TaskFinishedResponse(
111
176
ProcessId Pid, StringRef ErrorMsg, StringRef Output, StringRef Errors,
112
- void *Context, Optional<int > Signal)>;
177
+ void *Context, Optional<int > Signal, TaskProcessInformation ProcInfo )>;
113
178
#pragma clang diagnostic pop
114
179
115
180
// / \brief Indicates whether TaskQueue supports buffering output on the
@@ -202,6 +267,22 @@ class DummyTaskQueue : public TaskQueue {
202
267
};
203
268
204
269
} // 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
+
205
286
} // end namespace swift
206
287
207
288
#endif // SWIFT_BASIC_TASKQUEUE_H
0 commit comments