Revisión | 2b06a0ddc3db50acefe1726be2d6b9840b79890a (tree) |
---|---|
Tiempo | 2020-05-24 06:50:34 |
Autor | Tomasz Konojacki <me@xenu...> |
Commiter | Tomasz Konojacki |
sdasdsad
@@ -22,7 +22,6 @@ | ||
22 | 22 | |
23 | 23 | #include "system_metrics.hxx" |
24 | 24 | |
25 | -static double calc_cpu_usage(struct cpu_times &prev_ct, const struct cpu_times &ct); | |
26 | 25 | |
27 | 26 | double |
28 | 27 | system_metrics::cpu_usage() |
@@ -47,11 +46,13 @@ system_metrics::per_cpu_usage() | ||
47 | 46 | return ret; |
48 | 47 | } |
49 | 48 | |
49 | + | |
50 | + | |
50 | 51 | // |
51 | 52 | // util functions |
52 | 53 | // |
53 | 54 | |
54 | -static double | |
55 | +double | |
55 | 56 | calc_cpu_usage(struct cpu_times &prev_ct, const struct cpu_times &ct) |
56 | 57 | { |
57 | 58 | uint64_t idle = ct.idle; |
@@ -63,7 +63,7 @@ | ||
63 | 63 | // () is a magic value that signals the end of the list, see _SM_DISCARD_IF_END(). |
64 | 64 | #define _SM_FOREACH(...) _SM_FOREACH2(__VA_ARGS__, ()) |
65 | 65 | |
66 | -#define _SM_ADD_FIELD(field_name) { #field_name , &std::remove_pointer<decltype(this)>::type::name } | |
66 | +#define _SM_ADD_FIELD(field_name) { #field_name , &std::remove_pointer<decltype(this)>::type::field_name } | |
67 | 67 | |
68 | 68 | // SM_MAPIFY_STRUCT(type, field1, ...) is a macro that adds std::map-like at() |
69 | 69 | // and contains() methods to a struct for specified fields. All mapified fields |
@@ -102,5 +102,5 @@ | ||
102 | 102 | } \ |
103 | 103 | bool contains(const std::string_view &field) { \ |
104 | 104 | return static_cast<bool>(this->_sm_fields_map().count(field)); \ |
105 | - } \ | |
106 | - } | |
105 | + } | |
106 | + |
@@ -22,11 +22,15 @@ | ||
22 | 22 | |
23 | 23 | #pragma once |
24 | 24 | |
25 | -#include <cstdef> | |
25 | +#include <cstddef> | |
26 | 26 | #include <memory> |
27 | 27 | #include <string> |
28 | 28 | #include <vector> |
29 | +#include <unordered_map> | |
29 | 30 | #include <stdint.h> |
31 | +#include <string_view> | |
32 | + | |
33 | +#include "sm_mapify.hxx" | |
30 | 34 | |
31 | 35 | #if defined(__GNUC__) || defined(__clang__) |
32 | 36 | # define SM_LIKELY(x) __builtin_expect(!!(x),1) |
@@ -52,6 +56,7 @@ struct process { | ||
52 | 56 | uint64_t pid = 0; |
53 | 57 | uint64_t ppid = 0; |
54 | 58 | std::string path; |
59 | + double cpu_usage = -1; | |
55 | 60 | }; |
56 | 61 | |
57 | 62 | class system_metrics { |
@@ -74,4 +79,14 @@ private: | ||
74 | 79 | struct cpu_times prev_cpu_times; |
75 | 80 | std::vector<struct cpu_times> prev_per_cpu_times; |
76 | 81 | std::unique_ptr<struct sm_private> _priv; |
82 | + std::unordered_map<uint64_t, struct cpu_times > prev_proc_cpu_times; | |
83 | +}; | |
84 | + | |
85 | +struct process_list_fields { | |
86 | + bool pid = true; | |
87 | + bool cpu_usage; | |
88 | + bool name; | |
89 | + SM_MAPIFY_STRUCT(bool, pid, cpu_usage, name) | |
77 | 90 | }; |
91 | + | |
92 | +double calc_cpu_usage(struct cpu_times &prev_ct, const struct cpu_times &ct); |
@@ -24,7 +24,6 @@ | ||
24 | 24 | #include "win32_exception.hxx" |
25 | 25 | |
26 | 26 | #include <string> |
27 | -#include <vector> | |
28 | 27 | #include <mutex> |
29 | 28 | |
30 | 29 | #include <psapi.h> |
@@ -159,8 +158,11 @@ system_metrics::process_list() | ||
159 | 158 | { |
160 | 159 | auto &buf = this->_priv->proc_info_buf; |
161 | 160 | |
161 | + struct cpu_times ct; | |
162 | 162 | for (;;) { |
163 | 163 | ULONG ret_size_bytes; |
164 | + | |
165 | + ct = this->cpu_times(); | |
164 | 166 | NTSTATUS status = NtQuerySystemInformation( |
165 | 167 | SystemProcessInformation, |
166 | 168 | buf.data(), |
@@ -181,6 +183,8 @@ system_metrics::process_list() | ||
181 | 183 | break; |
182 | 184 | } |
183 | 185 | |
186 | + uint64_t total_cpu; | |
187 | + | |
184 | 188 | SYSTEM_PROCESS_INFORMATION *info = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>(&buf[0]); |
185 | 189 | std::vector<struct process> ret; |
186 | 190 | for (;;) { |
@@ -189,8 +193,19 @@ system_metrics::process_list() | ||
189 | 193 | p.pid = reinterpret_cast<uint64_t>(info->UniqueProcessId); |
190 | 194 | unicode_string_to_string(info->ImageName, p.path); |
191 | 195 | |
196 | + struct cpu_times t; | |
197 | + t.user = info->UserTime.QuadPart; | |
198 | + t.system = info->KernelTime.QuadPart; | |
199 | + t.idle = ct.system + ct.idle + ct.user - t.user - t.system; | |
200 | + | |
201 | + p.cpu_usage = calc_cpu_usage( | |
202 | + this->prev_proc_cpu_times[p.pid], | |
203 | + t | |
204 | + ); | |
205 | + | |
192 | 206 | ret.push_back(p); |
193 | 207 | |
208 | + | |
194 | 209 | if (info->NextEntryOffset) |
195 | 210 | info = reinterpret_cast<SYSTEM_PROCESS_INFORMATION*>( |
196 | 211 | reinterpret_cast<std::byte*>(info) + info->NextEntryOffset |
@@ -167,8 +167,17 @@ OUTPUT: | ||
167 | 167 | RETVAL |
168 | 168 | |
169 | 169 | AV* |
170 | -system_metrics::process_list() | |
170 | +system_metrics::process_list(...) | |
171 | 171 | CODE: |
172 | + //if (items%2==0) | |
173 | + // croak("uneven"); | |
174 | + process_list_fields fields; | |
175 | + for (size_t i = 1; items > i; i+=1) { | |
176 | + STRLEN len; | |
177 | + char *key = SvPV(ST(i), len); | |
178 | + fields.at({key,len}) = true; | |
179 | + } | |
180 | + printf("pid: %d\ncpu_usage: %d\nname: %d", (int)fields.pid, (int)fields.cpu_usage, (int)fields.name); | |
172 | 181 | std::vector<struct process> proc_list; |
173 | 182 | SM_BEGIN_WRAP_EXCEPTION |
174 | 183 | proc_list = THIS->process_list(); |
@@ -180,6 +189,7 @@ CODE: | ||
180 | 189 | HV *proc_hv = newHV(); |
181 | 190 | hv_stores(proc_hv, "pid", newSVuv(p.pid)); |
182 | 191 | hv_stores(proc_hv, "path", newSVpvn_flags(p.path.data(), p.path.size(), 0)); |
192 | + hv_stores(proc_hv, "cpu_usage", newSVnv(p.cpu_usage)); | |
183 | 193 | AvARRAY(ret)[i++] = newRV_noinc((SV*)proc_hv); |
184 | 194 | } |
185 | 195 | RETVAL = ret; |