Applied, thanks!

Damien Zammit, le dim. 21 sept. 2025 09:14:04 +0000, a ecrit:
> Between reading mtime and reading hpclock_read_counter,
> there may be an interrupt that updates mtime, therefore
> we need a check to perform the clock read process again
> in this case.
> 
> TESTED: on UP using:
> 
> ```
> \#include <stdio.h>
> \#include <time.h>
> 
> int main()
> {
>   struct timespec ts, now;
>   int i;
>   int cnt = 0;
> 
>   clock_gettime(CLOCK_MONOTONIC, &ts);
> 
>   for (i = 0; i < 10000000; i++) {
>     clock_gettime(CLOCK_MONOTONIC, &now);
>     if ((now.tv_nsec < ts.tv_nsec) && (now.tv_sec <= ts.tv_sec)) {
>       printf("BACKWARDS\n");
>       cnt++;
>       printf("  %u %09lu\n  %u %09lu\n\n",
>         ts.tv_sec, ts.tv_nsec,
>         now.tv_sec, now.tv_nsec
>       );
>     }
>     ts = now;
>   }
>   printf("went backwards %d out of %d times\n", cnt, i);
>   return 0;
> }
> ```
> 
> Before the change, some backward transitions were detected.
> After this change, none were detected.
> ---
>  kern/mach_clock.c | 20 +++++++++++++-------
>  1 file changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/kern/mach_clock.c b/kern/mach_clock.c
> index 3be0fb74..1c2ba0cb 100644
> --- a/kern/mach_clock.c
> +++ b/kern/mach_clock.c
> @@ -132,24 +132,30 @@ MACRO_END
>  
>  #define read_mapped_time(time)                                               
> \
>  MACRO_BEGIN                                                          \
> +     uint32_t _last_hpc;                                             \
>       do {                                                            \
> +             _last_hpc = last_hpc_read;                              \
>               (time)->seconds = mtime->time_value.seconds;            \
>               __sync_synchronize();                                   \
>               (time)->nanoseconds = mtime->time_value.nanoseconds;    \
>               __sync_synchronize();                                   \
> -     } while ((time)->seconds != mtime->check_seconds64);            \
> -     time_value64_add_hpc(time);                                     \
> +     } while (((time)->seconds != mtime->check_seconds64)            \
> +           || (_last_hpc != last_hpc_read));                         \
> +     time_value64_add_hpc(time, _last_hpc);                          \
>  MACRO_END
>  
> -#define read_mapped_uptime(uptime)                                   \
> +#define read_mapped_uptime(uptime)                                   \
>  MACRO_BEGIN                                                          \
> +     uint32_t _last_hpc;                                             \
>       do {                                                            \
> +             _last_hpc = last_hpc_read;                              \
>               (uptime)->seconds = mtime->uptime_value.seconds;        \
>               __sync_synchronize();                                   \
>               (uptime)->nanoseconds = mtime->uptime_value.nanoseconds;\
>               __sync_synchronize();                                   \
> -     } while ((uptime)->seconds != mtime->check_upseconds64);        \
> -     time_value64_add_hpc(uptime);                                   \
> +     } while (((uptime)->seconds != mtime->check_upseconds64)        \
> +           || (_last_hpc != last_hpc_read));                         \
> +     time_value64_add_hpc(uptime, _last_hpc);                        \
>  MACRO_END
>  
>  def_simple_lock_irq_data(static,     timer_lock)     /* lock for ... */
> @@ -443,11 +449,11 @@ clock_boottime_update(const struct time_value64 
> *new_time)
>   * Add the time value since last clock interrupt in nanosecond.
>   */
>  static void
> -time_value64_add_hpc(time_value64_t *value)
> +time_value64_add_hpc(time_value64_t *value, uint32_t last_hpc)
>  {
>       uint32_t now = hpclock_read_counter();
>       /* Time since last clock interrupt in nanosecond.  */
> -     int64_t ns = (now - last_hpc_read) * hpclock_get_counter_period_nsec();
> +     int64_t ns = (now - last_hpc) * hpclock_get_counter_period_nsec();
>  
>       /* Limit the value of ns under the period of a clock interrupt.  */
>       if (ns >= tick * 1000)
> -- 
> 2.45.2
> 
> 
> 

-- 
Samuel
>Ever heard of .cshrc?
That's a city in Bosnia.  Right?
(Discussion in comp.os.linux.misc on the intuitiveness of commands.)

Reply via email to