Skip to content

Commit

Permalink
Use nanosecond-resolution timestamps consistently on all platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jun 18, 2023
1 parent 1778f4c commit 58ccc17
Show file tree
Hide file tree
Showing 14 changed files with 231 additions and 119 deletions.
11 changes: 5 additions & 6 deletions src/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <stdarg.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

Expand Down Expand Up @@ -620,15 +619,15 @@ static const char *diag_get_source(const loc_t *loc)
if (fd < 0)
return NULL;

struct stat buf;
if (fstat(fd, &buf) != 0)
file_info_t info;
if (!get_handle_info(fd, &info))
goto close_file;

if (!S_ISREG(buf.st_mode))
if (info.type != FILE_REGULAR)
goto close_file;

if (buf.st_size > 0)
file->linebuf = map_file(fd, buf.st_size);
if (info.size > 0)
file->linebuf = map_file(fd, info.size);

close_file:
close(fd);
Expand Down
17 changes: 11 additions & 6 deletions src/fbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,9 @@ static void fbuf_decompress(fbuf_t *f)
fatal("%s has was created with unexpected checksum algorithm %c",
f->fname, header[5]);

struct stat buf;
if (fstat(fileno(f->file), &buf) != 0)
fatal_errno("fstat");
file_info_t info;
if (!get_handle_info(fileno(f->file), &info))
fatal_errno("%s: cannot get file info", f->fname);

const uint32_t len = UNPACK_BE32(header + 8);
const uint32_t checksum = UNPACK_BE32(header + 12);
Expand All @@ -378,7 +378,7 @@ static void fbuf_decompress(fbuf_t *f)
if (header_sz == 0)
header_sz = 16; // Compatibility with 1.8 and earlier

uint32_t filesz = buf.st_size;
uint32_t filesz = info.size;
if (header_sz > 16) { // XXX: added in 1.10
uint8_t header2[4];
fbuf_read_raw(f, header2, sizeof(header2));
Expand All @@ -393,9 +393,9 @@ static void fbuf_decompress(fbuf_t *f)
f->userheader = UNPACK_BE32(header3);
}

if (filesz > buf.st_size)
if (filesz > info.size)
fatal("%s has inconsistent compressed size %u vs file size %zu",
f->fname, filesz, buf.st_size);
f->fname, filesz, info.size);

uint8_t *rmap = map_file(fileno(f->file), filesz);

Expand Down Expand Up @@ -471,6 +471,11 @@ const char *fbuf_file_name(fbuf_t *f)
return f->fname;
}

int fbuf_file_handle(fbuf_t *f)
{
return fileno(f->file);
}

static void fbuf_compress_fastlz(fbuf_t *f)
{
uint8_t out[SPILL_SIZE];
Expand Down
1 change: 1 addition & 0 deletions src/fbuf.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ fbuf_t *fbuf_open(const char *file, fbuf_mode_t mode, fbuf_cs_t csum);
void fbuf_close(fbuf_t *f, uint32_t *checksum);
void fbuf_cleanup(void);
const char *fbuf_file_name(fbuf_t *f);
int fbuf_file_handle(fbuf_t *f);

void fbuf_write_user_header(fbuf_t *f, const void *data, size_t size);
size_t fbuf_peek_user_header(const char *file, uint8_t *buf, size_t size);
Expand Down
6 changes: 2 additions & 4 deletions src/jit/jit-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#ifdef __MINGW32__
Expand Down Expand Up @@ -985,8 +983,8 @@ void jit_preload(jit_t *j)
tb_printf(tb, DIR_SEP "preload%s." DLL_EXT, preload_vers[standard()]);

const char *path = tb_get(tb);
struct stat st;
if (stat(path, &st) != 0 || !S_ISREG(st.st_mode))
file_info_t info;
if (!get_file_info(path, &info) || info.type != FILE_REGULAR)
fatal("missing preload library at %s", path);

j->preloadlib = load_dll_internal(j, path);
Expand Down
107 changes: 39 additions & 68 deletions src/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "util.h"
#include "common.h"
#include "diag.h"
#include "fbuf.h"
#include "hash.h"
#include "lib.h"
#include "object.h"
Expand All @@ -37,7 +38,6 @@
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>

Expand All @@ -48,15 +48,13 @@ typedef struct _lib_unit lib_unit_t;

#define INDEX_FILE_MAGIC 0x55225511

typedef uint64_t lib_mtime_t;

struct _lib_unit {
object_t *object;
ident_t name;
tree_kind_t kind;
bool dirty;
bool error;
lib_mtime_t mtime;
uint64_t mtime;
vcode_unit_t vcode;
lib_seq_t sequence;
lib_unit_t *next;
Expand All @@ -74,7 +72,7 @@ struct _lib {
hash_t *lookup;
lib_unit_t *units;
lib_index_t *index;
lib_mtime_t index_mtime;
uint64_t index_mtime;
off_t index_size;
int lock_fd;
bool readonly;
Expand All @@ -98,7 +96,6 @@ static lib_list_t *loaded = NULL;
static search_path_t *search_paths = NULL;

static text_buf_t *lib_file_path(lib_t lib, const char *name);
static lib_mtime_t lib_stat_mtime(struct stat *st);

static const char *standard_suffix(vhdl_standard_t std)
{
Expand Down Expand Up @@ -161,8 +158,8 @@ static void lib_read_index(lib_t lib)
{
fbuf_t *f = lib_fbuf_open(lib, "_index", FBUF_IN, FBUF_CS_NONE);
if (f != NULL) {
struct stat st;
if (stat(fbuf_file_name(f), &st) < 0)
file_info_t info;
if (!get_handle_info(fbuf_file_handle(f), &info))
fatal_errno("%s", fbuf_file_name(f));

const uint32_t magic = read_u32(f);
Expand All @@ -172,8 +169,8 @@ static void lib_read_index(lib_t lib)
return;
}

lib->index_mtime = lib_stat_mtime(&st);
lib->index_size = st.st_size;
lib->index_mtime = info.mtime;
lib->index_size = info.size;

ident_rd_ctx_t ictx = ident_read_begin(f);
lib_index_t **insert = &(lib->index);
Expand Down Expand Up @@ -296,7 +293,7 @@ static lib_seq_t lib_next_sequence(lib_t lib)
}

static lib_unit_t *lib_put_aux(lib_t lib, object_t *object, bool dirty,
bool error, lib_mtime_t mtime, vcode_unit_t vu,
bool error, uint64_t mtime, vcode_unit_t vu,
lib_seq_t sequence)
{
assert(lib != NULL);
Expand Down Expand Up @@ -503,11 +500,11 @@ lib_t lib_new(const char *spec)

char *lockf LOCAL = xasprintf("%s" DIR_SEP "%s", path, "_NVC_LIB");

struct stat buf;
if (stat(path, &buf) == 0) {
if (S_ISDIR(buf.st_mode)) {
struct stat sb;
if (stat(lockf, &sb) != 0)
file_info_t dir_info;
if (get_file_info(path, &dir_info)) {
if (dir_info.type == FILE_DIR) {
file_info_t lockf_info;
if (!get_file_info(lockf, &lockf_info))
fatal("directory %s already exists and is not an NVC library",
path);
}
Expand Down Expand Up @@ -727,14 +724,14 @@ void lib_destroy(lib_t lib)
checked_sprintf(buf, sizeof(buf), "%s" DIR_SEP "%s",
lib->path, e->d_name);
if (unlink(buf) < 0)
perror("unlink");
fatal_errno("unlink");
}
}

closedir(d);

if (rmdir(lib->path) < 0)
perror("rmdir");
fatal_errno("rmdir");
}

lib_t lib_work(void)
Expand All @@ -754,42 +751,28 @@ const char *lib_path(lib_t lib)
return lib->path;
}

static lib_mtime_t lib_time_to_usecs(time_t t)
{
return (lib_mtime_t)t * 1000 * 1000;
}

static lib_mtime_t lib_mtime_now(void)
{
struct timeval tv;
if (gettimeofday(&tv, NULL) != 0)
fatal_errno("gettimeofday");

return ((lib_mtime_t)tv.tv_sec * 1000000) + tv.tv_usec;
}

void lib_put(lib_t lib, tree_t unit)
{
lib_seq_t seq = LIB_SEQUENCE_INVALID;
if (tree_kind(unit) == T_ARCH)
seq = lib_next_sequence(lib);

object_t *obj = tree_to_object(unit);
lib_put_aux(lib, obj, true, false, lib_mtime_now(), NULL, seq);
lib_put_aux(lib, obj, true, false, get_real_time(), NULL, seq);
}

void lib_put_vlog(lib_t lib, vlog_node_t module)
{
assert(vlog_kind(module) == V_MODULE);
object_t *obj = vlog_to_object(module);
lib_put_aux(lib, obj, true, false, lib_mtime_now(), NULL,
lib_put_aux(lib, obj, true, false, get_real_time(), NULL,
LIB_SEQUENCE_INVALID);
}

void lib_put_error(lib_t lib, tree_t unit)
{
object_t *obj = tree_to_object(unit);
lib_put_aux(lib, obj, true, true, lib_mtime_now(), NULL,
lib_put_aux(lib, obj, true, true, get_real_time(), NULL,
LIB_SEQUENCE_INVALID);
}

Expand Down Expand Up @@ -824,21 +807,14 @@ vcode_unit_t lib_get_vcode(lib_t lib, tree_t unit)
return where->vcode;
}

static lib_mtime_t lib_stat_mtime(struct stat *st)
{
lib_mtime_t mt = lib_time_to_usecs(st->st_mtime);
#if defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
mt += st->st_mtimespec.tv_nsec / 1000;
#elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
mt += st->st_mtim.tv_nsec / 1000;
#endif
return mt;
}

static lib_unit_t *lib_read_unit(lib_t lib, const char *fname)
{
fbuf_t *f = lib_fbuf_open(lib, fname, FBUF_IN, FBUF_CS_ADLER32);

file_info_t info;
if (!get_handle_info(fbuf_file_handle(f), &info))
fatal_errno("%s", fname);

ident_rd_ctx_t ident_ctx = ident_read_begin(f);
loc_rd_ctx_t *loc_ctx = loc_read_begin(f);

Expand Down Expand Up @@ -874,14 +850,7 @@ static lib_unit_t *lib_read_unit(lib_t lib, const char *fname)

arena_set_checksum(object_arena(obj), checksum);

LOCAL_TEXT_BUF path = lib_file_path(lib, fname);

struct stat st;
if (stat(tb_get(path), &st) < 0)
fatal_errno("%s", fname);

lib_mtime_t mt = lib_stat_mtime(&st);
return lib_put_aux(lib, obj, false, false, mt, vu, seq);
return lib_put_aux(lib, obj, false, false, info.mtime, vu, seq);
}

static lib_unit_t *lib_get_aux(lib_t lib, ident_t ident)
Expand Down Expand Up @@ -928,10 +897,10 @@ static lib_unit_t *lib_get_aux(lib_t lib, ident_t ident)

if (lu != NULL && !opt_get_int(OPT_IGNORE_TIME)) {
bool stale = false;
file_info_t info;
const char *file = loc_file_str(&(lu->object->loc));
struct stat st;
if (stat(file, &st) == 0)
stale = (lu->mtime < lib_stat_mtime(&st));
if (get_file_info(file, &info))
stale = (lu->mtime < info.mtime);

if (stale) {
diag_t *d = diag_new(DIAG_WARN, NULL);
Expand Down Expand Up @@ -1151,13 +1120,15 @@ void lib_save(lib_t lib)
}

LOCAL_TEXT_BUF index_path = lib_file_path(lib, "_index");
struct stat st;
if (stat(tb_get(index_path), &st) == 0
&& (lib_stat_mtime(&st) != lib->index_mtime
|| st.st_size != lib->index_size)) {
// Library was updated concurrently: re-read the index while we
// have the lock
lib_read_index(lib);
file_info_t info;
if (get_file_info(tb_get(index_path), &info)) {
if (info.mtime != lib->index_mtime || info.size != lib->index_size) {
// Library was updated concurrently: re-read the index while we
// have the lock
DEBUG_ONLY(debugf("detected concurrent modification of library %s",
istr(lib->name)));
lib_read_index(lib);
}
}

int index_sz = lib_index_size(lib);
Expand All @@ -1179,11 +1150,11 @@ void lib_save(lib_t lib)
ident_write_end(ictx);
fbuf_close(f, NULL);

if (stat(tb_get(index_path), &st) != 0)
fatal_errno("stat: %s", tb_get(index_path));
if (!get_file_info(tb_get(index_path), &info))
fatal_errno("%s", tb_get(index_path));

lib->index_mtime = lib_stat_mtime(&st);
lib->index_size = st.st_size;
lib->index_mtime = info.mtime;
lib->index_size = info.size;

file_unlock(lib->lock_fd);
}
Expand Down
4 changes: 2 additions & 2 deletions src/make.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,8 @@ void make(tree_t *targets, int count, FILE *out)
if (!opt_get_int(OPT_MAKE_DEPS_ONLY))
fprintf(out, "\n-include local.mk\n");
else {
struct stat dummy;
if (stat("local.mk", &dummy) == 0)
file_info_t info;
if (get_file_info("local.mk", &info))
fprintf(out, "\ninclude local.mk\n");
}

Expand Down
5 changes: 2 additions & 3 deletions src/nvc.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
#include <ctype.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>

Expand Down Expand Up @@ -961,8 +960,8 @@ static int install_cmd(int argc, char **argv)
get_libexec_dir(tb);
tb_printf(tb, DIR_SEP "install-%s.sh", argv[i]);

struct stat sb;
if (stat(tb_get(tb), &sb) != 0) {
file_info_t info;
if (!get_file_info(tb_get(tb), &info) || info.type != FILE_REGULAR) {
errorf("%s is not an executable script", tb_get(tb));
list_packages();
return EXIT_FAILURE;
Expand Down
Loading

0 comments on commit 58ccc17

Please sign in to comment.