From 88db624127e11d4a1d1000a5ebcfb6757a05f3a4 Mon Sep 17 00:00:00 2001 From: Dmitry Kozlov Date: Fri, 24 Dec 2010 20:31:28 +0300 Subject: cli: show cpu and memory utilization in statistics --- accel-pptpd/cli/std_cmd.c | 13 +++++++++ accel-pptpd/cli/telnet.c | 3 +++ accel-pptpd/memdebug.c | 10 +++---- accel-pptpd/triton/md.c | 2 +- accel-pptpd/triton/timer.c | 2 +- accel-pptpd/triton/triton.c | 63 ++++++++++++++++++++++++++++++++++++++++--- accel-pptpd/triton/triton.h | 5 ++++ accel-pptpd/triton/triton_p.h | 2 +- 8 files changed, 88 insertions(+), 12 deletions(-) diff --git a/accel-pptpd/cli/std_cmd.c b/accel-pptpd/cli/std_cmd.c index 127e7a27..0d168e58 100644 --- a/accel-pptpd/cli/std_cmd.c +++ b/accel-pptpd/cli/std_cmd.c @@ -16,6 +16,17 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, { time_t dt; int day,hour; + char statm_fname[128]; + FILE *f; + unsigned long vmsize = 0, vmrss = 0; + unsigned long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; + + sprintf(statm_fname, "/proc/%i/statm", getpid()); + f = fopen(statm_fname, "r"); + if (f) { + fscanf(f, "%lu %lu", &vmsize, &vmrss); + fclose(f); + } time(&dt); dt -= triton_stat.start_time; @@ -25,6 +36,8 @@ static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, dt %= 60 * 60; cli_sendv(client, "uptime: %i.%02i:%02i:%02i\r\n", day, hour, dt / 60, dt % 60); + cli_sendv(client, "cpu: %i%% (%i/%i)\r\n", triton_stat.ru_utime + triton_stat.ru_stime, triton_stat.ru_utime, triton_stat.ru_stime); + cli_sendv(client, "mem: %lu/%lu kB\r\n", vmrss / page_size_kb, vmsize / page_size_kb); cli_send(client, "core:\r\n"); cli_sendv(client, " mempool_allocated: %u\r\n", triton_stat.mempool_allocated); cli_sendv(client, " mempool_available: %u\r\n", triton_stat.mempool_available); diff --git a/accel-pptpd/cli/telnet.c b/accel-pptpd/cli/telnet.c index 256f236b..89512ad8 100644 --- a/accel-pptpd/cli/telnet.c +++ b/accel-pptpd/cli/telnet.c @@ -69,6 +69,8 @@ static void disconnect(struct telnet_client_t *cln) log_debug("cli: disconnect\n"); + triton_stop_collect_cpu_usage(); + list_del(&cln->entry); triton_md_unregister_handler(&cln->hnd); @@ -567,6 +569,7 @@ static int serv_read(struct triton_md_handler_t *h) conn->auth = 1; send_prompt(conn); } + triton_collect_cpu_usage(); } return 0; } diff --git a/accel-pptpd/memdebug.c b/accel-pptpd/memdebug.c index d36779e1..c443ec1a 100644 --- a/accel-pptpd/memdebug.c +++ b/accel-pptpd/memdebug.c @@ -80,7 +80,7 @@ void __export md_free(void *ptr, const char *fname, int line) } if (mem->magic2 != *(uint64_t*)(mem->data + mem->size)) { - printf("memory corruption:\nmalloc(%lu) at %s:%i\nfree at %s:%i\n", mem->size, mem->fname, mem->line, fname, line); + printf("memory corruption:\nmalloc(%lu) at %s:%i\nfree at %s:%i\n", (long unsigned)mem->size, mem->fname, mem->line, fname, line); abort(); } @@ -106,7 +106,7 @@ void __export *md_realloc(void *ptr, size_t size, const char *fname, int line) } if (mem->magic2 != *(uint64_t*)(mem->data + mem->size)) { - printf("memory corruption:\nmalloc(%lu) at %s:%i\nfree at %s:%i\n", mem->size, mem->fname, mem->line, fname, line); + printf("memory corruption:\nmalloc(%lu) at %s:%i\nfree at %s:%i\n", (long unsigned)mem->size, mem->fname, mem->line, fname, line); abort(); } @@ -140,11 +140,11 @@ static void siginfo(int num) spin_lock(&mem_list_lock); list_for_each_entry(mem, &mem_list, entry) { - printf("%s:%i %lu\n", mem->fname, mem->line, mem->size); + printf("%s:%i %lu\n", mem->fname, mem->line, (long unsigned)mem->size); total += mem->size; } spin_unlock(&mem_list_lock); - printf("total = %lu\n", total); + printf("total = %lu\n", (long unsigned)total); } static void siginfo2(int num) @@ -154,7 +154,7 @@ static void siginfo2(int num) spin_lock(&mem_list_lock); list_for_each_entry(mem, &mem_list, entry) { if (mem->magic1 != MAGIC1 || mem->magic2 != *(uint64_t*)(mem->data + mem->size)) - printf("%s:%i %lu\n", mem->fname, mem->line, mem->size); + printf("%s:%i %lu\n", mem->fname, mem->line, (long unsigned)mem->size); } spin_unlock(&mem_list_lock); } diff --git a/accel-pptpd/triton/md.c b/accel-pptpd/triton/md.c index 15ed9fcd..d8453896 100644 --- a/accel-pptpd/triton/md.c +++ b/accel-pptpd/triton/md.c @@ -124,7 +124,7 @@ void __export triton_md_register_handler(struct triton_context_t *ctx, struct tr if (ctx) h->ctx = (struct _triton_context_t *)ctx->tpd; else - h->ctx = (struct _triton_context_t *)default_ctx->tpd; + h->ctx = (struct _triton_context_t *)default_ctx.tpd; ud->tpd = h; spin_lock(&h->ctx->lock); list_add_tail(&h->entry, &h->ctx->handlers); diff --git a/accel-pptpd/triton/timer.c b/accel-pptpd/triton/timer.c index d6be1e42..4e37754c 100644 --- a/accel-pptpd/triton/timer.c +++ b/accel-pptpd/triton/timer.c @@ -133,7 +133,7 @@ int __export triton_timer_add(struct triton_context_t *ctx, struct triton_timer_ if (ctx) t->ctx = (struct _triton_context_t *)ctx->tpd; else - t->ctx = (struct _triton_context_t *)default_ctx->tpd; + t->ctx = (struct _triton_context_t *)default_ctx.tpd; t->fd = timerfd_create(CLOCK_MONOTONIC, 0); if (t->fd < 0) { triton_log_error("timer:timerfd_create: %s", strerror(errno)); diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c index 1a2cd2bd..3ed14ffd 100644 --- a/accel-pptpd/triton/triton.c +++ b/accel-pptpd/triton/triton.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "triton_p.h" #include "memdebug.h" @@ -27,7 +28,18 @@ static mempool_t *ctx_pool; static mempool_t *call_pool; static mempool_t *ctx_stack_pool; -__export struct triton_stat_t triton_stat; +struct triton_stat_t __export triton_stat; + +static struct timeval ru_utime; +static struct timeval ru_stime; +static struct timespec ru_timestamp; +static int ru_refs; +static void ru_update(struct triton_timer_t *); +static struct triton_timer_t ru_timer = { + .period = 1000, + .expire = ru_update, +}; +struct triton_context_t default_ctx; #define log_debug2(fmt, ...) @@ -325,11 +337,12 @@ void __export triton_context_unregister(struct triton_context_t *ud) ctx->need_free = 1; spin_lock(&ctx_list_lock); list_del(&ctx->entry); - if (need_terminate && list_empty(&ctx_list)) - terminate = 1; + if (__sync_sub_and_fetch(&triton_stat.context_count, 1) == 1) { + if (need_terminate) + terminate = 1; + } spin_unlock(&ctx_list_lock); - __sync_sub_and_fetch(&triton_stat.context_count, 1); if (terminate) { list_for_each_entry(t, &threads, entry) @@ -438,6 +451,45 @@ void __export triton_cancel_call(struct triton_context_t *ud, void (*func)(void } } +void __export triton_collect_cpu_usage(void) +{ + struct rusage rusage; + + if (__sync_fetch_and_add(&ru_refs, 1) == 0) { + triton_timer_add(NULL, &ru_timer, 0); + getrusage(RUSAGE_SELF, &rusage); + clock_gettime(CLOCK_MONOTONIC, &ru_timestamp); + ru_utime = rusage.ru_utime; + ru_stime = rusage.ru_stime; + triton_stat.ru_utime = 0; + triton_stat.ru_stime = 0; + } +} + +void __export triton_stop_collect_cpu_usage(void) +{ + if (__sync_sub_and_fetch(&ru_refs, 1) == 0) + triton_timer_del(&ru_timer); +} + +static void ru_update(struct triton_timer_t *t) +{ + struct timespec ts; + struct rusage rusage; + unsigned int dt; + + getrusage(RUSAGE_SELF, &rusage); + clock_gettime(CLOCK_MONOTONIC, &ts); + + dt = (ts.tv_sec - ru_timestamp.tv_sec) * 1000000 + (ts.tv_nsec - ru_timestamp.tv_nsec) / 1000000; + triton_stat.ru_utime = (double)((rusage.ru_utime.tv_sec - ru_utime.tv_sec) * 1000000 + (rusage.ru_utime.tv_usec - ru_utime.tv_usec)) / dt * 100; + triton_stat.ru_stime = (double)((rusage.ru_stime.tv_sec - ru_stime.tv_sec) * 1000000 + (rusage.ru_stime.tv_usec - ru_stime.tv_usec)) / dt * 100; + + ru_timestamp = ts; + ru_utime = rusage.ru_utime; + ru_stime = rusage.ru_stime; +} + int __export triton_init(const char *conf_file) { ctx_pool = mempool_create2(sizeof(struct _triton_context_t)); @@ -492,6 +544,9 @@ void __export triton_run() md_run(); timer_run(); + + triton_context_register(&default_ctx, NULL); + triton_context_wakeup(&default_ctx); } void __export triton_terminate() diff --git a/accel-pptpd/triton/triton.h b/accel-pptpd/triton/triton.h index 799560b1..a4664ffb 100644 --- a/accel-pptpd/triton/triton.h +++ b/accel-pptpd/triton/triton.h @@ -64,6 +64,8 @@ struct triton_stat_t unsigned int timer_count; unsigned int timer_pending; time_t start_time; + int ru_utime; + int ru_stime; }; extern struct triton_stat_t triton_stat; @@ -98,6 +100,9 @@ void triton_event_fire(int ev_id, void *arg); struct conf_sect_t *conf_get_section(const char *name); char *conf_get_opt(const char *sect, const char *name); +void triton_collect_cpu_usage(void); +void triton_stop_collect_cpu_usage(void); + #define TRITON_OK 0 #define TRITON_ERR_NOCOMP -1 #define TRITON_ERR_NOSUPP -2 diff --git a/accel-pptpd/triton/triton_p.h b/accel-pptpd/triton/triton_p.h index 77702144..2bc265cb 100644 --- a/accel-pptpd/triton/triton_p.h +++ b/accel-pptpd/triton/triton_p.h @@ -95,7 +95,7 @@ void md_run(); void md_terminate(); void timer_run(); void timer_terminate(); -struct triton_context_t *default_ctx; +extern struct triton_context_t default_ctx; int triton_queue_ctx(struct _triton_context_t*); void triton_thread_wakeup(struct _triton_thread_t*); int conf_load(const char *fname); -- cgit v1.2.3