summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Rosdahl <joel@rosdahl.net>2019-05-26 14:02:02 +0200
committerJoel Rosdahl <joel@rosdahl.net>2019-05-26 14:02:02 +0200
commit0b3276d5541e8a7f7eeccaa72820d0b5f312f8d0 (patch)
tree276d7f2c7d3a09dbdf14c6e793d0ef068abdf53b
parent64b650951d1f9a9b2a058c4b7f3cbdafe410cc45 (diff)
downloadccache-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.c20
-rw-r--r--src/ccache.h2
-rw-r--r--src/counters.c8
-rw-r--r--src/stats.c59
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;
}