From d9298a35b6741a918e21e5d04e742f05b784e3ea Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Sat, 2 Feb 2019 12:30:56 +0100 Subject: blogc: added template variables for memory and cpu time resource usage this include infrastructure required to have variables evaluated as lazy function calls. missing tests, docs and improvements. --- Makefile.am | 4 +++ configure.ac | 2 +- src/blogc/funcvars.c | 47 ++++++++++++++++++++++++++++ src/blogc/funcvars.h | 19 ++++++++++++ src/blogc/renderer.c | 12 ++++++-- src/blogc/rusage.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/blogc/rusage.h | 21 +++++++++++++ 7 files changed, 188 insertions(+), 4 deletions(-) create mode 100644 src/blogc/funcvars.c create mode 100644 src/blogc/funcvars.h create mode 100644 src/blogc/rusage.c create mode 100644 src/blogc/rusage.h diff --git a/Makefile.am b/Makefile.am index b383833..e2985cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,8 +40,10 @@ noinst_HEADERS = \ src/blogc/content-parser.h \ src/blogc/datetime-parser.h \ src/blogc/debug.h \ + src/blogc/funcvars.h \ src/blogc/loader.h \ src/blogc/renderer.h \ + src/blogc/rusage.h \ src/blogc/source-parser.h \ src/blogc/template-parser.h \ src/blogc-git-receiver/post-receive.h \ @@ -124,8 +126,10 @@ libblogc_la_SOURCES = \ src/blogc/content-parser.c \ src/blogc/datetime-parser.c \ src/blogc/debug.c \ + src/blogc/funcvars.c \ src/blogc/loader.c \ src/blogc/renderer.c \ + src/blogc/rusage.c \ src/blogc/source-parser.c \ src/blogc/template-parser.c \ $(NULL) diff --git a/configure.ac b/configure.ac index 62244e1..cb68940 100644 --- a/configure.ac +++ b/configure.ac @@ -220,7 +220,7 @@ AM_CONDITIONAL([USE_BGR_DEPS], [test "x$have_bgr_deps" = "xyes"]) BASH="$ac_cv_path_bash" AC_SUBST(BASH) -AC_CHECK_HEADERS([sys/stat.h sys/wait.h time.h]) +AC_CHECK_HEADERS([sys/resource.h sys/stat.h sys/time.h sys/wait.h time.h]) LT_LIB_M diff --git a/src/blogc/funcvars.c b/src/blogc/funcvars.c new file mode 100644 index 0000000..a3af274 --- /dev/null +++ b/src/blogc/funcvars.c @@ -0,0 +1,47 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2019 Rafael G. Martins + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#include +#include +#include + +#include "funcvars.h" +#include "rusage.h" +#include "../common/utils.h" + + +static const struct func_map { + const char *variable; + const blogc_funcvars_func_t func; +} funcs[] = { + {"BLOGC_RUSAGE_CPU_TIME", blogc_rusage_cpu_time}, + {"BLOGC_RUSAGE_MEMORY", blogc_rusage_memory}, + {NULL, NULL}, +}; + + +char* +blogc_funcvars_lookup(const char *name, bc_trie_t *global) +{ + // protect against evaluating the same function twice in the same global + // context + if (NULL != bc_trie_lookup(global, name)) + return NULL; + + for (size_t i = 0; funcs[i].variable != NULL; i++) { + if (0 == strcmp(name, funcs[i].variable)) { + char *val = funcs[i].func(); + if (val == NULL) + return NULL; + bc_trie_insert(global, name, bc_strdup(val)); + return val; + } + } + + return NULL; +} diff --git a/src/blogc/funcvars.h b/src/blogc/funcvars.h new file mode 100644 index 0000000..d46266f --- /dev/null +++ b/src/blogc/funcvars.h @@ -0,0 +1,19 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2019 Rafael G. Martins + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifndef ___FUNCVARS_H +#define ___FUNCVARS_H + +#include +#include "../common/utils.h" + +typedef char* (*blogc_funcvars_func_t) (void); + +char* blogc_funcvars_lookup(const char *name, bc_trie_t *global); + +#endif /* ___FUNCVARS_H */ diff --git a/src/blogc/renderer.c b/src/blogc/renderer.c index 6a591ec..2326e09 100644 --- a/src/blogc/renderer.c +++ b/src/blogc/renderer.c @@ -12,6 +12,7 @@ #include #include #include "datetime-parser.h" +#include "funcvars.h" #include "template-parser.h" #include "renderer.h" #include "../common/error.h" @@ -101,10 +102,15 @@ blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local, } if ((0 == strcmp(var, "FOREACH_ITEM")) && - (foreach_var != NULL && foreach_var->data != NULL)) + (foreach_var != NULL && foreach_var->data != NULL)) { value = foreach_var->data; - else - value = blogc_get_variable(var, global, local); + } + else { + value = blogc_funcvars_lookup(var, global); + if (value == NULL) { + value = blogc_get_variable(var, global, local); + } + } if (value == NULL) { free(var); diff --git a/src/blogc/rusage.c b/src/blogc/rusage.c new file mode 100644 index 0000000..b04938e --- /dev/null +++ b/src/blogc/rusage.c @@ -0,0 +1,87 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2019 Rafael G. Martins + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_SYS_TIME_H +#include +#endif /* HAVE_SYS_TIME_H */ + +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif /* HAVE_SYS_RESOURCE_H */ + +#include "../common/utils.h" +#include "rusage.h" + +// FIXME: optimize to use a single syscall for both cpu time and memory? + + +#include +long long +blogc_rusage_get_cpu_time(void) +{ + struct rusage usage; + if (0 != getrusage(RUSAGE_SELF, &usage)) + return 0; + return ( + (usage.ru_utime.tv_sec * 1000000) + usage.ru_utime.tv_usec + + (usage.ru_stime.tv_sec * 1000000) + usage.ru_stime.tv_usec); +} + + +char* +blogc_rusage_format_cpu_time(long long time) +{ + if (time > 1000000) + return bc_strdup_printf("%.3s", ((float) time) / 1000000.0); + + // this is a special case: some systems may report the cpu time rounded up to the + // milisecond. it is useless to show ".000" in this case. + if (time > 1000) + return bc_strdup_printf("%.*fms", time % 1000 ? 3 : 0, ((float) time) / 1000.0); + + return bc_strdup_printf("%dus", time); +} + + +char* +blogc_rusage_cpu_time(void) +{ + return blogc_rusage_format_cpu_time(blogc_rusage_get_cpu_time()); +} + + +long +blogc_rusage_get_memory(void) +{ + struct rusage usage; + if (0 != getrusage(RUSAGE_SELF, &usage)) + return 0; + return usage.ru_maxrss; +} + + +char* +blogc_rusage_format_memory(long mem) +{ + if (mem > 1048576) + return bc_strdup_printf("%.3fGB", ((float) mem) / 1048576.0); + if (mem > 1024) + return bc_strdup_printf("%.3fMB", ((float) mem) / 1024.0); + return bc_strdup_printf("%dKB", mem); +} + + +char* +blogc_rusage_memory(void) +{ + return blogc_rusage_format_memory(blogc_rusage_get_memory()); +} diff --git a/src/blogc/rusage.h b/src/blogc/rusage.h new file mode 100644 index 0000000..cfdccbe --- /dev/null +++ b/src/blogc/rusage.h @@ -0,0 +1,21 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2019 Rafael G. Martins + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifndef ___RUSAGE_H +#define ___RUSAGE_H + +long long blogc_rusage_get_cpu_time(void); // in microseconds +long blogc_rusage_get_memory(void); // in kilobytes + +char* blogc_rusage_format_cpu_time(long long time); +char* blogc_rusage_format_memory(long mem); + +char* blogc_rusage_cpu_time(void); +char* blogc_rusage_memory(void); + +#endif /* ___RUSAGE_H */ -- cgit v1.2.3-18-g5258