Thanks. Again, my review inline below.

--
Nadav Har'El
n...@scylladb.com


On Wed, May 10, 2023 at 11:58 AM luca abeni <lucab...@gmail.com> wrote:

> From: Claudio Fontana <claudio.font...@huawei.com>
>
> we only support CLOCK_MONOTONIC, and we don't support remainder
> due to the signal implementation.
>
> Signed-off-by: Claudio Fontana <claudio.font...@huawei.com>
> ---
>  include/osv/sched.hh | 10 +++++++++
>  libc/time.cc         | 49 +++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 58 insertions(+), 1 deletion(-)
>
> diff --git a/include/osv/sched.hh b/include/osv/sched.hh
> index c1f414ba..03502c38 100644
> --- a/include/osv/sched.hh
> +++ b/include/osv/sched.hh
> @@ -513,6 +513,8 @@ public:
>      inline void wake_with_from_mutex(Action action);
>      template <class Rep, class Period>
>      static void sleep(std::chrono::duration<Rep, Period> duration);
> +    template <class Clock, class Duration>
> +    static void sleep(std::chrono::time_point<Clock, Duration>
> time_point);
>

The function name sleep() is deeply ingrained in C / Unix / Linux users'
minds as something that takes
a relative time (duration) as parameter (i.e., sleep for N seconds), not a
deadline (time_point).
So I suggest giving this new function a different name. A good name is
"sleep_until", this is also the
name that C++'s thread API uses:
https://en.cppreference.com/w/cpp/thread/sleep_until


>      /**
>       * Let the other thread on the current CPU run if there is any.
>       *
> @@ -1407,6 +1409,14 @@ void thread::sleep(std::chrono::duration<Rep,
> Period> duration)
>      sleep_impl(t);
>  }
>
> +template <class Clock, class Duration>
> +void thread::sleep(std::chrono::time_point<Clock, Duration> time_point)
> +{
> +    timer t(*current());
> +    t.set(time_point);
> +    wait_until([&] { return t.expired(); });
> +}
> +
>  template <class Action>
>  inline
>  void thread::wake_with_irq_or_preemption_disabled(Action action)
> diff --git a/libc/time.cc b/libc/time.cc
> index 2660eb86..c31f31fd 100644
> --- a/libc/time.cc
> +++ b/libc/time.cc
> @@ -15,7 +15,18 @@
>  #include <osv/sched.hh>
>  #include "pthread.hh"
>
> -u64 convert(const timespec& ts)
> +#define timespecisset(t) ((t)->tv_sec || (t)->tv_nsec)
> +#define timespecclear(t) ((t)->tv_sec = (t)->tv_nsec = 0)
> +#define timespeccmp(s,t,op) ((s)->tv_sec == (t)->tv_sec ? \
> +                             (s)->tv_nsec op (t)->tv_nsec : (s)->tv_sec
> op (t)->tv_sec)
> +#define timespecadd(s,t,a) ( (a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \
> +        ((a)->tv_nsec = (s)->tv_nsec + (t)->tv_nsec) >= 1000000000L && \
> +                          ((a)->tv_nsec -= 1000000000L, (a)->tv_sec++) )
> +#define timespecsub(s,t,a) ( (a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \
> +        ((a)->tv_nsec = (s)->tv_nsec - (t)->tv_nsec) < 0 && \
> +                          ((a)->tv_nsec += 1000000000L, (a)->tv_sec--) )
>

Unless I'm missing something, you aren't using any of these macros below,
just timespeccmp(),
so please remove all the unused ones.
In general we should  need functions to add or subtract timestamps, because
what we normally
would do is to convert the timespec to a std::chrono::timepoint, and those
we can add and
subtract with the "+" and "-" operators which are already implemented by
std::chrono. We can
also do the same with <=, by the way.

By the way, in modern C++ (and C), it's much nicer to replace macros by
inline
functions, which are easier to understand and also give you some
compile-time checking
on types, etc.


> +
> +static u64 convert(const timespec& ts)
>  {
>      return ts.tv_sec * 1000000000 + ts.tv_nsec;
>  }
> @@ -36,6 +47,9 @@ int gettimeofday(struct timeval* tv, struct timezone* tz)
>  OSV_LIBC_API
>  int nanosleep(const struct timespec* req, struct timespec* rem)
>  {
> +    if (!req || req->tv_nsec < 0 || req->tv_nsec >= 1000000000L ||
> req->tv_sec < 0)
> +        return libc_error(EINVAL);
> +
>      sched::thread::sleep(std::chrono::nanoseconds(convert(*req)));
>      return 0;
>  }
> @@ -127,3 +141,36 @@ clock_t clock(void)
>      clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
>      return ts.tv_sec * 1000000000L + ts.tv_nsec;
>  }
> +
> +int clock_nanosleep(clockid_t clock_id, int flags,
>

I think Waldek would like us to put the "OSV_LIBC_API" tag on functions
which implement the C library
functions - as we do above on nanosleep(). CCing Waldek to agree or correct
me.


> +                    const struct timespec *request,
> +                    struct timespec *remain)
> +{
> +    /* XXX we are implementing really only CLOCK_MONOTONIC, */
> +    /* and we don't support remain, due to signals. */
> +    if (remain) {
> +        UNIMPLEMENTED("clock_nanosleep(): remain not supported, due to
> signals");
> +    }
> +    if (clock_id != CLOCK_MONOTONIC) {
> +        UNIMPLEMENTED("clock_nanosleep(): only CLOCK_MONOTONIC is
> supported");
> +    }
> +
> +    switch (flags) {
> +    case 0:
> +        return nanosleep(request, NULL);
> +    case TIMER_ABSTIME: {
> +        struct timespec ts;
> +        if (clock_gettime(clock_id, &ts) != 0) {
> +            return -1;
> +        }
> +        if (timespeccmp(request, &ts, <=)) {
> +            return 0;
> +        }
>

Do we really need to do this check? Won't sched::thread::sleep() simply
silently return immediately
if the given time point is in the past? Please check, and if it just works,
you don't need the above if()s
at all, and don't need the timespeccmp function.


> +        sched::thread::sleep(osv::clock::uptime::time_point(
> +
>  osv::clock::uptime::duration(convert(*request))));
> +        return 0;
> +    }
> +    default:
> +        return libc_error(EINVAL);
> +    }
> +}
> --
> 2.30.2
>
> --
> You received this message because you are subscribed to the Google Groups
> "OSv Development" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to osv-dev+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/osv-dev/20230510085745.11416-5-luca.abeni%40santannapisa.it
> .
>

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/CANEVyjvAPVkwV3HemSAJGK74RGifjKexsMfLV%3D-ywvN1JHTGUw%40mail.gmail.com.

Reply via email to