bug-gnulib
[Top][All Lists]
Advanced

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

Re: utimensat round 3


From: Jim Meyering
Subject: Re: utimensat round 3
Date: Fri, 16 Oct 2009 14:01:08 +0200

Jim Meyering wrote:
...
> Note however, that test-utimens is failing for me
> on an ext4 + Fedora-12-alpha-based system due to this:
>
>     /* See comment above about this utimecmp call.  */
>     ASSERT (0 <= utimecmp (BASE "file", &st2, &st1, 
> UTIMECMP_TRUNCATE_SOURCE));
>
> That utimecmp assertion fails almost all the time due to the
> comparison of two time stamps independently down-sampled
> at different resolutions.
>
> It wasn't clear right away to me, so I wrote a program to
> call clock_gettime, then utimensat-to-set-to-NOW, then stat.
> Compare the clock_gettime result with st_mtime second and nanosecond values.
>
> I see ~1-millisecond-resolution FS timestamps
> and higher-resolution clock_gettime times:
>
> d.ns: stat.ns - now.ns
>
> ds   d.ns            stat.ns      now.ns  (now.ns[i] - now.ns[i-1])
> ==========================================
> 0  -579637         510150007    510729644 (0)
> 0  -656640         510150007    510806647 (77003)
> 0  -716861         510150007    510866868 (60221)
> 0  -776398         510150007    510926405 (59537)
> 0  -835731         510150007    510985738 (59333)
> 0  -934985         510150007    511084992 (99254)
> 0     3891 !!!     511150073    511146182 (61190)
> 0   -55913         511150073    511205986 (59804)
> 0  -115589         511150073    511265662 (59676)
> 0  -175220         511150073    511325293 (59631)
> 0  -234472         511150073    511384545 (59252)
> 0  -293974         511150073    511444047 (59502)
> 0  -353255         511150073    511503328 (59281)
> 0  -412612         511150073    511562685 (59357)
> 0  -472069         511150073    511622142 (59457)
> 0  -531468         511150073    511681541 (59399)
> 0  -591027         511150073    511741100 (59559)
> 0  -650239         511150073    511800312 (59212)
> 0  -709527         511150073    511859600 (59288)
> 0  -769023         511150073    511919096 (59496)
> 0  -828184         511150073    511978257 (59161)
> 0  -899541         511150073    512049614 (71357)
> 0  -959895         511150073    512109968 (60354)
> 0   -19442         512150046    512169488 (59520)
> 0   -78649         512150046    512228695 (59207)
> 0  -138054         512150046    512288100 (59405)
> 0  -197514         512150046    512347560 (59460)
> 0  -256642         512150046    512406688 (59128)
> 0  -315945         512150046    512465991 (59303)
> 0  -375208         512150046    512525254 (59263)
> 0  -434469         512150046    512584515 (59261)
> 0  -493769         512150046    512643815 (59300)
> 0  -553978         512150046    512704024 (60209)
> 0  -613284         512150046    512763330 (59306)
> 0  -672490         512150046    512822536 (59206)
> 0  -731724         512150046    512881770 (59234)
> 0  -790961         512150046    512941007 (59237)
> 0  -850143         512150046    513000189 (59182)
> 0  -920239         512150046    513070285 (70096)
> 0    20804 !!!     513150503    513129699 (59414)
> 0   -39840         513150503    513190343 (60644)
> 0   -99067         513150503    513249570 (59227)
> 0  -158482         513150503    513308985 (59415)
> 0  -217610         513150503    513368113 (59128)
> ...
>
> This failure may also be due to the way utimecmp works,
> but I haven't delved into that code today.

FYI, here's the program I used to print the above table:

#define _GNU_SOURCE 1
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>

#define BASE "test-utimens.t"

#define ASSERT(expr) \
  do                                                                         \
    {                                                                        \
      if (!(expr))                                                           \
        {                                                                    \
          fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__);  \
          fflush (stderr);                                                   \
          abort ();                                                          \
        }                                                                    \
    }                                                                        \
  while (0)

#define func(a,b) utimensat(AT_FDCWD,a,b,0)

int
main (int argc, char **argv)
{
  if (argc < 2)
    abort ();

  int signed_n = atoi (argv[1]);
  if (signed_n < 0)
    abort ();
  unsigned int n = signed_n;

  ASSERT (close (creat (BASE "file", 0600)) == 0);

  unsigned long prev_now_ns = 0;

  printf ("ds %8s %3s %12s %11s\n", "d.ns", "", "stat.ns", "now.ns");
  printf ("==========================================\n");
  unsigned int i;
  for (i = 0; i < n; i++)
    {

      struct stat st3;
      struct timespec ts[2] = { {0, UTIME_OMIT}, {0, UTIME_NOW} };
      struct timespec now;
      clock_gettime (CLOCK_REALTIME, &now);
      ASSERT (func (BASE "file", ts) == 0);
      ASSERT (stat (BASE "file", &st3) == 0);
      long s_diff = st3.st_mtime - now.tv_sec;
      long ns_diff = st3.st_mtim.tv_nsec - now.tv_nsec;
      long delta_now = (i == 0 ? 0 : now.tv_nsec - prev_now_ns);
      printf ("%ld %8ld %3s  %12ld %12ld (%ld)\n", s_diff, ns_diff,
              s_diff || 0 < ns_diff ? "!!!" : "",
              st3.st_mtim.tv_nsec, now.tv_nsec, delta_now);
      prev_now_ns = now.tv_nsec;
    }

  /* Cleanup.  */
  ASSERT (unlink (BASE "file") == 0);

  return 0;
}
------------------------------------------------------

I compiled and ran it like this:

    gcc -W -Wall -Wformat -Wextra utimens.c -lrt && ./a.out 100

Note: not intended to be portable.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]