From 23a1110cbd2889bf34fdce2bdd1f818822404f2d Mon Sep 17 00:00:00 2001 From: cube Date: Sat, 23 Jul 2005 18:56:15 +0000 Subject: [PATCH] Implement the timer_create(2) family of syscalls. --- sys/compat/netbsd32/netbsd32.h | 23 +++++- sys/compat/netbsd32/netbsd32_conv.h | 17 ++++- sys/compat/netbsd32/netbsd32_time.c | 114 +++++++++++++++++++++++++++- sys/compat/netbsd32/syscalls.master | 15 ++-- 4 files changed, 159 insertions(+), 10 deletions(-) diff --git a/sys/compat/netbsd32/netbsd32.h b/sys/compat/netbsd32/netbsd32.h index db838d4360fe..eb9bf28e9f7d 100644 --- a/sys/compat/netbsd32/netbsd32.h +++ b/sys/compat/netbsd32/netbsd32.h @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32.h,v 1.35 2005/07/13 11:53:57 cube Exp $ */ +/* $NetBSD: netbsd32.h,v 1.36 2005/07/23 18:56:15 cube Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -126,6 +126,7 @@ struct netbsd32_iovec { /* from */ typedef int32_t netbsd32_timer_t; typedef int32_t netbsd32_time_t; +typedef netbsd32_pointer_t netbsd32_timerp_t; typedef netbsd32_pointer_t netbsd32_timespecp_t; struct netbsd32_timespec { @@ -151,6 +152,12 @@ struct netbsd32_itimerval { struct netbsd32_timeval it_value; /* current value */ }; +typedef netbsd32_pointer_t netbsd32_itimerspecp_t; +struct netbsd32_itimerspec { + struct netbsd32_timespec it_interval; + struct netbsd32_timespec it_value; +}; + /* from */ typedef netbsd32_pointer_t netbsd32_fidp_t; @@ -386,6 +393,20 @@ struct netbsd32_sigvec { int sv_flags; /* see signal options below */ }; +union netbsd32_sigval { + int sival_int; + netbsd32_voidp sival_ptr; +}; + +typedef netbsd32_pointer_t netbsd32_sigeventp_t; +struct netbsd32_sigevent { + int sigev_notify; + int sigev_signo; + union netbsd32_sigval sigev_value; + netbsd32_voidp sigev_notify_function; + netbsd32_voidp sigev_notify_attributes; +}; + /* from */ typedef netbsd32_pointer_t netbsd32_sockaddrp_t; typedef netbsd32_pointer_t netbsd32_osockaddrp_t; diff --git a/sys/compat/netbsd32/netbsd32_conv.h b/sys/compat/netbsd32/netbsd32_conv.h index ad77a82117d7..9e52de8fa317 100644 --- a/sys/compat/netbsd32/netbsd32_conv.h +++ b/sys/compat/netbsd32/netbsd32_conv.h @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_conv.h,v 1.5 2005/02/26 23:10:21 perry Exp $ */ +/* $NetBSD: netbsd32_conv.h,v 1.6 2005/07/23 18:56:15 cube Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -79,6 +79,7 @@ static __inline void netbsd32_from_shmid_ds __P((struct shmid_ds *, struct netbs static __inline void netbsd32_to_semid_ds __P((struct netbsd32_semid_ds *, struct semid_ds *)); static __inline void netbsd32_from_semid_ds __P((struct semid_ds *, struct netbsd32_semid_ds *)); static __inline void netbsd32_from_loadavg __P((struct netbsd32_loadavg *, struct loadavg *)); +static __inline void netbsd32_to_sigevent(struct netbsd32_sigevent *, struct sigevent *); /* converters for structures that we need */ static __inline void @@ -535,4 +536,18 @@ netbsd32_from_loadavg(av32, av) av32->fscale = (netbsd32_long)av->fscale; } +static __inline void +netbsd32_to_sigevent(struct netbsd32_sigevent *ev32, struct sigevent *ev) +{ + ev->sigev_notify = ev32->sigev_notify; + ev->sigev_signo = ev32->sigev_signo; + /* + * XXX sival_ptr, sigev_notify_function and + * sigev_notify_attributes are currently unused + */ + ev->sigev_value.sival_int = ev32->sigev_value.sival_int; + ev->sigev_notify_function = (void *)(intptr_t)ev32->sigev_notify_function; + ev->sigev_notify_attributes = (void *)(intptr_t)ev32->sigev_notify_attributes; +} + #endif /* _COMPAT_NETBSD32_NETBSD32_CONV_H_ */ diff --git a/sys/compat/netbsd32/netbsd32_time.c b/sys/compat/netbsd32/netbsd32_time.c index dc6a5e3034a2..64e6df5d6d55 100644 --- a/sys/compat/netbsd32/netbsd32_time.c +++ b/sys/compat/netbsd32/netbsd32_time.c @@ -1,4 +1,4 @@ -/* $NetBSD: netbsd32_time.c,v 1.10 2005/07/11 19:50:42 cube Exp $ */ +/* $NetBSD: netbsd32_time.c,v 1.11 2005/07/23 18:56:15 cube Exp $ */ /* * Copyright (c) 1998, 2001 Matthew R. Green @@ -29,7 +29,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: netbsd32_time.c,v 1.10 2005/07/11 19:50:42 cube Exp $"); +__KERNEL_RCSID(0, "$NetBSD: netbsd32_time.c,v 1.11 2005/07/23 18:56:15 cube Exp $"); #if defined(_KERNEL_OPT) #include "opt_ntp.h" @@ -628,3 +628,113 @@ netbsd32_nanosleep(l, v, retval) return error; } + +static int +netbsd32_timer_create_fetch(const void *src, void *dst, size_t size) +{ + struct sigevent *evp = dst; + struct netbsd32_sigevent ev32; + int error; + + error = copyin(src, &ev32, sizeof(ev32)); + if (error) + return error; + + netbsd32_to_sigevent(&ev32, evp); + return 0; +} + +int +netbsd32_timer_create(struct lwp *l, void *v, register_t *retval) +{ + struct netbsd32_timer_create_args /* { + syscallarg(netbsd32_clockid_t) clock_id; + syscallarg(netbsd32_sigeventp_t) evp; + syscallarg(netbsd32_timerp_t) timerid; + } */ *uap = v; + + return timer_create1(NETBSD32PTR64(SCARG(uap, timerid)), + SCARG(uap, clock_id), NETBSD32PTR64(SCARG(uap, evp)), + netbsd32_timer_create_fetch, l->l_proc); +} + +int +netbsd32_timer_delete(struct lwp *l, void *v, register_t *retval) +{ + struct netbsd32_timer_delete_args /* { + syscallarg(netbsd32_timer_t) timerid; + } */ *uap = v; + struct sys_timer_delete_args ua; + + NETBSD32TO64_UAP(timerid); + return sys_timer_delete(l, (void *)&ua, retval); +} + +int +netbsd32_timer_settime(struct lwp *l, void *v, register_t *retval) +{ + struct netbsd32_timer_settime_args /* { + syscallarg(netbsd32_timer_t) timerid; + syscallarg(int) flags; + syscallarg(const netbsd32_itimerspecp_t) value; + syscallarg(netbsd32_itimerspecp_t) ovalue; + } */ *uap = v; + int error; + struct itimerspec value, ovalue, *ovp = NULL; + struct netbsd32_itimerspec its32; + + if ((error = copyin(NETBSD32PTR64(SCARG(uap, value)), &its32, + sizeof(its32))) != 0) + return (error); + netbsd32_to_timespec(&its32.it_interval, &value.it_interval); + netbsd32_to_timespec(&its32.it_value, &value.it_value); + + if (SCARG(uap, ovalue)) + ovp = &ovalue; + + if ((error = dotimer_settime(SCARG(uap, timerid), &value, ovp, + SCARG(uap, flags), l->l_proc)) != 0) + return error; + + if (ovp) { + netbsd32_from_timespec(&ovp->it_interval, &its32.it_interval); + netbsd32_from_timespec(&ovp->it_value, &its32.it_value); + return copyout(&its32, NETBSD32PTR64(SCARG(uap, ovalue)), + sizeof(its32)); + } + return 0; +} + +int +netbsd32_timer_gettime(struct lwp *l, void *v, register_t *retval) +{ + struct netbsd32_timer_gettime_args /* { + syscallarg(netbsd32_timer_t) timerid; + syscallarg(netbsd32_itimerspecp_t) value; + } */ *uap = v; + int error; + struct itimerspec its; + struct netbsd32_itimerspec its32; + + if ((error = dotimer_gettime(SCARG(uap, timerid), l->l_proc, + &its)) != 0) + return error; + + netbsd32_from_timespec(&its.it_interval, &its32.it_interval); + netbsd32_from_timespec(&its.it_value, &its32.it_value); + + return copyout(&its32, (caddr_t)NETBSD32PTR64(SCARG(uap, value)), + sizeof(its32)); +} + +int +netbsd32_timer_getoverrun(struct lwp *l, void *v, register_t *retval) +{ + struct netbsd32_timer_getoverrun_args /* { + syscallarg(netbsd32_timer_t) timerid; + } */ *uap = v; + struct sys_timer_getoverrun_args ua; + + NETBSD32TO64_UAP(timerid); + return sys_timer_getoverrun(l, (void *)&ua, retval); +} diff --git a/sys/compat/netbsd32/syscalls.master b/sys/compat/netbsd32/syscalls.master index a4cac2596a2a..2cc520e926c2 100644 --- a/sys/compat/netbsd32/syscalls.master +++ b/sys/compat/netbsd32/syscalls.master @@ -1,4 +1,4 @@ - $NetBSD: syscalls.master,v 1.35 2005/07/12 07:45:34 cube Exp $ + $NetBSD: syscalls.master,v 1.36 2005/07/23 18:56:15 cube Exp $ ; from: NetBSD: syscalls.master,v 1.81 1998/07/05 08:49:50 jonathan Exp ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -392,11 +392,14 @@ 232 STD { int netbsd32_clock_gettime(netbsd32_clockid_t clock_id, netbsd32_timespecp_t tp); } 233 STD { int netbsd32_clock_settime(netbsd32_clockid_t clock_id, const netbsd32_timespecp_t tp); } 234 STD { int netbsd32_clock_getres(netbsd32_clockid_t clock_id, netbsd32_timespecp_t tp); } -235 UNIMPL timer_create -236 UNIMPL timer_delete -237 UNIMPL timer_settime -238 UNIMPL timer_gettime -239 UNIMPL timer_getoverrun +235 STD { int netbsd32_timer_create(netbsd32_clockid_t clock_id, netbsd32_sigeventp_t evp, \ + netbsd32_timerp_t timerid); } +236 STD { int netbsd32_timer_delete(netbsd32_timer_t timerid); } +237 STD { int netbsd32_timer_settime(netbsd32_timer_t timerid, int flags, \ + const netbsd32_itimerspecp_t value, \ + netbsd32_itimerspecp_t ovalue); } +238 STD { int netbsd32_timer_gettime(netbsd32_timer_t timerid, netbsd32_itimerspecp_t value); } +239 STD { int netbsd32_timer_getoverrun(netbsd32_timer_t timerid); } ; ; Syscalls 240-269 are reserved for other IEEE Std1003.1b syscalls ;