]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Improve solution to #405
authorJoel Rosdahl <joel@rosdahl.net>
Sun, 26 May 2019 12:02:02 +0000 (14:02 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 18 Jul 2019 20:05:49 +0000 (22:05 +0200)
Instead of changing the global stats_file value temporarily in
update_manifest, pass which file to update explicitly to
stats_update_size.

src/ccache.c
src/ccache.h
src/counters.c
src/stats.c

index 19ae1eabf5eec4f40bb9eaa7caa79b2a067d1a35..aa7ca96f8d4309200c1c88c1ab4a92a6826da601 100644 (file)
@@ -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);
index 66a98457b264d54c345b309bffda263045dff6bf..a2694d1a6112973e6a7aa10781e32ba5c3f8d97b 100644 (file)
@@ -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);
index 1693c97d47ed8760ea36903fac254b0386b0a420..1441a4fb8b38379dd4c46d76a78448e94be00ee9 100644 (file)
@@ -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.
index 0a0c7aab324b0e55b95ba4d19bfb97cffb334779..ff3123a259939d3ec080e8e53ea7792688009ec7 100644 (file)
@@ -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;
 }