Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/linux/common Implement clock_* POSIX functions.



details:   https://anonhg.NetBSD.org/src/rev/f2b23cf7c18b
branches:  trunk
changeset: 580946:f2b23cf7c18b
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Mon May 16 21:18:34 2005 +0000

description:
Implement clock_* POSIX functions.

diffstat:

 sys/compat/linux/common/linux_sched.h |    9 +-
 sys/compat/linux/common/linux_time.c  |  257 ++++++++++++++++++++++++++++++++-
 2 files changed, 255 insertions(+), 11 deletions(-)

diffs (truncated from 323 to 300 lines):

diff -r 9b50807a0725 -r f2b23cf7c18b sys/compat/linux/common/linux_sched.h
--- a/sys/compat/linux/common/linux_sched.h     Mon May 16 21:18:18 2005 +0000
+++ b/sys/compat/linux/common/linux_sched.h     Mon May 16 21:18:34 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_sched.h,v 1.3 2004/09/05 07:22:20 jdolecek Exp $ */
+/*     $NetBSD: linux_sched.h,v 1.4 2005/05/16 21:18:34 fvdl Exp $     */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -81,4 +81,11 @@
        long            tv_nsec;        /* nanoseconds */
 };
 
+#define LINUX_CLOCK_REALTIME           0
+#define LINUX_CLOCK_MONOTONIC          1
+#define LINUX_CLOCK_PROCESS_CPUTIME_ID 2
+#define LINUX_CLOCK_THREAD_CPUTIME_ID  3
+#define LINUX_CLOCK_REALTIME_HR                4
+#define LINUX_CLOCK_MONOTONIC_HR       5
+
 #endif /* _LINUX_SCHED_H */
diff -r 9b50807a0725 -r f2b23cf7c18b sys/compat/linux/common/linux_time.c
--- a/sys/compat/linux/common/linux_time.c      Mon May 16 21:18:18 2005 +0000
+++ b/sys/compat/linux/common/linux_time.c      Mon May 16 21:18:34 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_time.c,v 1.10 2005/05/03 16:26:30 manu Exp $ */
+/*     $NetBSD: linux_time.c,v 1.11 2005/05/16 21:18:34 fvdl Exp $ */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.10 2005/05/03 16:26:30 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.11 2005/05/16 21:18:34 fvdl Exp $");
 
 #include <sys/param.h>
 #include <sys/ucred.h>
@@ -48,12 +48,23 @@
 #include <sys/systm.h>
 #include <sys/sa.h>
 #include <sys/syscallargs.h>
+#include <sys/lwp.h>
+#include <sys/proc.h>
 
 #include <compat/linux/common/linux_types.h>
 #include <compat/linux/common/linux_signal.h>
+#include <compat/linux/common/linux_sched.h>
 
 #include <compat/linux/linux_syscallargs.h>
 
+#include <compat/common/compat_util.h>
+
+static void native_to_linux_timespec(struct linux_timespec *,
+                                    struct timespec *);
+static void linux_to_native_timespec(struct timespec *,
+                                    struct linux_timespec *);
+static int linux_to_native_clockid(clockid_t *, clockid_t);
+
 /*
  * This is not implemented for alpha yet
  */
@@ -68,10 +79,11 @@
  */
 struct timezone linux_sys_tz;
 
-int linux_sys_gettimeofday(l, v, retval)
-   struct lwp *l;
-   void *v;
-   register_t *retval;
+int
+linux_sys_gettimeofday(l, v, retval)
+       struct lwp *l;
+       void *v;
+       register_t *retval;
 {
        struct linux_sys_gettimeofday_args /* {
                syscallarg(struct timeval *) tz;
@@ -94,10 +106,11 @@
        return (0);
 }
 
-int linux_sys_settimeofday(l, v, retval)
-   struct lwp *l;
-   void *v;
-   register_t *retval;
+int
+linux_sys_settimeofday(l, v, retval)
+       struct lwp *l;
+       void *v;
+       register_t *retval;
 {
        struct linux_sys_settimeofday_args /* {
                syscallarg(struct timeval *) tz;
@@ -125,3 +138,227 @@
 }
 
 #endif /* __i386__ || __m68k__ || __powerpc__ || __mips__ || __arm__ */
+
+static void
+native_to_linux_timespec(struct linux_timespec *ltp, struct timespec *ntp)
+{
+       ltp->tv_sec = ntp->tv_sec;
+       ltp->tv_nsec = ntp->tv_nsec;
+}
+
+static void
+linux_to_native_timespec(struct timespec *ntp, struct linux_timespec *ltp)
+{
+       ntp->tv_sec = ltp->tv_sec;
+       ntp->tv_nsec = ltp->tv_nsec;
+}
+
+static int
+linux_to_native_clockid(clockid_t *n, clockid_t l)
+{
+       switch (l) {
+       case LINUX_CLOCK_REALTIME:
+               *n = CLOCK_REALTIME;
+               break;
+       case LINUX_CLOCK_MONOTONIC:
+               *n = CLOCK_MONOTONIC;
+               break;
+       case LINUX_CLOCK_PROCESS_CPUTIME_ID:
+       case LINUX_CLOCK_THREAD_CPUTIME_ID:
+       case LINUX_CLOCK_REALTIME_HR:
+       case LINUX_CLOCK_MONOTONIC_HR:
+               return EINVAL;
+       }
+
+       return 0;
+}
+
+int
+linux_sys_clock_gettime(l, v, retval)
+       struct lwp *l;
+       void *v;
+       register_t *retval;
+{
+       struct linux_sys_clock_gettime_args /* {
+               syscallarg(clockid_t) which;
+               syscallarg(struct linux_timespec *)tp;
+       } */ *uap = v;
+       caddr_t sg;
+       struct proc *p = l->l_proc;
+       struct timespec *tp, ts;
+       struct linux_timespec lts;
+       int error;
+       clockid_t nwhich;
+       struct sys_clock_gettime_args sga;
+
+       error = linux_to_native_clockid(&nwhich, SCARG(uap, which));
+       if (error != 0)
+               return error;
+       sg = stackgap_init(p, 0);
+       tp = stackgap_alloc(p, &sg, sizeof *tp);
+
+       SCARG(&sga, clock_id) = nwhich;
+       SCARG(&sga, tp) = tp;
+
+       error = sys_clock_gettime(l, &sga, retval);
+       if (error != 0)
+               return error;
+
+       error = copyin(tp, &ts, sizeof ts);
+       if (error != 0)
+               return error;
+
+       native_to_linux_timespec(&lts, &ts);
+
+       return copyout(&lts, SCARG(uap, tp), sizeof lts);
+}
+
+int
+linux_sys_clock_settime(l, v, retval)
+       struct lwp *l;
+       void *v;
+       register_t *retval;
+{
+       struct linux_sys_clock_settime_args /* {
+               syscallarg(clockid_t) which;
+               syscallarg(struct linux_timespec *)tp;
+       } */ *uap = v;
+       caddr_t sg;
+       struct proc *p = l->l_proc;
+       struct timespec *tp, ts;
+       struct linux_timespec lts;
+       int error;
+       clockid_t nwhich;
+       struct sys_clock_settime_args sta;
+
+       error = linux_to_native_clockid(&nwhich, SCARG(uap, which));
+       if (error != 0)
+               return error;
+
+       error = copyin(SCARG(uap, tp), &lts, sizeof lts);
+       if (error != 0)
+               return error;
+
+       linux_to_native_timespec(&ts, &lts);
+
+       sg = stackgap_init(p, 0);
+       tp = stackgap_alloc(p, &sg, sizeof *tp);
+       error = copyout(&ts, tp, sizeof ts);
+       if (error != 0)
+               return error;
+
+       SCARG(&sta, clock_id) = nwhich;
+       SCARG(&sta, tp) = tp;
+
+       return sys_clock_settime(l, &sta, retval);
+}
+
+int
+linux_sys_clock_getres(l, v, retval)
+       struct lwp *l;
+       void *v;
+       register_t *retval;
+{
+       struct linux_sys_clock_gettime_args /* {
+               syscallarg(clockid_t) which;
+               syscallarg(struct linux_timespec *)tp;
+       } */ *uap = v;
+       caddr_t sg;
+       struct proc *p = l->l_proc;
+       struct timespec *tp, ts;
+       struct linux_timespec lts;
+       int error;
+       clockid_t nwhich;
+       struct sys_clock_gettime_args sga;
+
+       error = linux_to_native_clockid(&nwhich, SCARG(uap, which));
+       if (error != 0)
+               return error;
+
+       if (SCARG(uap, tp) != NULL) {
+               sg = stackgap_init(p, 0);
+               tp = stackgap_alloc(p, &sg, sizeof *tp);
+       } else
+               tp = NULL;
+
+       SCARG(&sga, clock_id) = nwhich;
+       SCARG(&sga, tp) = tp;
+
+       error = sys_clock_getres(l, &sga, retval);
+       if (error != 0)
+               return error;
+
+       if (tp != NULL) {
+               error = copyin(tp, &ts, sizeof ts);
+               if (error != 0)
+                       return error;
+               native_to_linux_timespec(&lts, &ts);
+
+               return copyout(&lts, SCARG(uap, tp), sizeof lts);
+       }
+
+       return 0;
+}
+
+int
+linux_sys_clock_nanosleep(l, v, retval)
+       struct lwp *l;
+       void *v;
+       register_t *retval;
+{
+       struct linux_sys_clock_nanosleep_args /* {
+               syscallarg(clockid_t) which;
+               syscallarg(int) flags;
+               syscallarg(struct linux_timespec) *rqtp;
+               syscallarg(struct linux_timespec) *rmtp;
+       } */ *uap = v;
+       caddr_t sg;
+       struct proc *p = l->l_proc;
+       struct timespec *rqtp, *rmtp;
+       struct linux_timespec lrqts, lrmts;
+       struct timespec rqts, rmts;
+       int error;
+       struct sys_nanosleep_args sna;
+
+       if (SCARG(uap, flags) != 0)
+               return EINVAL;          /* XXX deal with TIMER_ABSTIME */
+
+       if (SCARG(uap, which) != LINUX_CLOCK_REALTIME)
+               return EINVAL;
+
+       error = copyin(SCARG(uap, rqtp), &lrqts, sizeof lrqts);
+       if (error != 0)
+               return error;
+
+       linux_to_native_timespec(&rqts, &lrqts);
+
+       sg = stackgap_init(p, 0);
+       rqtp = stackgap_alloc(p, &sg, sizeof *rqtp);
+       error = copyout(&rqts, rqtp, sizeof rqts);
+       if (error != 0)
+               return error;
+
+       if (SCARG(uap, rmtp) != NULL)



Home | Main Index | Thread Index | Old Index