diff options
Diffstat (limited to 'src/timer.c')
-rw-r--r-- | src/timer.c | 168 |
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]); + } +} + |