Browse Source

* Improve google perf tools support

* Pass to event_add only copies of struct timeval to avoid timing problems
tags/0.2.7
Vsevolod Stakhov 15 years ago
parent
commit
b8c5174335
9 changed files with 90 additions and 36 deletions
  1. 16
    0
      CMakeLists.txt
  2. 4
    0
      config.h.in
  3. 22
    6
      src/buffer.c
  4. 2
    1
      src/controller.c
  5. 1
    0
      src/fuzzy_storage.c
  6. 2
    0
      src/lmtp.c
  7. 40
    2
      src/util.c
  8. 2
    0
      src/util.h
  9. 1
    27
      src/worker.c

+ 16
- 0
CMakeLists.txt View File

@@ -147,6 +147,21 @@ IF(ENABLE_PROFILING MATCHES "ON")
ENDIF(ENABLE_PROFILING MATCHES "ON")

IF(ENABLE_GPERF_TOOLS MATCHES "ON")
FIND_PATH(GPERF_INCLUDE google/profiler.h PATHS /opt/include
/usr/include
/usr/local/include
DOC "Path where google perftools includes can be found")
INCLUDE_DIRECTORIES("${GPERF_INCLUDE}")
FIND_LIBRARY(GPERF_LIBRARY NAMES profiler PATHS /lib
/opt/lib
/usr/lib
/usr/local/lib
DOC "Path where the gperf library can be found")
IF(NOT GPERF_LIBRARY)
MESSAGE(FATAL_ERROR "gperf tools support is enabled but not found in system")
ENDIF(NOT GPERF_LIBRARY)
GET_FILENAME_COMPONENT(GPERF_PATH "${GPERF_LIBRARY}" PATH)
LINK_DIRECTORIES("${GPERF_PATH}")
SET(WITH_GPERF_TOOLS 1)
ENDIF(ENABLE_GPERF_TOOLS MATCHES "ON")

@@ -429,6 +444,7 @@ ADD_EXECUTABLE(rspamd ${RSPAMDSRC} ${CONTRIBSRC} ${TOKENIZERSSRC}
${CLASSIFIERSSRC} ${PLUGINSSRC} ${YACC_OUTPUT}
${LEX_OUTPUT})
SET_TARGET_PROPERTIES(rspamd PROPERTIES LINKER_LANGUAGE C)
SET_TARGET_PROPERTIES(rspamd PROPERTIES COMPILE_FLAGS "-DRSPAMD_MAIN")
SET_TARGET_PROPERTIES(rspamd PROPERTIES VERSION ${RSPAMD_VERSION})

IF(ENABLE_PERL MATCHES "ON")

+ 4
- 0
config.h.in View File

@@ -269,6 +269,10 @@
#define HAVE_SETLOCALE 1
#endif

#ifdef WITH_GPERF_TOOLS
#include <google/profiler.h>
#endif

#include <errno.h>
#include <signal.h>
#include <event.h>

+ 22
- 6
src/buffer.c View File

@@ -44,6 +44,7 @@ write_buffers (int fd, rspamd_io_dispatcher_t *d)
GList *cur;
GError *err;
rspamd_buffer_t *buf;
struct timeval *ntv;
ssize_t r;

/* Fix order */
@@ -87,7 +88,9 @@ write_buffers (int fd, rspamd_io_dispatcher_t *d)
/* Wait for other event */
event_del (d->ev);
event_set (d->ev, fd, EV_WRITE, dispatcher_cb, (void *)d);
event_add (d->ev, d->tv);
ntv = memory_pool_alloc (d->pool, sizeof (struct timeval));
memcpy (ntv, d->tv, sizeof (struct timeval));
event_add (d->ev, ntv);
return;
}
cur = g_list_next (cur);
@@ -111,13 +114,17 @@ write_buffers (int fd, rspamd_io_dispatcher_t *d)
event_del (d->ev);
event_set (d->ev, fd, EV_READ | EV_PERSIST, dispatcher_cb, (void *)d);
event_add (d->ev, d->tv);
ntv = memory_pool_alloc (d->pool, sizeof (struct timeval));
memcpy (ntv, d->tv, sizeof (struct timeval));
event_add (d->ev, ntv);
}
else {
/* Plan other write event */
event_del (d->ev);
event_set (d->ev, fd, EV_WRITE, dispatcher_cb, (void *)d);
event_add (d->ev, d->tv);
ntv = memory_pool_alloc (d->pool, sizeof (struct timeval));
memcpy (ntv, d->tv, sizeof (struct timeval));
event_add (d->ev, ntv);
}
}

@@ -257,6 +264,7 @@ dispatcher_cb (int fd, short what, void *arg)
{
rspamd_io_dispatcher_t *d = (rspamd_io_dispatcher_t *)arg;
GError *err;
struct timeval *ntv;

msg_debug ("dispatcher_cb: in dispatcher callback, what: %d, fd: %d", (int)what, fd);

@@ -272,7 +280,9 @@ dispatcher_cb (int fd, short what, void *arg)
if (d->out_buffers == NULL) {
event_del (d->ev);
event_set (d->ev, fd, EV_READ | EV_PERSIST, dispatcher_cb, (void *)d);
event_add (d->ev, d->tv);
ntv = memory_pool_alloc (d->pool, sizeof (struct timeval));
memcpy (ntv, d->tv, sizeof (struct timeval));
event_add (d->ev, ntv);
}
else {
write_buffers (fd, d);
@@ -293,6 +303,7 @@ rspamd_create_dispatcher (int fd, enum io_policy policy,
struct timeval *tv, void *user_data)
{
rspamd_io_dispatcher_t *new;
struct timeval *ntv;

if (fd == -1) {
return NULL;
@@ -320,7 +331,9 @@ rspamd_create_dispatcher (int fd, enum io_policy policy,
new->fd = fd;

event_set (new->ev, fd, EV_WRITE, dispatcher_cb, (void *)new);
event_add (new->ev, new->tv);
ntv = memory_pool_alloc (new->pool, sizeof (struct timeval));
memcpy (ntv, new->tv, sizeof (struct timeval));
event_add (new->ev, ntv);

return new;
}
@@ -378,6 +391,7 @@ rspamd_dispatcher_write (rspamd_io_dispatcher_t *d,
size_t len, gboolean delayed, gboolean allocated)
{
rspamd_buffer_t *newbuf;
struct timeval *ntv;

newbuf = memory_pool_alloc (d->pool, sizeof (rspamd_buffer_t));
if (!allocated) {
@@ -401,7 +415,9 @@ rspamd_dispatcher_write (rspamd_io_dispatcher_t *d,
msg_debug ("rspamd_dispatcher_write: plan write event");
event_del (d->ev);
event_set (d->ev, d->fd, EV_WRITE, dispatcher_cb, (void *)d);
event_add (d->ev, d->tv);
ntv = memory_pool_alloc (d->pool, sizeof (struct timeval));
memcpy (ntv, d->tv, sizeof (struct timeval));
event_add (d->ev, ntv);
}
}


+ 2
- 1
src/controller.c View File

@@ -627,8 +627,9 @@ start_controller (struct rspamd_worker *worker)

/* Send SIGUSR2 to parent */
kill (getppid (), SIGUSR2);

gperf_profiler_init (worker->srv->cfg, "controller");
event_loop (0);

exit (EXIT_SUCCESS);

+ 1
- 0
src/fuzzy_storage.c View File

@@ -478,6 +478,7 @@ start_fuzzy_storage (struct rspamd_worker *worker)
event_set(&worker->bind_ev, worker->cf->listen_sock, EV_READ | EV_PERSIST, accept_fuzzy_socket, (void *)worker);
event_add(&worker->bind_ev, NULL);

gperf_profiler_init (worker->srv->cfg, "fuzzy");

event_loop (0);
exit (EXIT_SUCCESS);

+ 2
- 0
src/lmtp.c View File

@@ -294,6 +294,8 @@ start_lmtp_worker (struct rspamd_worker *worker)
io_tv.tv_sec = WORKER_IO_TIMEOUT;
io_tv.tv_usec = 0;

gperf_profiler_init (worker->srv->cfg, "lmtp");

event_loop (0);
exit (EXIT_SUCCESS);
}

+ 40
- 2
src/util.c View File

@@ -28,9 +28,10 @@
#include "cfg_file.h"
#include "main.h"

#ifdef RSPAMD_MAIN
sig_atomic_t do_reopen_log = 0;
extern rspamd_hash_t *counters;
#endif

struct logger_params {
GLogFunc log_func;
@@ -669,7 +670,9 @@ rspamd_set_logger (GLogFunc func, struct config_file *cfg)
int
reopen_log (struct config_file *cfg)
{
#ifdef RSPAMD_MAIN
do_reopen_log = 0;
#endif
close_log (cfg);
return open_log (cfg);
}
@@ -692,9 +695,11 @@ void
syslog_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer arg)
{
struct config_file *cfg = (struct config_file *)arg;
#ifdef RSPAMD_MAIN
if (do_reopen_log) {
reopen_log (cfg);
}
#endif

if (log_level <= cfg->log_level) {
if (log_level >= G_LOG_LEVEL_DEBUG) {
@@ -725,10 +730,11 @@ file_log_function (const gchar *log_domain, GLogLevelFlags log_level, const gcha
if (cfg->log_fd == -1) {
return;
}
#ifdef RSPAMD_MAIN
if (do_reopen_log) {
reopen_log (cfg);
}
#endif

if (log_level <= cfg->log_level) {
now = time (NULL);
@@ -844,6 +850,7 @@ calculate_check_time (struct timespec *begin, int resolution)
double
set_counter (const char *name, long int value)
{
#ifdef RSPAMD_MAIN
struct counter_data *cd;
double alpha;
char *key;
@@ -868,6 +875,9 @@ set_counter (const char *name, long int value)
}

return cd->value;
#else
return 0;
#endif
}

#ifndef g_tolower
@@ -899,6 +909,34 @@ rspamd_strcase_hash (gconstpointer key)
return h;
}

void
gperf_profiler_init (struct config_file *cfg, const char *descr)
{
#if defined(WITH_GPERF_TOOLS) && defined(MAIN_RSPAMD)
char prof_path[PATH_MAX];

if (getenv("CPUPROFILE")) {

/* disable inherited Profiler enabled in master process */
ProfilerStop ();
}
/* Try to create temp directory for gmon.out and chdir to it */
if (cfg->profile_path == NULL) {
cfg->profile_path = g_strdup_printf ("%s/rspamd-profile", cfg->temp_dir);
}

snprintf (prof_path, sizeof (prof_path), "%s-%s.%d", cfg->profile_path, descr, (int)getpid ());
if (ProfilerStart (prof_path)) {
/* start ITIMER_PROF timer */
ProfilerRegisterThread();
}
else {
msg_warn ("gperf_frofiler_init: cannot start google perftools profiler");
}

#endif
}

/*
* vi:ts=4
*/

+ 2
- 0
src/util.h View File

@@ -67,5 +67,7 @@ double set_counter (const char *name, long int value);
guint rspamd_strcase_hash (gconstpointer key);
gboolean rspamd_strcase_equal (gconstpointer v, gconstpointer v2);

void gperf_profiler_init (struct config_file *cfg, const char *descr);


#endif

+ 1
- 27
src/worker.c View File

@@ -48,10 +48,6 @@ extern PerlInterpreter *perl_interpreter;

#ifdef WITH_GPERF_TOOLS
#include <glib/gprintf.h>
/* Declare prototypes */
int ProfilerStart (u_char* fname);
void ProfilerStop (void);
void ProfilerRegisterThread (void);
#endif

static struct timeval io_tv;
@@ -343,29 +339,7 @@ start_worker (struct rspamd_worker *worker)
monstartup ((u_long) &_start, (u_long) &etext);
#endif

#ifdef WITH_GPERF_TOOLS
char prof_path[PATH_MAX];

if (getenv("CPUPROFILE")) {

/* disable inherited Profiler enabled in master process */
ProfilerStop ();
}
/* Try to create temp directory for gmon.out and chdir to it */
if (worker->srv->cfg->profile_path == NULL) {
worker->srv->cfg->profile_path = g_strdup_printf ("%s/rspamd-profile", worker->srv->cfg->temp_dir);
}

snprintf (prof_path, sizeof (prof_path), "%s.%d", worker->srv->cfg->profile_path, (int)getpid ());
if (ProfilerStart (prof_path)) {
/* start ITIMER_PROF timer */
ProfilerRegisterThread();
}
else {
msg_warn ("start_worker: cannot start google perftools profiler");
}

#endif
gperf_profiler_init (worker->srv->cfg, "worker");

worker->srv->pid = getpid ();


Loading…
Cancel
Save