]> source.dussan.org Git - rspamd.git/commitdiff
* Improve google perf tools support
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 25 Aug 2009 09:50:35 +0000 (13:50 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 25 Aug 2009 09:50:35 +0000 (13:50 +0400)
* Pass to event_add only copies of struct timeval to avoid timing problems

CMakeLists.txt
config.h.in
src/buffer.c
src/controller.c
src/fuzzy_storage.c
src/lmtp.c
src/util.c
src/util.h
src/worker.c

index 3024a07d2e074085a63b67e05a6aa0d26c27b1c4..d52ee61ef4f589534e45a3006629b7ef8a42d74a 100644 (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")
index 12593da611a729356664d6f46445b45b07c615ed..0db410bb530b91f5375d40052522ce6cf1c70ce4 100644 (file)
 #define HAVE_SETLOCALE 1
 #endif
 
+#ifdef WITH_GPERF_TOOLS
+#include <google/profiler.h>
+#endif
+
 #include <errno.h>
 #include <signal.h>
 #include <event.h>
index f8d027307bb3f6c4cf119644c51b42da7264f947..d212fc22096f7be6fa9c36ada577d9620fd618c6 100644 (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);
        }
 }
 
index 65434c974c833e3f9d03cf4eba7a2931e38e12af..4196e16f04937577fcdf13499a55c59539bf396f 100644 (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);
index 296e815624dbec9ee7e856d684d63e4a2c9c9aaf..53f3d9b16c3b5a746e1f7b2dbbb3e4184e4e335e 100644 (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);
index 6554ba4f4d6b9ba7962d95f90c5207c0fa5897c7..c3d5ab344eb70fa88f40611d556b1a9703f4776e 100644 (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);
 }
index 364e1b0a4820b63ad7d73432c88dc8398c1a3c55..585aa5cb8a1c806c6ace699167dacbc8b8a6c9fd 100644 (file)
 #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
  */
index d7665d462f5c4050ff00789b608873969a899106..139a44262205ebf9204d7527b402801b21a7044e 100644 (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
index 4832c71fcc794910b0348e144c0ce01922462757..9e9b739382c1e2337ba53239bfa4a6f6ac29540a 100644 (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 ();