aboutsummaryrefslogtreecommitdiff
path: root/src/timer.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-04-25 21:52:09 +0300
committerSergey Poznyakoff <gray@gnu.org>2020-04-25 22:00:26 +0300
commitfbb142ae5a57ab227e46ff6ffeb4b29db000034f (patch)
treecc237b384f298a892a64848a2631c96432cceab7 /src/timer.c
parent68d0e67d55882d1298bb0bf89c954c0ff2b1b823 (diff)
downloadwydawca-fbb142ae5a57ab227e46ff6ffeb4b29db000034f.tar.gz
wydawca-fbb142ae5a57ab227e46ff6ffeb4b29db000034f.tar.bz2
Keep statistic items in global array. Use special thread for periodic reporting
* src/config.c: New configuration statement stat-report-interval * src/directive.c * src/timer.c: Rewrite statistic counters and functions (wydawca_stat_log,wydawca_stat_init,wydawca_stat_update) (wydawca_stat_notify,wydawca_stat_add): New functions. (wy_thr_stat): New thread (statistics reporter. * src/triplet.c: Remove per-thread statistic counters. * src/wydawca.c (wy_main): Use new statistic calls. Force statistic logging at the end of the run. * src/wydawca.h (DEFAULT_STAT_REPORT_INTERVAL): New constant. (stat_report_interval): New extern. (wy_get_stat_array, wy_get_stat_slot) (wy_get_stat_counter): Remove. (wydawca_stat_log,wydawca_stat_init,wydawca_stat_update) (wydawca_stat_notify,wydawca_stat_add) (wydawca_stat_incr): New protos. (stat_mask_p,logstats,wydawca_stats_export) (wydawca_stats_update): Remove protos.
Diffstat (limited to 'src/timer.c')
-rw-r--r--src/timer.c168
1 files changed, 152 insertions, 16 deletions
diff --git a/src/timer.c b/src/timer.c
index 10fd9a5..ae026d9 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -108,6 +108,16 @@ _timer_compute(wydawca_timer_t t)
DIFFTIME(rusage.ru_stime, t->children_mark.ru_stime);
}
+static inline void
+_timer_reset(wydawca_timer_t t)
+{
+ t->real = 0.0;
+ t->self_user = 0.0;
+ t->self_system = 0.0;
+ t->children_user = 0.0;
+ t->children_system = 0.0;
+}
+
wydawca_timer_t
timer_get(int idx)
{
@@ -130,11 +140,7 @@ wydawca_timer_t
timer_reset(int idx)
{
wydawca_timer_t t = get_thread_timer(idx);
- t->real = 0.0;
- t->self_user = 0.0;
- t->self_system = 0.0;
- t->children_user = 0.0;
- t->children_system = 0.0;
+ _timer_reset(t);
return t;
}
@@ -188,18 +194,20 @@ timer_format_time(double t)
}
/* Cumulative statistic counters and timers */
-WY_STAT_COUNTER *wydawca_global_stats;
+WY_STAT_COUNTER wydawca_global_stats[WY_MAX_STAT];
WY_TIMER *wydawca_global_timer_table;
pthread_mutex_t global_stats_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t global_stats_cond = PTHREAD_COND_INITIALIZER;
+static int stat_stop;
+pthread_t stat_tid;
-/* wydawca_stats_export must be called from the main thread in order to
- export the thread's specific stats and timer pointers to
- wydawca_global_stats and wydawca_global_stats. */
void
-wydawca_stats_export(void)
+wydawca_stat_add(int what, size_t n)
{
- wydawca_global_stats = wy_get_stat_array();
- wydawca_global_timer_table = get_thread_timer_table();
+ if (what >= WY_MAX_STAT) abort();
+ pthread_mutex_lock(&global_stats_mutex);
+ wydawca_global_stats[what] += n;
+ pthread_mutex_unlock(&global_stats_mutex);
}
/* When running in cron mode, this function is called by the triplet
@@ -207,14 +215,12 @@ wydawca_stats_export(void)
incorporates the thread-specific statistics into the cumulative
counters. */
void
-wydawca_stats_update(void)
+wydawca_stat_update(void)
{
int i;
- WY_STAT_COUNTER *ctr = wy_get_stat_array();
WY_TIMER *thread_timers = get_thread_timer_table();
pthread_mutex_lock(&global_stats_mutex);
- for (i = 0; i < WY_MAX_STAT; i++)
- wydawca_global_stats[i] += ctr[i];
+// _timer_compute(&wydawca_global_timer_table[WY_TIMER_WYDAWCA]);
for (i = 0; i < MAX_TIMERS; i++) {
wydawca_global_timer_table[i].real
+= thread_timers[i].real;
@@ -229,3 +235,133 @@ wydawca_stats_update(void)
}
pthread_mutex_unlock(&global_stats_mutex);
}
+
+void
+wydawca_stat_notify(int final)
+{
+ void *ret;
+ pthread_mutex_lock(&global_stats_mutex);
+ stat_stop = final;
+ pthread_cond_broadcast(&global_stats_cond);
+ pthread_mutex_unlock(&global_stats_mutex);
+ if (final)
+ pthread_join(stat_tid, &ret);
+}
+
+void
+wydawca_stat_reset(void)
+{
+ int i;
+
+ for (i = 0; i < WY_MAX_STAT; i++)
+ wydawca_global_stats[i] = 0;
+ for (i = 0; i < MAX_TIMERS; i++)
+ _timer_reset(&wydawca_global_timer_table[i]);
+}
+
+time_t stat_report_interval = DEFAULT_STAT_REPORT_INTERVAL;
+
+void *
+wy_thr_stat(void *ptr)
+{
+ wy_set_cur_thread_name("statcol");
+ pthread_mutex_lock(&global_stats_mutex);
+ /* export the thread's specific stats and timer pointers to
+ wydawca_global_stats and wydawca_global_stats. */
+ wydawca_global_timer_table = get_thread_timer_table();
+ while (!stat_stop) {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += stat_report_interval;
+ pthread_cond_timedwait(&global_stats_cond, &global_stats_mutex, &ts);
+ wydawca_stat_log();
+ notify_finish();
+ wydawca_stat_reset();
+ }
+ pthread_mutex_unlock(&global_stats_mutex);
+ return NULL;
+}
+
+void
+wydawca_stat_init(void)
+{
+ pthread_create(&stat_tid, NULL, wy_thr_stat, NULL);
+}
+
+static char *stat_name[WY_MAX_STAT] = {
+ N_("errors"),
+ N_("warnings"),
+ N_("bad signatures"),
+ N_("access violation attempts"),
+ N_("complete triplets"),
+ N_("incomplete triplets"),
+ N_("bad triplets"),
+ N_("expired triplets"),
+ N_("triplet successes"),
+ N_("files uploaded"),
+ N_("files archived"),
+ N_("symlinks created"),
+ N_("symlinks removed"),
+ N_("check failures"),
+};
+
+static char *stat_kwname[WY_MAX_STAT] = {
+ "stat:errors",
+ "stat:warnings",
+ "stat:bad_signatures",
+ "stat:access_violations",
+ "stat:complete_triplets",
+ "stat:incomplete_triplets",
+ "stat:bad_triplets",
+ "stat:expired_triplets",
+ "stat:triplet_success",
+ "stat:uploads",
+ "stat:archives",
+ "stat:symlinks",
+ "stat:rmsymlinks",
+ "stat:check_failures"
+};
+
+int
+wy_stat_mask_p(unsigned long mask)
+{
+ int i;
+
+ for (i = 0; i < WY_MAX_STAT; i++)
+ if (wydawca_global_stats[i] != 0 && (mask && WY_STAT_MASK(i)))
+ return 1;
+ return 0;
+}
+
+int
+wy_stat_expansion(char **ret, char const *name, size_t len)
+{
+ int i;
+
+ for (i = 0; i < WY_MAX_STAT; i++) {
+ if (strlen(stat_kwname[i]) == len
+ && memcmp(stat_kwname[i], name, len) == 0) {
+ size_t size = 0;
+ *ret = NULL;
+ if (grecs_asprintf(ret, &size, "%u", wydawca_global_stats[i]))
+ return WRDSE_NOSPACE;
+ else
+ return WRDSE_OK;
+ }
+ }
+ return WRDSE_UNDEF;
+}
+
+void
+wydawca_stat_log(void)
+{
+ int i;
+
+ if (wy_stat_mask_p(print_stats)) {
+ for (i = 0; i < WY_MAX_STAT; i++)
+ if (print_stats & WY_STAT_MASK(i))
+ wy_log(LOG_INFO, "%s: %u",
+ gettext(stat_name[i]), wydawca_global_stats[i]);
+ }
+}
+

Return to:

Send suggestions and report system problems to the System administrator.