]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsclocks: add support for cpu clocks
authorThomas Weißschuh <thomas@t-8ch.de>
Mon, 31 Jul 2023 15:49:11 +0000 (17:49 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Mon, 31 Jul 2023 15:49:11 +0000 (17:49 +0200)
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
bash-completion/lsclocks
misc-utils/lsclocks.1.adoc
misc-utils/lsclocks.c
tests/expected/misc/lsclocks-cpu [new file with mode: 0644]
tests/ts/misc/lsclocks

index 72e6d23bf0872f90bd71ca1bac015b88f2211b2f..30cf9c545a2dd6c6202d9f05d593d396225a29d1 100644 (file)
@@ -31,6 +31,10 @@ _lsclocks_module()
                        COMPREPLY=( $(compgen -o filenames -W "$clocks" -- "$cur") )
                        return 0
                        ;;
+               '-c'|'--cpu-clock')
+                       _pids
+                       return 0
+                       ;;
                '-h'|'--help'|'-V'|'--version')
                        return 0
                        ;;
@@ -44,6 +48,7 @@ _lsclocks_module()
                                --raw
                                --time
                                --dynamic-clock
+                               --cpu-clock
                                --help
                                --version"
                        COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
index 31d565b3de2b2af3b48d5e9ebf1581a74c732930..32de275f60b7f4f3af0b1e126bd9ff79893b25c4 100644 (file)
@@ -49,6 +49,10 @@ Do not try to discover dynamic clocks.
 Also display specified dynamic clock.
 Can be specified multiple times.
 
+*-c*, *--cpu-clock* _pid_
+Also display CPU clock of specified process.
+Can be specified multiple times.
+
 include::man-common/help-version.adoc[]
 
 == OUTPUT COLUMNS
index 665d02be10cedeba9b0fc1d69a8f2161252179f0..a54e12e656180a609ad49d9ba29dfce5b983223e 100644 (file)
@@ -93,6 +93,7 @@ static inline bool CLOCKID_IS_DYNAMIC(clockid_t clk)
 enum CLOCK_TYPE {
        CT_SYS,
        CT_PTP,
+       CT_CPU,
 };
 
 static const char *clock_type_name(enum CLOCK_TYPE type)
@@ -102,6 +103,8 @@ static const char *clock_type_name(enum CLOCK_TYPE type)
                return "sys";
        case CT_PTP:
                return "ptp";
+       case CT_CPU:
+               return "cpu";
        }
        errx(EXIT_FAILURE, _("Unknown clock type %d"), type);
 }
@@ -197,6 +200,7 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_(" -t, --time <clock>         show current time of single clock\n"), out);
        fputs(_(" --no-discover-dynamic      do not try to discover dynamic clocks\n"), out);
        fputs(_(" -d, --dynamic-clock <path> also display specified dynamic clock\n"), out);
+       fputs(_(" -c, --cpu-clock <pid>      also display CPU clock of specified process\n"), out);
 
        fputs(USAGE_SEPARATOR, out);
        printf(USAGE_HELP_OPTIONS(29));
@@ -418,6 +422,33 @@ static void add_dynamic_clocks_from_discovery(struct libscols_table *tb,
        globfree(&state);
 }
 
+struct cpu_clock {
+       struct list_head head;
+       pid_t pid;
+       char name[sizeof(stringify_value(SINT_MAX(pid_t)))];
+};
+
+static void add_cpu_clock(struct libscols_table *tb,
+                         const int *columns, size_t ncolumns,
+                         pid_t pid, const char *name)
+{
+       int rc;
+       clockid_t clockid;
+
+       rc = clock_getcpuclockid(pid, &clockid);
+       if (rc)
+               errx(EXIT_FAILURE, _("Could not get CPU clock of process %jd: %s"),
+                                  (intmax_t) pid, strerror(rc));
+
+       struct clockinfo clockinfo = {
+               .type = CT_CPU,
+               .name = name,
+               .id = clockid,
+       };
+       add_clock_line(tb, columns, ncolumns, &clockinfo);
+}
+
+
 int main(int argc, char **argv)
 {
        size_t i;
@@ -433,8 +464,9 @@ int main(int argc, char **argv)
        size_t ncolumns = 0;
        clockid_t clock = -1;
        struct dynamic_clock *dynamic_clock;
-       struct list_head *current_dynamic_clock;
-       struct list_head dynamic_clocks;
+       struct cpu_clock *cpu_clock;
+       struct list_head *current_dynamic_clock, *current_cpu_clock;
+       struct list_head dynamic_clocks, cpu_clocks;
 
        struct timespec now;
 
@@ -453,6 +485,7 @@ int main(int argc, char **argv)
                { "time",                required_argument, NULL, 't' },
                { "no-discover-dynamic", no_argument,       NULL, OPT_NO_DISC_DYN },
                { "dynamic-clock",       required_argument, NULL, 'd' },
+               { "cpu-clock",           required_argument, NULL, 'c' },
                { 0 }
        };
 
@@ -462,8 +495,9 @@ int main(int argc, char **argv)
        close_stdout_atexit();
 
        INIT_LIST_HEAD(&dynamic_clocks);
+       INIT_LIST_HEAD(&cpu_clocks);
 
-       while ((c = getopt_long(argc, argv, "no:Jrt:d:Vh", longopts, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "no:Jrt:d:c:Vh", longopts, NULL)) != -1) {
                switch (c) {
                case 'n':
                        noheadings = true;
@@ -492,6 +526,13 @@ int main(int argc, char **argv)
                case OPT_NO_DISC_DYN:
                        disc_dynamic = false;
                        break;
+               case 'c':
+                       cpu_clock = xmalloc(sizeof(*cpu_clock));
+                       cpu_clock->pid = strtopid_or_err(optarg, _("failed to parse pid"));
+                       snprintf(cpu_clock->name, sizeof(cpu_clock->name),
+                                "%jd", (intmax_t) cpu_clock->pid);
+                       list_add(&cpu_clock->head, &cpu_clocks);
+                       break;
                case 'V':
                        print_version(EXIT_SUCCESS);
                case 'h':
@@ -555,6 +596,13 @@ int main(int argc, char **argv)
 
        list_free(&dynamic_clocks, struct dynamic_clock, head, free);
 
+       list_for_each(current_cpu_clock, &cpu_clocks) {
+               cpu_clock = list_entry(current_cpu_clock, struct cpu_clock, head);
+               add_cpu_clock(tb, columns, ncolumns, cpu_clock->pid, cpu_clock->name);
+       }
+
+       list_free(&cpu_clocks, struct cpu_clock, head, free);
+
        scols_table_enable_json(tb, json);
        scols_table_enable_raw(tb, raw);
        scols_table_enable_noheadings(tb, noheadings);
diff --git a/tests/expected/misc/lsclocks-cpu b/tests/expected/misc/lsclocks-cpu
new file mode 100644 (file)
index 0000000..8da71a5
--- /dev/null
@@ -0,0 +1 @@
+cpu     1
index 48cd7d9092fc4d676d2a3f1612e1aa038f49575f..f1e403c5bdd835041305cd7ea67e97dc02760448 100755 (executable)
@@ -49,4 +49,10 @@ else
        ts_skip_subtest "/dev/ptp0 not usable"
 fi
 
+ts_init_subtest cpu
+
+"$TS_CMD_LSCLOCKS" --cpu 1 --output TYPE,ID,NAME | tail -1 > "$TS_OUTPUT" 2>> "$TS_ERRLOG"
+
+ts_finalize_subtest
+
 ts_finalize