ngx_google_perftools_module
Igor Sysoev
14 years ago
41 | 41 | if [ $USE_PERL = YES ]; then |
42 | 42 | . auto/lib/perl/conf |
43 | 43 | fi |
44 | ||
45 | if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then | |
46 | . auto/lib/google-perftools/conf | |
47 | fi |
0 | ||
1 | # Copyright (C) Igor Sysoev | |
2 | ||
3 | ||
4 | ngx_feature="Google perftools" | |
5 | ngx_feature_name= | |
6 | ngx_feature_run=no | |
7 | ngx_feature_incs= | |
8 | ngx_feature_path= | |
9 | ngx_feature_libs="-lprofiler" | |
10 | ngx_feature_test="ProfilerStop()" | |
11 | . auto/feature | |
12 | ||
13 | ||
14 | if [ $ngx_found = no ]; then | |
15 | ||
16 | # FreeBSD port | |
17 | ||
18 | ngx_feature="Google perftools in /usr/local/" | |
19 | ||
20 | if [ $NGX_RPATH = YES ]; then | |
21 | ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lprofiler" | |
22 | else | |
23 | ngx_feature_libs="-L/usr/local/lib -lprofiler" | |
24 | fi | |
25 | ||
26 | . auto/feature | |
27 | fi | |
28 | ||
29 | ||
30 | if [ $ngx_found = yes ]; then | |
31 | CORE_LIBS="$CORE_LIBS $ngx_feature_libs" | |
32 | fi |
5 | 5 | $NGX_OBJS/src/os/unix $NGX_OBJS/src/os/win32 \ |
6 | 6 | $NGX_OBJS/src/http $NGX_OBJS/src/http/modules \ |
7 | 7 | $NGX_OBJS/src/http/modules/perl \ |
8 | $NGX_OBJS/src/mail | |
8 | $NGX_OBJS/src/mail \ | |
9 | $NGX_OBJS/src/misc | |
9 | 10 | |
10 | 11 | |
11 | 12 | ngx_objs_dir=$NGX_OBJS$ngx_regex_dirsep |
124 | 125 | END |
125 | 126 | |
126 | 127 | fi |
128 | ||
129 | ||
130 | ngx_all_srcs="$ngx_all_srcs $NGX_MISC_SRCS" | |
127 | 131 | |
128 | 132 | |
129 | 133 | if test -n "$NGX_ADDON_SRCS"; then |
308 | 312 | fi |
309 | 313 | |
310 | 314 | |
315 | # the misc sources | |
316 | ||
317 | if test -n "$NGX_MISC_SRCS"; then | |
318 | ||
319 | ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" | |
320 | ||
321 | for ngx_src in $NGX_MISC_SRCS | |
322 | do | |
323 | ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` | |
324 | ngx_obj=`echo $ngx_src \ | |
325 | | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \ | |
326 | -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \ | |
327 | -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \ | |
328 | -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"` | |
329 | ||
330 | cat << END >> $NGX_MAKEFILE | |
331 | ||
332 | $ngx_obj: \$(CORE_DEPS) $ngx_cont$ngx_src | |
333 | $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX | |
334 | ||
335 | END | |
336 | done | |
337 | ||
338 | fi | |
339 | ||
340 | ||
311 | 341 | # the addons sources |
312 | 342 | |
313 | 343 | if test -n "$NGX_ADDON_SRCS"; then |
374 | 374 | fi |
375 | 375 | |
376 | 376 | |
377 | if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then | |
378 | modules="$modules $NGX_GOOGLE_PERFTOOLS_MODULE" | |
379 | NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_GOOGLE_PERFTOOLS_SRCS" | |
380 | fi | |
381 | ||
382 | ||
377 | 383 | cat << END > $NGX_MODULES_C |
378 | 384 | |
379 | 385 | #include <ngx_config.h> |
114 | 114 | USE_PERL=NO |
115 | 115 | NGX_PERL=perl |
116 | 116 | |
117 | NGX_GOOGLE_PERFTOOLS=NO | |
118 | ||
117 | 119 | NGX_CPU_CACHE_LINE= |
118 | 120 | |
119 | 121 | |
200 | 202 | --without-mail_imap_module) MAIL_IMAP=NO ;; |
201 | 203 | --without-mail_smtp_module) MAIL_SMTP=NO ;; |
202 | 204 | |
205 | --with-google_perftools_module) NGX_GOOGLE_PERFTOOLS=YES ;; | |
206 | ||
203 | 207 | --add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;; |
204 | 208 | |
205 | 209 | --with-cc=*) CC="$value" ;; |
316 | 320 | --without-mail_imap_module disable ngx_mail_imap_module |
317 | 321 | --without-mail_smtp_module disable ngx_mail_smtp_module |
318 | 322 | |
323 | --with-google_perftools_module enable ngx_google_perftools_module | |
324 | ||
319 | 325 | --add-module=PATH enable an external module |
320 | 326 | |
321 | 327 | --with-cc=PATH set path to C compiler |
459 | 459 | |
460 | 460 | MAIL_PROXY_MODULE="ngx_mail_proxy_module" |
461 | 461 | MAIL_PROXY_SRCS="src/mail/ngx_mail_proxy_module.c" |
462 | ||
463 | NGX_GOOGLE_PERFTOOLS_MODULE=ngx_google_perftools_module | |
464 | NGX_GOOGLE_PERFTOOLS_SRCS=src/misc/ngx_google_perftools_module.c | |
465 |
0 | ||
1 | /* | |
2 | * Copyright (C) Igor Sysoev | |
3 | */ | |
4 | ||
5 | ||
6 | #include <ngx_config.h> | |
7 | #include <ngx_core.h> | |
8 | ||
9 | /* | |
10 | * declare Profiler here interface because | |
11 | * <google/profiler.h> is C++ header file | |
12 | */ | |
13 | ||
14 | int ProfilerStart(u_char* fname); | |
15 | void ProfilerStop(void); | |
16 | void ProfilerRegisterThread(void); | |
17 | ||
18 | ||
19 | static void *ngx_google_perftools_create_conf(ngx_cycle_t *cycle); | |
20 | static ngx_int_t ngx_google_perftools_worker(ngx_cycle_t *cycle); | |
21 | ||
22 | ||
23 | typedef struct { | |
24 | ngx_str_t profiles; | |
25 | } ngx_google_perftools_conf_t; | |
26 | ||
27 | ||
28 | static ngx_command_t ngx_google_perftools_commands[] = { | |
29 | ||
30 | { ngx_string("google_perftools_profiles"), | |
31 | NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, | |
32 | ngx_conf_set_str_slot, | |
33 | 0, | |
34 | offsetof(ngx_google_perftools_conf_t, profiles), | |
35 | NULL }, | |
36 | ||
37 | ngx_null_command | |
38 | }; | |
39 | ||
40 | ||
41 | static ngx_core_module_t ngx_google_perftools_module_ctx = { | |
42 | ngx_string("google_perftools"), | |
43 | ngx_google_perftools_create_conf, | |
44 | NULL | |
45 | }; | |
46 | ||
47 | ||
48 | ngx_module_t ngx_google_perftools_module = { | |
49 | NGX_MODULE_V1, | |
50 | &ngx_google_perftools_module_ctx, /* module context */ | |
51 | ngx_google_perftools_commands, /* module directives */ | |
52 | NGX_CORE_MODULE, /* module type */ | |
53 | NULL, /* init master */ | |
54 | NULL, /* init module */ | |
55 | ngx_google_perftools_worker, /* init process */ | |
56 | NULL, /* init thread */ | |
57 | NULL, /* exit thread */ | |
58 | NULL, /* exit process */ | |
59 | NULL, /* exit master */ | |
60 | NGX_MODULE_V1_PADDING | |
61 | }; | |
62 | ||
63 | ||
64 | static void * | |
65 | ngx_google_perftools_create_conf(ngx_cycle_t *cycle) | |
66 | { | |
67 | ngx_google_perftools_conf_t *gptcf; | |
68 | ||
69 | gptcf = ngx_pcalloc(cycle->pool, sizeof(ngx_google_perftools_conf_t)); | |
70 | if (gptcf == NULL) { | |
71 | return NULL; | |
72 | } | |
73 | ||
74 | /* | |
75 | * set by pcalloc() | |
76 | * | |
77 | * gptcf->profiles = { 0, NULL }; | |
78 | */ | |
79 | ||
80 | return gptcf; | |
81 | } | |
82 | ||
83 | ||
84 | static ngx_int_t | |
85 | ngx_google_perftools_worker(ngx_cycle_t *cycle) | |
86 | { | |
87 | u_char *profile; | |
88 | ngx_google_perftools_conf_t *gptcf; | |
89 | ||
90 | gptcf = (ngx_google_perftools_conf_t *) | |
91 | ngx_get_conf(cycle->conf_ctx, ngx_google_perftools_module); | |
92 | ||
93 | if (gptcf->profiles.len == 0) { | |
94 | return NGX_OK; | |
95 | } | |
96 | ||
97 | profile = ngx_alloc(gptcf->profiles.len + NGX_INT_T_LEN + 2, cycle->log); | |
98 | if (profile == NULL) { | |
99 | return NGX_OK; | |
100 | } | |
101 | ||
102 | if (getenv("CPUPROFILE")) { | |
103 | ||
104 | /* 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)) { | |
111 | ||
112 | /* start ITIMER_PROF timer */ | |
113 | ProfilerRegisterThread(); | |
114 | ||
115 | } else { | |
116 | ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno, | |
117 | "ProfilerStart(%s) failed", profile); | |
118 | } | |
119 | ||
120 | ngx_free(profile); | |
121 | ||
122 | return NGX_OK; | |
123 | } | |
124 | ||
125 | ||
126 | /* ProfilerStop() is called on Profiler destruction */ |