blob: 8be5b97ec9bdf1e20c0fccf67fc39121f85facc0 [file] [log] [blame]
Igor Sysoev85dd8fc2008-03-18 10:36:27 +00001
2/*
3 * Copyright (C) Igor Sysoev
4 */
5
6
7#include <ngx_config.h>
8#include <ngx_core.h>
9
10/*
Igor Sysoevb45498c2010-03-26 11:27:32 +000011 * declare Profiler interface here because
Igor Sysoev85dd8fc2008-03-18 10:36:27 +000012 * <google/profiler.h> is C++ header file
13 */
14
15int ProfilerStart(u_char* fname);
16void ProfilerStop(void);
17void ProfilerRegisterThread(void);
18
19
20static void *ngx_google_perftools_create_conf(ngx_cycle_t *cycle);
21static ngx_int_t ngx_google_perftools_worker(ngx_cycle_t *cycle);
22
23
24typedef struct {
25 ngx_str_t profiles;
26} ngx_google_perftools_conf_t;
27
28
29static ngx_command_t ngx_google_perftools_commands[] = {
30
31 { ngx_string("google_perftools_profiles"),
32 NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
33 ngx_conf_set_str_slot,
34 0,
35 offsetof(ngx_google_perftools_conf_t, profiles),
36 NULL },
37
38 ngx_null_command
39};
40
41
42static ngx_core_module_t ngx_google_perftools_module_ctx = {
43 ngx_string("google_perftools"),
44 ngx_google_perftools_create_conf,
45 NULL
46};
47
48
49ngx_module_t ngx_google_perftools_module = {
50 NGX_MODULE_V1,
51 &ngx_google_perftools_module_ctx, /* module context */
52 ngx_google_perftools_commands, /* module directives */
53 NGX_CORE_MODULE, /* module type */
54 NULL, /* init master */
55 NULL, /* init module */
56 ngx_google_perftools_worker, /* init process */
57 NULL, /* init thread */
58 NULL, /* exit thread */
59 NULL, /* exit process */
60 NULL, /* exit master */
61 NGX_MODULE_V1_PADDING
62};
63
64
65static void *
66ngx_google_perftools_create_conf(ngx_cycle_t *cycle)
67{
68 ngx_google_perftools_conf_t *gptcf;
69
70 gptcf = ngx_pcalloc(cycle->pool, sizeof(ngx_google_perftools_conf_t));
71 if (gptcf == NULL) {
72 return NULL;
73 }
74
75 /*
Igor Sysoev86f791e2010-03-26 21:17:26 +000076 * set by ngx_pcalloc()
Igor Sysoev85dd8fc2008-03-18 10:36:27 +000077 *
78 * gptcf->profiles = { 0, NULL };
79 */
80
81 return gptcf;
82}
83
84
85static ngx_int_t
86ngx_google_perftools_worker(ngx_cycle_t *cycle)
87{
88 u_char *profile;
89 ngx_google_perftools_conf_t *gptcf;
90
91 gptcf = (ngx_google_perftools_conf_t *)
92 ngx_get_conf(cycle->conf_ctx, ngx_google_perftools_module);
93
94 if (gptcf->profiles.len == 0) {
95 return NGX_OK;
96 }
97
98 profile = ngx_alloc(gptcf->profiles.len + NGX_INT_T_LEN + 2, cycle->log);
99 if (profile == NULL) {
100 return NGX_OK;
101 }
102
103 if (getenv("CPUPROFILE")) {
Igor Sysoev85dd8fc2008-03-18 10:36:27 +0000104 /* disable inherited Profiler enabled in master process */
105 ProfilerStop();
106 }
107
108 ngx_sprintf(profile, "%V.%d%Z", &gptcf->profiles, ngx_pid);
109
110 if (ProfilerStart(profile)) {
Igor Sysoev85dd8fc2008-03-18 10:36:27 +0000111 /* start ITIMER_PROF timer */
112 ProfilerRegisterThread();
113
114 } else {
115 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
116 "ProfilerStart(%s) failed", profile);
117 }
118
119 ngx_free(profile);
120
121 return NGX_OK;
122}
123
124
125/* ProfilerStop() is called on Profiler destruction */