This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new bc084a8505 sched/clock/clock_getcpuclockid: add clock_getcpuclockid
implementation
bc084a8505 is described below
commit bc084a850570f92f59d1f760e4f9d66df6577750
Author: guoshichao <[email protected]>
AuthorDate: Wed Jun 21 17:26:35 2023 +0800
sched/clock/clock_getcpuclockid: add clock_getcpuclockid implementation
1. the implementation can pass the full
ltp/open_posix_testsuite/clock_getcpuclockid testcases
2. the modification are referred to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getcpuclockid.html
Signed-off-by: guoshichao <[email protected]>
---
include/nuttx/clock.h | 15 ++++++
include/sys/syscall_lookup.h | 1 +
include/time.h | 1 +
sched/clock/Make.defs | 2 +-
.../{clock_getres.c => clock_getcpuclockid.c} | 57 ++++++++++----------
sched/clock/clock_getres.c | 7 +--
sched/clock/clock_gettime.c | 61 +++++++++++++++++++++-
syscall/syscall.csv | 1 +
8 files changed, 109 insertions(+), 36 deletions(-)
diff --git a/include/nuttx/clock.h b/include/nuttx/clock.h
index 294f528d81..ace7a20a48 100644
--- a/include/nuttx/clock.h
+++ b/include/nuttx/clock.h
@@ -81,6 +81,21 @@
# undef CONFIG_SYSTEM_TIME64
#endif
+/* The following are the bit fields of the clockid_t
+ * bit 0~2: the clock type
+ * CLOCK_REALTIME - 0
+ * CLOCK_MONOTONIC - 1
+ * CLOCK_PROCESS_CPUTIME_ID - 2
+ * CLOCK_THREAD_CPUTIME_ID - 3
+ * CLOCK_BOOTTIME - 4
+ * bit 3~32: the pid or tid value
+ *
+ * The CLOCK_MASK are using to extract the clock_type from the clockid_t
+ */
+
+#define CLOCK_MASK 7
+#define CLOCK_SHIFT 3
+
/* Timing constants *********************************************************/
#define NSEC_PER_SEC 1000000000L /* Seconds */
diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h
index 949c629450..5218e5f292 100644
--- a/include/sys/syscall_lookup.h
+++ b/include/sys/syscall_lookup.h
@@ -168,6 +168,7 @@ SYSCALL_LOOKUP(clock_nanosleep, 4)
*/
SYSCALL_LOOKUP(clock, 0)
+SYSCALL_LOOKUP(clock_getcpuclockid, 2)
SYSCALL_LOOKUP(clock_getres, 2)
SYSCALL_LOOKUP(clock_gettime, 2)
SYSCALL_LOOKUP(clock_settime, 2)
diff --git a/include/time.h b/include/time.h
index 6f08b4a02b..72e35584c9 100644
--- a/include/time.h
+++ b/include/time.h
@@ -201,6 +201,7 @@ clock_t clock(void);
int clock_settime(clockid_t clockid, FAR const struct timespec *tp);
int clock_gettime(clockid_t clockid, FAR struct timespec *tp);
int clock_getres(clockid_t clockid, FAR struct timespec *res);
+int clock_getcpuclockid(pid_t pid, FAR clockid_t *clockid);
int timespec_get(FAR struct timespec *t, int b);
time_t timegm(FAR struct tm *tp);
diff --git a/sched/clock/Make.defs b/sched/clock/Make.defs
index 5c51e902be..fc7ff0a952 100644
--- a/sched/clock/Make.defs
+++ b/sched/clock/Make.defs
@@ -21,7 +21,7 @@
CSRCS += clock_initialize.c clock_settime.c clock_gettime.c clock_getres.c
CSRCS += clock_abstime2ticks.c
CSRCS += clock_systime_ticks.c clock_systime_timespec.c
-CSRCS += clock.c
+CSRCS += clock.c clock_getcpuclockid.c
ifeq ($(CONFIG_CLOCK_TIMEKEEPING),y)
CSRCS += clock_timekeeping.c
diff --git a/sched/clock/clock_getres.c b/sched/clock/clock_getcpuclockid.c
similarity index 66%
copy from sched/clock/clock_getres.c
copy to sched/clock/clock_getcpuclockid.c
index c5b27104f7..d26731bee1 100644
--- a/sched/clock/clock_getres.c
+++ b/sched/clock/clock_getcpuclockid.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * sched/clock/clock_getres.c
+ * sched/clock/clock_getcpuclockid.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -24,10 +24,9 @@
#include <nuttx/config.h>
-#include <stdint.h>
#include <time.h>
#include <errno.h>
-#include <debug.h>
+#include <unistd.h>
#include "clock/clock.h"
@@ -36,42 +35,40 @@
****************************************************************************/
/****************************************************************************
- * Name: clock_getres
+ * Name: clock_getcpuclockid
*
* Description:
- * Clock Functions based on POSIX APIs
+ * The function shall return clock id of the CPU-time clock of the process
+ * specified by pid
+ *
+ * Input Parameters:
+ * pid - the specified process id
+ * clockid - the clock type that need to setup
+ *
+ * Returned Value:
+ * Return 0 on success, return error number on error
*
****************************************************************************/
-int clock_getres(clockid_t clock_id, struct timespec *res)
+int clock_getcpuclockid(pid_t pid, FAR clockid_t *clockid)
{
- int ret = OK;
-
- sinfo("clock_id=%d\n", clock_id);
-
- switch (clock_id)
+ if (pid < 0)
{
- default:
- serr("Returning ERROR\n");
- set_errno(EINVAL);
- ret = ERROR;
- break;
-
- case CLOCK_MONOTONIC:
- case CLOCK_BOOTTIME:
- case CLOCK_REALTIME:
- case CLOCK_PROCESS_CPUTIME_ID:
- case CLOCK_THREAD_CPUTIME_ID:
-
- /* Form the timspec using clock resolution in nanoseconds */
+ set_errno(EINVAL);
+ return ERROR;
+ }
- res->tv_sec = 0;
- res->tv_nsec = NSEC_PER_TICK;
+ /* If the pid is 0, we need to use the pid of current process */
- sinfo("Returning res=(%d,%d)\n", (int)res->tv_sec,
- (int)res->tv_nsec);
- break;
+ if (pid == 0)
+ {
+ pid = getpid();
}
- return ret;
+ /* For clock_getcpuclockid, the clock type are
+ * CLOCK_PROCESS_CPUTIME_ID
+ */
+
+ *clockid = (pid << CLOCK_SHIFT) | CLOCK_PROCESS_CPUTIME_ID;
+ return OK;
}
diff --git a/sched/clock/clock_getres.c b/sched/clock/clock_getres.c
index c5b27104f7..99ed173a5f 100644
--- a/sched/clock/clock_getres.c
+++ b/sched/clock/clock_getres.c
@@ -45,11 +45,12 @@
int clock_getres(clockid_t clock_id, struct timespec *res)
{
- int ret = OK;
+ clockid_t clock_type = clock_id & CLOCK_MASK;
+ int ret = OK;
- sinfo("clock_id=%d\n", clock_id);
+ sinfo("clock_id=%d, clock_type=%d\n", clock_id, clock_type);
- switch (clock_id)
+ switch (clock_type)
{
default:
serr("Returning ERROR\n");
diff --git a/sched/clock/clock_gettime.c b/sched/clock/clock_gettime.c
index 4f1d5e0f4b..2842e08292 100644
--- a/sched/clock/clock_gettime.c
+++ b/sched/clock/clock_gettime.c
@@ -31,6 +31,7 @@
#include <debug.h>
#include <nuttx/arch.h>
+#include <nuttx/sched.h>
#include <nuttx/spinlock.h>
#include "clock/clock.h"
@@ -58,6 +59,11 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
#endif
int ret = OK;
+ clockid_t clock_type = clock_id & CLOCK_MASK;
+#ifdef CONFIG_SCHED_CRITMONITOR
+ pid_t pid = clock_id >> CLOCK_SHIFT;
+#endif
+
DEBUGASSERT(tp != NULL);
/* CLOCK_MONOTONIC is an optional under POSIX: "If the Monotonic Clock
@@ -72,7 +78,7 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
* is invoked with a clock_id argument of CLOCK_MONOTONIC."
*/
- if (clock_id == CLOCK_MONOTONIC || clock_id == CLOCK_BOOTTIME)
+ if (clock_type == CLOCK_MONOTONIC || clock_type == CLOCK_BOOTTIME)
{
/* The the time elapsed since the timer was initialized at power on
* reset.
@@ -87,7 +93,7 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
* backward as the system time-of-day clock is changed.
*/
- else if (clock_id == CLOCK_REALTIME)
+ else if (clock_type == CLOCK_REALTIME)
{
/* Get the elapsed time since the time-of-day was last set.
* clock_systime_timespec() provides the time since power was applied;
@@ -131,6 +137,57 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp)
}
#endif /* CONFIG_CLOCK_TIMEKEEPING */
}
+#ifdef CONFIG_SCHED_CRITMONITOR
+ else if (clock_type == CLOCK_THREAD_CPUTIME_ID)
+ {
+ FAR struct tcb_s *tcb;
+
+ if (pid == 0)
+ {
+ /* Fetch the THREAD_CPUTIME for current thread */
+
+ tcb = nxsched_self();
+ }
+ else
+ {
+ tcb = nxsched_get_tcb(pid);
+ }
+
+ up_perf_convert(tcb->run_time, tp);
+ }
+ else if (clock_type == CLOCK_PROCESS_CPUTIME_ID)
+ {
+ FAR struct task_group_s *group;
+ unsigned long runtime;
+ irqstate_t flags;
+ int i;
+ FAR struct tcb_s *tcb;
+
+ if (pid == 0)
+ {
+ /* Fetch the PROCESS_CPUTIME for current process */
+
+ tcb = nxsched_self();
+ }
+ else
+ {
+ tcb = nxsched_get_tcb(pid);
+ }
+
+ group = tcb->group;
+ runtime = 0;
+
+ flags = enter_critical_section();
+ for (i = group->tg_nmembers - 1; i >= 0; i--)
+ {
+ tcb = nxsched_get_tcb(group->tg_members[i]);
+ runtime += tcb->run_time;
+ }
+
+ leave_critical_section(flags);
+ up_perf_convert(runtime, tp);
+ }
+#endif
else
{
ret = -EINVAL;
diff --git a/syscall/syscall.csv b/syscall/syscall.csv
index c0f048f11b..f40c2de7d5 100644
--- a/syscall/syscall.csv
+++ b/syscall/syscall.csv
@@ -13,6 +13,7 @@
"chown","unistd.h","","int","FAR const char *","uid_t","gid_t"
"clearenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int"
"clock","time.h","","clock_t"
+"clock_getcpuclockid","time.h","","int","pid_t","FAR clockid_t *"
"clock_getres","time.h","","int","clockid_t","FAR struct timespec *"
"clock_gettime","time.h","","int","clockid_t","FAR struct timespec *"
"clock_nanosleep","time.h","","int","clockid_t","int","FAR const struct
timespec *", "FAR struct timespec *"