diff options
author | Joel Rosdahl <joel@rosdahl.net> | 2019-05-26 14:02:02 +0200 |
---|---|---|
committer | Joel Rosdahl <joel@rosdahl.net> | 2019-05-26 14:02:02 +0200 |
commit | 0b3276d5541e8a7f7eeccaa72820d0b5f312f8d0 (patch) | |
tree | 276d7f2c7d3a09dbdf14c6e793d0ef068abdf53b | |
parent | 64b650951d1f9a9b2a058c4b7f3cbdafe410cc45 (diff) | |
download | ccache-0b3276d5541e8a7f7eeccaa72820d0b5f312f8d0.tar.gz |
Improve solution to #405
Instead of changing the global stats_file value temporarily in
update_manifest, pass which file to update explicitly to
stats_update_size.
-rw-r--r-- | src/ccache.c | 20 | ||||
-rw-r--r-- | src/ccache.h | 2 | ||||
-rw-r--r-- | src/counters.c | 8 | ||||
-rw-r--r-- | src/stats.c | 59 |
4 files changed, 53 insertions, 36 deletions
diff --git a/src/ccache.c b/src/ccache.c index 67e5f182..4572b87f 100644 --- a/src/ccache.c +++ b/src/ccache.c @@ -236,8 +236,8 @@ static char *cpp_stderr; // belongs (<cache_dir>/<x>/stats). char *stats_file = NULL; -// The stats_file to use for manifest -static char *manifest_stats; +// The stats file to use for the manifest. +static char *manifest_stats_file; // Whether the output is a precompiled header. bool output_is_precompiled_header = false; @@ -1236,6 +1236,7 @@ do_copy_or_move_file_to_cache(const char *source, const char *dest, bool copy) failed(); } stats_update_size( + stats_file, file_size(&st) - (orig_dest_existed ? file_size(&orig_dest_st) : 0), orig_dest_existed ? 0 : 1); } @@ -1356,23 +1357,19 @@ update_manifest_file(void) old_size = file_size(&st); } - char *old_stats_file = stats_file; - stats_flush(); - stats_file = manifest_stats; - MTR_BEGIN("manifest", "manifest_put"); if (manifest_put(manifest_path, cached_obj_hash, included_files)) { cc_log("Added object file hash to %s", manifest_path); if (x_stat(manifest_path, &st) == 0) { - stats_update_size(file_size(&st) - old_size, old_size == 0 ? 1 : 0); + stats_update_size( + manifest_stats_file, + file_size(&st) - old_size, + old_size == 0 ? 1 : 0); } } else { cc_log("Failed to add object file hash to %s", manifest_path); } MTR_END("manifest", "manifest_put"); - - stats_flush(); - stats_file = old_stats_file; } static void @@ -2222,7 +2219,8 @@ calculate_object_hash(struct args *args, struct hash *hash, int direct_mode) char *manifest_name = hash_result(hash); manifest_path = get_path_in_cache(manifest_name, ".manifest"); - manifest_stats = format("%s/%c/stats", conf->cache_dir, manifest_name[0]); + manifest_stats_file = + format("%s/%c/stats", conf->cache_dir, manifest_name[0]); free(manifest_name); cc_log("Looking for object file hash in %s", manifest_path); diff --git a/src/ccache.h b/src/ccache.h index 66a98457..a2694d1a 100644 --- a/src/ccache.h +++ b/src/ccache.h @@ -224,7 +224,7 @@ unsigned stats_get_pending(enum stats stat); void stats_zero(void); void stats_summary(void); void stats_print(void); -void stats_update_size(int64_t size, int files); +void stats_update_size(const char *sfile, int64_t size, int files); void stats_get_obsolete_limits(const char *dir, unsigned *maxfiles, uint64_t *maxsize); void stats_set_sizes(const char *dir, unsigned num_files, uint64_t total_size); diff --git a/src/counters.c b/src/counters.c index 1693c97d..1441a4fb 100644 --- a/src/counters.c +++ b/src/counters.c @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2016 Joel Rosdahl +// Copyright (C) 2010-2019 Joel Rosdahl // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free @@ -35,8 +35,10 @@ counters_init(size_t initial_size) void counters_free(struct counters *c) { - free(c->data); - free(c); + if (c) { + free(c->data); + free(c); + } } // Set a new size. New data entries are set to 0. diff --git a/src/stats.c b/src/stats.c index 0a0c7aab..ff3123a2 100644 --- a/src/stats.c +++ b/src/stats.c @@ -47,6 +47,7 @@ typedef char *(*format_fn)(uint64_t value); static char *format_size_times_1024(uint64_t size); static char *format_timestamp(uint64_t timestamp); +static void stats_flush_to_file(const char *sfile, struct counters *updates); // Statistics fields in display order. static struct { @@ -399,11 +400,21 @@ stats_collect(struct counters *counters, time_t *last_updated) // Record that a number of bytes and files have been added to the cache. Size // is in bytes. void -stats_update_size(int64_t size, int files) +stats_update_size(const char *sfile, int64_t size, int files) { - init_counter_updates(); - counter_updates->data[STATS_NUMFILES] += files; - counter_updates->data[STATS_TOTALSIZE] += size / 1024; + struct counters *updates; + if (sfile == stats_file) { + init_counter_updates(); + updates = counter_updates; + } else { + updates = counters_init(STATS_END); + } + updates->data[STATS_NUMFILES] += files; + updates->data[STATS_TOTALSIZE] += size / 1024; + if (sfile != stats_file) { + stats_flush_to_file(sfile, updates); + counters_free(updates); + } } // Read in the stats from one directory and add to the counters. @@ -417,9 +428,9 @@ stats_read(const char *sfile, struct counters *counters) free(data); } -// Write counter updates in counter_updates to disk. -void -stats_flush(void) +// Write counter updates in updates to sfile. +static void +stats_flush_to_file(const char *sfile, struct counters *updates) { assert(conf); @@ -427,13 +438,13 @@ stats_flush(void) return; } - if (!counter_updates) { + if (!updates) { return; } bool should_flush = false; for (int i = 0; i < STATS_END; ++i) { - if (counter_updates->data[i] > 0) { + if (updates->data[i] > 0) { should_flush = true; break; } @@ -442,38 +453,38 @@ stats_flush(void) return; } - if (!stats_file) { + if (!sfile) { char *stats_dir; - // A NULL stats_file means that we didn't get past calculate_object_hash(), - // so we just choose one of stats files in the 16 subdirectories. + // A NULL sfile means that we didn't get past calculate_object_hash(), so + // we just choose one of stats files in the 16 subdirectories. stats_dir = format("%s/%x", conf->cache_dir, hash_from_int(getpid()) % 16); - stats_file = format("%s/stats", stats_dir); + sfile = format("%s/stats", stats_dir); free(stats_dir); } - if (!lockfile_acquire(stats_file, lock_staleness_limit)) { + if (!lockfile_acquire(sfile, lock_staleness_limit)) { return; } struct counters *counters = counters_init(STATS_END); - stats_read(stats_file, counters); + stats_read(sfile, counters); for (int i = 0; i < STATS_END; ++i) { - counters->data[i] += counter_updates->data[i]; + counters->data[i] += updates->data[i]; } - stats_write(stats_file, counters); - lockfile_release(stats_file); + stats_write(sfile, counters); + lockfile_release(sfile); if (!str_eq(conf->log_file, "") || conf->debug) { for (int i = 0; i < STATS_END; ++i) { - if (counter_updates->data[stats_info[i].stat] != 0 + if (updates->data[stats_info[i].stat] != 0 && !(stats_info[i].flags & FLAG_NOZERO)) { cc_log("Result: %s", stats_info[i].message); } } } - char *subdir = dirname(stats_file); + char *subdir = dirname(sfile); bool need_cleanup = false; if (conf->max_files != 0 @@ -499,8 +510,14 @@ stats_flush(void) free(subdir); counters_free(counters); +} - free(counter_updates); +// Write counter updates in counter_updates to disk. +void +stats_flush(void) +{ + stats_flush_to_file(stats_file, counter_updates); + counters_free(counter_updates); counter_updates = NULL; } |