authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-17 21:24:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-08-17 21:26:33-07:00
logce8b9c0c5cdbe4161952e6f2aa875f722949d4cb
treedfe8510900d080451cc4a20ce440fb67e311fa69
parent27cb23cbc5fe35d0eae8494006ba93111bd2bde6

std.cache_hash: don't trust mtime granularity to be better than 1ms

I empirically observed mtime not changing when rapidly writing the same file name within the same millisecond of wall clock time, despite the mtime field having nanosecond precision. I believe this fixes the CI test failures.

1 files changed, 22 insertions(+), 10 deletions(-)

lib/std/cache_hash.zig+22-10
...@@ -466,7 +466,16 @@ fn isProblematicTimestamp(fs_clock: i128) bool {...@@ -466,7 +466,16 @@ fn isProblematicTimestamp(fs_clock: i128) bool {
466 } else {466 } else {
467 wall_nsec &= @as(i64, -1) << @intCast(u6, @ctz(i64, fs_nsec));467 wall_nsec &= @as(i64, -1) << @intCast(u6, @ctz(i64, fs_nsec));
468 }468 }
469 return wall_nsec == fs_nsec and wall_sec == fs_sec;469 if (wall_nsec == fs_nsec and wall_sec == fs_sec)
470 return true;
471
472 // I have also observed precision problems at a millisecond granularity.
473 const fs_msec = @intCast(i64, @divFloor(fs_clock, std.time.ns_per_ms * 2));
474 const wall_msec = @intCast(i64, @divFloor(wall_clock, std.time.ns_per_ms * 2));
475 if (fs_msec == wall_msec)
476 return true;
477
478 return false;
470}479}
471480
472test "cache file and then recall it" {481test "cache file and then recall it" {
...@@ -479,9 +488,10 @@ test "cache file and then recall it" {...@@ -479,9 +488,10 @@ test "cache file and then recall it" {
479 const temp_file = "test.txt";488 const temp_file = "test.txt";
480 const temp_manifest_dir = "temp_manifest_dir";489 const temp_manifest_dir = "temp_manifest_dir";
481490
491 const ts = std.time.nanoTimestamp();
482 try cwd.writeFile(temp_file, "Hello, world!\n");492 try cwd.writeFile(temp_file, "Hello, world!\n");
483493
484 while (isProblematicTimestamp(std.time.nanoTimestamp())) {494 while (isProblematicTimestamp(ts)) {
485 std.time.sleep(1);495 std.time.sleep(1);
486 }496 }
487497
...@@ -545,9 +555,13 @@ test "check that changing a file makes cache fail" {...@@ -545,9 +555,13 @@ test "check that changing a file makes cache fail" {
545 const original_temp_file_contents = "Hello, world!\n";555 const original_temp_file_contents = "Hello, world!\n";
546 const updated_temp_file_contents = "Hello, world; but updated!\n";556 const updated_temp_file_contents = "Hello, world; but updated!\n";
547557
558 try cwd.deleteTree(temp_manifest_dir);
559 try cwd.deleteTree(temp_file);
560
561 const ts = std.time.nanoTimestamp();
548 try cwd.writeFile(temp_file, original_temp_file_contents);562 try cwd.writeFile(temp_file, original_temp_file_contents);
549563
550 while (isProblematicTimestamp(std.time.nanoTimestamp())) {564 while (isProblematicTimestamp(ts)) {
551 std.time.sleep(1);565 std.time.sleep(1);
552 }566 }
553567
...@@ -571,10 +585,6 @@ test "check that changing a file makes cache fail" {...@@ -571,10 +585,6 @@ test "check that changing a file makes cache fail" {
571585
572 try cwd.writeFile(temp_file, updated_temp_file_contents);586 try cwd.writeFile(temp_file, updated_temp_file_contents);
573587
574 while (isProblematicTimestamp(std.time.nanoTimestamp())) {
575 std.time.sleep(1);
576 }
577
578 {588 {
579 var ch = try CacheHash.init(testing.allocator, cwd, temp_manifest_dir);589 var ch = try CacheHash.init(testing.allocator, cwd, temp_manifest_dir);
580 defer ch.release();590 defer ch.release();
...@@ -594,7 +604,7 @@ test "check that changing a file makes cache fail" {...@@ -594,7 +604,7 @@ test "check that changing a file makes cache fail" {
594 testing.expect(!mem.eql(u8, digest1[0..], digest2[0..]));604 testing.expect(!mem.eql(u8, digest1[0..], digest2[0..]));
595605
596 try cwd.deleteTree(temp_manifest_dir);606 try cwd.deleteTree(temp_manifest_dir);
597 try cwd.deleteFile(temp_file);607 try cwd.deleteTree(temp_file);
598}608}
599609
600test "no file inputs" {610test "no file inputs" {
...@@ -643,10 +653,11 @@ test "CacheHashes with files added after initial hash work" {...@@ -643,10 +653,11 @@ test "CacheHashes with files added after initial hash work" {
643 const temp_file2 = "cache_hash_post_file_test2.txt";653 const temp_file2 = "cache_hash_post_file_test2.txt";
644 const temp_manifest_dir = "cache_hash_post_file_manifest_dir";654 const temp_manifest_dir = "cache_hash_post_file_manifest_dir";
645655
656 const ts1 = std.time.nanoTimestamp();
646 try cwd.writeFile(temp_file1, "Hello, world!\n");657 try cwd.writeFile(temp_file1, "Hello, world!\n");
647 try cwd.writeFile(temp_file2, "Hello world the second!\n");658 try cwd.writeFile(temp_file2, "Hello world the second!\n");
648659
649 while (isProblematicTimestamp(std.time.nanoTimestamp())) {660 while (isProblematicTimestamp(ts1)) {
650 std.time.sleep(1);661 std.time.sleep(1);
651 }662 }
652663
...@@ -680,9 +691,10 @@ test "CacheHashes with files added after initial hash work" {...@@ -680,9 +691,10 @@ test "CacheHashes with files added after initial hash work" {
680 testing.expect(mem.eql(u8, &digest1, &digest2));691 testing.expect(mem.eql(u8, &digest1, &digest2));
681692
682 // Modify the file added after initial hash693 // Modify the file added after initial hash
694 const ts2 = std.time.nanoTimestamp();
683 try cwd.writeFile(temp_file2, "Hello world the second, updated\n");695 try cwd.writeFile(temp_file2, "Hello world the second, updated\n");
684696
685 while (isProblematicTimestamp(std.time.nanoTimestamp())) {697 while (isProblematicTimestamp(ts2)) {
686 std.time.sleep(1);698 std.time.sleep(1);
687 }699 }
688700