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 *"

Reply via email to