memprof 0.3.7 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
data/ext/memprof.c CHANGED
@@ -7,6 +7,7 @@
7
7
  #include <assert.h>
8
8
  #include <err.h>
9
9
  #include <fcntl.h>
10
+ #include <inttypes.h>
10
11
  #include <stddef.h>
11
12
  #include <stdint.h>
12
13
  #include <stdio.h>
@@ -485,8 +486,9 @@ memprof_trace_request(VALUE self, VALUE env)
485
486
  if (!rb_block_given_p())
486
487
  rb_raise(rb_eArgError, "block required");
487
488
 
488
- double secs;
489
- struct timeval now;
489
+ uint64_t start_time;
490
+ uint64_t end_time;
491
+ char str_time[32];
490
492
 
491
493
  json_gen gen;
492
494
  if (tracing_json_gen)
@@ -497,8 +499,9 @@ memprof_trace_request(VALUE self, VALUE env)
497
499
  json_gen_map_open(gen);
498
500
 
499
501
  json_gen_cstr(gen, "start");
500
- gettimeofday(&now, NULL);
501
- json_gen_integer(gen, (now.tv_sec * 1000) + (now.tv_usec / 1000));
502
+ start_time = timeofday_ms();
503
+ sprintf(str_time, "%" PRIu64, start_time);
504
+ json_gen_number(gen, str_time, strlen(str_time));
502
505
 
503
506
  json_gen_cstr(gen, "tracers");
504
507
  json_gen_map_open(gen);
@@ -507,32 +510,32 @@ memprof_trace_request(VALUE self, VALUE env)
507
510
  trace_invoke_all(TRACE_RESET);
508
511
  trace_invoke_all(TRACE_START);
509
512
 
510
- secs = timeofday();
513
+ start_time = timeofday_ms();
511
514
  VALUE ret = rb_yield(Qnil);
512
- secs = timeofday() - secs;
515
+ end_time = timeofday_ms();
513
516
 
514
517
  trace_invoke_all(TRACE_DUMP);
515
518
  trace_invoke_all(TRACE_STOP);
516
519
 
517
520
  json_gen_map_close(gen);
518
521
 
519
- if (RTEST(env) && BUILTIN_TYPE(env) == T_HASH) {
522
+ if (RTEST(env) && TYPE(env) == T_HASH) {
520
523
  VALUE val, str;
521
524
  val = rb_hash_aref(env, rb_str_new2("action_controller.request.path_parameters"));
522
525
  if (!RTEST(val))
523
526
  val = rb_hash_aref(env, rb_str_new2("action_dispatch.request.parameters"));
524
527
 
525
- if (RTEST(val) && BUILTIN_TYPE(val) == T_HASH) {
528
+ if (RTEST(val) && TYPE(val) == T_HASH) {
526
529
  json_gen_cstr(gen, "rails");
527
530
  json_gen_map_open(gen);
528
531
  str = rb_hash_aref(val, rb_str_new2("controller"));
529
- if (RTEST(str) && BUILTIN_TYPE(str) == T_STRING) {
532
+ if (RTEST(str) && TYPE(str) == T_STRING) {
530
533
  json_gen_cstr(gen, "controller");
531
534
  json_gen_cstr(gen, RSTRING_PTR(str));
532
535
  }
533
536
 
534
537
  str = rb_hash_aref(val, rb_str_new2("action"));
535
- if (RTEST(str) && BUILTIN_TYPE(str) == T_STRING) {
538
+ if (RTEST(str) && TYPE(str) == T_STRING) {
536
539
  json_gen_cstr(gen, "action");
537
540
  json_gen_cstr(gen, RSTRING_PTR(str));
538
541
  }
@@ -547,7 +550,7 @@ memprof_trace_request(VALUE self, VALUE env)
547
550
  #define DUMP_HASH_ENTRY(key) do { \
548
551
  str = rb_hash_aref(env, rb_str_new2(key)); \
549
552
  if (RTEST(str) && \
550
- BUILTIN_TYPE(str) == T_STRING && \
553
+ TYPE(str) == T_STRING && \
551
554
  RSTRING_PTR(str)) { \
552
555
  json_gen_cstr(gen, key); \
553
556
  json_gen_cstr(gen, RSTRING_PTR(str)); \
@@ -562,18 +565,18 @@ memprof_trace_request(VALUE self, VALUE env)
562
565
  DUMP_HASH_ENTRY("QUERY_STRING");
563
566
 
564
567
  json_gen_map_close(gen);
568
+ }
565
569
 
566
- if (RTEST(ret) && BUILTIN_TYPE(ret) == T_ARRAY) {
567
- json_gen_cstr(gen, "response");
568
- json_gen_map_open(gen);
569
- json_gen_cstr(gen, "code");
570
- json_gen_value(gen, RARRAY_PTR(ret)[0]);
571
- json_gen_map_close(gen);
572
- }
570
+ if (RTEST(ret) && TYPE(ret) == T_ARRAY) {
571
+ json_gen_cstr(gen, "response");
572
+ json_gen_map_open(gen);
573
+ json_gen_cstr(gen, "code");
574
+ json_gen_value(gen, RARRAY_PTR(ret)[0]);
575
+ json_gen_map_close(gen);
573
576
  }
574
577
 
575
578
  json_gen_cstr(gen, "time");
576
- json_gen_double(gen, secs);
579
+ json_gen_integer(gen, end_time-start_time);
577
580
 
578
581
  json_gen_map_close(gen);
579
582
  json_gen_reset(gen);
data/ext/tracers/fd.c CHANGED
@@ -1,5 +1,6 @@
1
1
  #include <assert.h>
2
2
  #include <errno.h>
3
+ #include <poll.h>
3
4
  #include <stdio.h>
4
5
  #include <stdlib.h>
5
6
  #include <string.h>
@@ -17,20 +18,23 @@
17
18
 
18
19
  struct memprof_fd_stats {
19
20
  size_t read_calls;
20
- double read_time;
21
+ uint32_t read_time;
21
22
  size_t read_requested_bytes;
22
23
  size_t read_actual_bytes;
23
24
 
24
25
  size_t write_calls;
25
- double write_time;
26
+ uint32_t write_time;
26
27
  size_t write_requested_bytes;
27
28
  size_t write_actual_bytes;
28
29
 
29
30
  size_t connect_calls;
30
- double connect_time;
31
+ uint32_t connect_time;
31
32
 
32
33
  size_t select_calls;
33
- double select_time;
34
+ uint32_t select_time;
35
+
36
+ size_t poll_calls;
37
+ uint32_t poll_time;
34
38
  };
35
39
 
36
40
  static struct tracer tracer;
@@ -38,16 +42,16 @@ static struct memprof_fd_stats stats;
38
42
 
39
43
  static ssize_t
40
44
  read_tramp(int fildes, void *buf, size_t nbyte) {
41
- double secs = 0;
45
+ uint32_t millis = 0;
42
46
  int err;
43
47
  ssize_t ret;
44
48
 
45
- secs = timeofday();
49
+ millis = timeofday_ms();
46
50
  ret = read(fildes, buf, nbyte);
47
51
  err = errno;
48
- secs = timeofday() - secs;
52
+ millis = timeofday_ms() - millis;
49
53
 
50
- stats.read_time += secs;
54
+ stats.read_time += millis;
51
55
  stats.read_calls++;
52
56
  stats.read_requested_bytes += nbyte;
53
57
  if (ret > 0)
@@ -59,16 +63,16 @@ read_tramp(int fildes, void *buf, size_t nbyte) {
59
63
 
60
64
  static ssize_t
61
65
  write_tramp(int fildes, const void *buf, size_t nbyte) {
62
- double secs = 0;
66
+ uint32_t millis = 0;
63
67
  int err;
64
68
  ssize_t ret;
65
69
 
66
- secs = timeofday();
70
+ millis = timeofday_ms();
67
71
  ret = write(fildes, buf, nbyte);
68
72
  err = errno;
69
- secs = timeofday() - secs;
73
+ millis = timeofday_ms() - millis;
70
74
 
71
- stats.write_time += secs;
75
+ stats.write_time += millis;
72
76
  stats.write_calls++;
73
77
  stats.write_requested_bytes += nbyte;
74
78
  if (ret > 0)
@@ -80,15 +84,15 @@ write_tramp(int fildes, const void *buf, size_t nbyte) {
80
84
 
81
85
  static int
82
86
  connect_tramp(int socket, const struct sockaddr *address, socklen_t address_len) {
83
- double secs = 0;
87
+ uint32_t millis = 0;
84
88
  int err, ret;
85
89
 
86
- secs = timeofday();
90
+ millis = timeofday_ms();
87
91
  ret = connect(socket, address, address_len);
88
92
  err = errno;
89
- secs = timeofday() - secs;
93
+ millis = timeofday_ms() - millis;
90
94
 
91
- stats.connect_time += secs;
95
+ stats.connect_time += millis;
92
96
  stats.connect_calls++;
93
97
 
94
98
  errno = err;
@@ -98,21 +102,39 @@ connect_tramp(int socket, const struct sockaddr *address, socklen_t address_len)
98
102
  static int
99
103
  select_tramp(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout)
100
104
  {
101
- double secs = 0;
105
+ uint32_t millis = 0;
102
106
  int ret, err;
103
107
 
104
- secs = timeofday();
108
+ millis = timeofday_ms();
105
109
  ret = select(nfds, readfds, writefds, errorfds, timeout);
106
110
  err = errno;
107
- secs = timeofday() - secs;
111
+ millis = timeofday_ms() - millis;
108
112
 
109
- stats.select_time += secs;
113
+ stats.select_time += millis;
110
114
  stats.select_calls++;
111
115
 
112
116
  errno = err;
113
117
  return ret;
114
118
  }
115
119
 
120
+ static int
121
+ poll_tramp(struct pollfd fds[], nfds_t nfds, int timeout)
122
+ {
123
+ uint32_t millis = 0;
124
+ int ret, err;
125
+
126
+ millis = timeofday_ms();
127
+ ret = poll(fds, nfds, timeout);
128
+ err = errno;
129
+ millis = timeofday_ms() - millis;
130
+
131
+ stats.poll_time += millis;
132
+ stats.poll_calls++;
133
+
134
+ errno = err;
135
+ return ret;
136
+ }
137
+
116
138
  static void
117
139
  fd_trace_start() {
118
140
  static int inserted = 0;
@@ -124,11 +146,13 @@ fd_trace_start() {
124
146
 
125
147
  insert_tramp("read", read_tramp);
126
148
  insert_tramp("write", write_tramp);
127
- insert_tramp("connect", connect_tramp);
149
+ insert_tramp("poll", poll_tramp);
150
+
128
151
  #ifdef HAVE_MACH
129
152
  insert_tramp("select$DARWIN_EXTSN", select_tramp);
130
153
  #else
131
154
  insert_tramp("select", select_tramp);
155
+ insert_tramp("connect", connect_tramp);
132
156
  #endif
133
157
  }
134
158
 
@@ -149,7 +173,7 @@ fd_trace_dump(json_gen gen) {
149
173
  json_gen_cstr(gen, "calls");
150
174
  json_gen_integer(gen, stats.read_calls);
151
175
  json_gen_cstr(gen, "time");
152
- json_gen_double(gen, stats.read_time);
176
+ json_gen_integer(gen, stats.read_time);
153
177
  json_gen_cstr(gen, "requested");
154
178
  json_gen_integer(gen, stats.read_requested_bytes);
155
179
  json_gen_cstr(gen, "actual");
@@ -163,7 +187,7 @@ fd_trace_dump(json_gen gen) {
163
187
  json_gen_cstr(gen, "calls");
164
188
  json_gen_integer(gen, stats.write_calls);
165
189
  json_gen_cstr(gen, "time");
166
- json_gen_double(gen, stats.write_time);
190
+ json_gen_integer(gen, stats.write_time);
167
191
  json_gen_cstr(gen, "requested");
168
192
  json_gen_integer(gen, stats.write_requested_bytes);
169
193
  json_gen_cstr(gen, "actual");
@@ -177,7 +201,7 @@ fd_trace_dump(json_gen gen) {
177
201
  json_gen_cstr(gen, "calls");
178
202
  json_gen_integer(gen, stats.connect_calls);
179
203
  json_gen_cstr(gen, "time");
180
- json_gen_double(gen, stats.connect_time);
204
+ json_gen_integer(gen, stats.connect_time);
181
205
  json_gen_map_close(gen);
182
206
  }
183
207
 
@@ -187,7 +211,17 @@ fd_trace_dump(json_gen gen) {
187
211
  json_gen_cstr(gen, "calls");
188
212
  json_gen_integer(gen, stats.select_calls);
189
213
  json_gen_cstr(gen, "time");
190
- json_gen_double(gen, stats.select_time);
214
+ json_gen_integer(gen, stats.select_time);
215
+ json_gen_map_close(gen);
216
+ }
217
+
218
+ if (stats.poll_calls > 0) {
219
+ json_gen_cstr(gen, "poll");
220
+ json_gen_map_open(gen);
221
+ json_gen_cstr(gen, "calls");
222
+ json_gen_integer(gen, stats.poll_calls);
223
+ json_gen_cstr(gen, "time");
224
+ json_gen_integer(gen, stats.poll_time);
191
225
  json_gen_map_close(gen);
192
226
  }
193
227
  }
data/ext/tracers/gc.c CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  struct memprof_gc_stats {
15
15
  size_t gc_calls;
16
- double gc_time;
16
+ uint32_t gc_time;
17
17
  };
18
18
 
19
19
  static struct tracer tracer;
@@ -23,13 +23,13 @@ static void (*orig_garbage_collect)();
23
23
  static void
24
24
  gc_tramp()
25
25
  {
26
- double secs = 0;
26
+ uint32_t millis = 0;
27
27
 
28
- secs = timeofday();
28
+ millis = timeofday_ms();
29
29
  orig_garbage_collect();
30
- secs = timeofday() - secs;
30
+ millis = timeofday_ms() - millis;
31
31
 
32
- stats.gc_time += secs;
32
+ stats.gc_time += millis;
33
33
  stats.gc_calls++;
34
34
  }
35
35
 
@@ -64,7 +64,7 @@ gc_trace_dump(json_gen gen) {
64
64
  json_gen_integer(gen, stats.gc_calls);
65
65
 
66
66
  json_gen_cstr(gen, "time");
67
- json_gen_double(gen, stats.gc_time);
67
+ json_gen_integer(gen, stats.gc_time);
68
68
  }
69
69
 
70
70
  void install_gc_tracer()
data/ext/tracers/mysql.c CHANGED
@@ -9,30 +9,55 @@
9
9
  #include "bin_api.h"
10
10
  #include "json.h"
11
11
  #include "tracer.h"
12
+ #include "tracers/sql.h"
12
13
  #include "tramp.h"
13
14
  #include "util.h"
14
15
 
15
16
  struct memprof_mysql_stats {
16
17
  size_t query_calls;
17
- double query_time;
18
+ uint32_t query_time;
19
+
20
+ size_t query_calls_by_type[sql_UNKNOWN];
21
+ uint32_t query_time_by_type[sql_UNKNOWN];
18
22
  };
19
23
 
20
24
  static struct tracer tracer;
21
25
  static struct memprof_mysql_stats stats;
26
+
22
27
  static int (*orig_real_query)(void *mysql, const char *stmt_str, unsigned long length);
28
+ static int (*orig_send_query)(void *mysql, const char *stmt_str, unsigned long length);
23
29
 
24
30
  static int
25
31
  real_query_tramp(void *mysql, const char *stmt_str, unsigned long length) {
26
- double secs = 0;
32
+ enum memprof_sql_type type;
33
+ uint32_t millis = 0;
27
34
  int ret;
28
35
 
29
- secs = timeofday();
36
+ millis = timeofday_ms();
30
37
  ret = orig_real_query(mysql, stmt_str, length);
31
- secs = timeofday() - secs;
38
+ millis = timeofday_ms() - millis;
39
+
40
+ stats.query_time += millis;
41
+ stats.query_calls++;
42
+
43
+ type = memprof_sql_query_type(stmt_str, length);
44
+ stats.query_time_by_type[type] += millis;
45
+ stats.query_calls_by_type[type]++;
46
+
47
+ return ret;
48
+ }
49
+
50
+ static int
51
+ send_query_tramp(void *mysql, const char *stmt_str, unsigned long length) {
52
+ enum memprof_sql_type type;
53
+ int ret;
32
54
 
33
- stats.query_time += secs;
55
+ ret = orig_send_query(mysql, stmt_str, length);
34
56
  stats.query_calls++;
35
57
 
58
+ type = memprof_sql_query_type(stmt_str, length);
59
+ stats.query_calls_by_type[type]++;
60
+
36
61
  return ret;
37
62
  }
38
63
 
@@ -48,6 +73,10 @@ mysql_trace_start() {
48
73
  orig_real_query = bin_find_symbol("mysql_real_query", NULL, 1);
49
74
  if (orig_real_query)
50
75
  insert_tramp("mysql_real_query", real_query_tramp);
76
+
77
+ orig_send_query = bin_find_symbol("mysql_send_query", NULL, 1);
78
+ if (orig_send_query)
79
+ insert_tramp("mysql_send_query", send_query_tramp);
51
80
  }
52
81
 
53
82
  static void
@@ -61,12 +90,30 @@ mysql_trace_reset() {
61
90
 
62
91
  static void
63
92
  mysql_trace_dump(json_gen gen) {
93
+ enum memprof_sql_type i;
94
+
64
95
  if (stats.query_calls > 0) {
65
96
  json_gen_cstr(gen, "queries");
66
97
  json_gen_integer(gen, stats.query_calls);
67
98
 
68
99
  json_gen_cstr(gen, "time");
69
- json_gen_double(gen, stats.query_time);
100
+ json_gen_integer(gen, stats.query_time);
101
+
102
+ json_gen_cstr(gen, "types");
103
+ json_gen_map_open(gen);
104
+ for (i=0; i<=sql_UNKNOWN; i++) {
105
+ json_gen_cstr(gen, memprof_sql_type_str(i));
106
+ json_gen_map_open(gen);
107
+
108
+ json_gen_cstr(gen, "queries");
109
+ json_gen_integer(gen, stats.query_calls_by_type[i]);
110
+
111
+ json_gen_cstr(gen, "time");
112
+ json_gen_integer(gen, stats.query_time_by_type[i]);
113
+
114
+ json_gen_map_close(gen);
115
+ }
116
+ json_gen_map_close(gen);
70
117
  }
71
118
  }
72
119
 
@@ -9,11 +9,13 @@
9
9
  #include "bin_api.h"
10
10
  #include "json.h"
11
11
  #include "tracer.h"
12
+ #include "tracers/sql.h"
12
13
  #include "tramp.h"
13
14
  #include "util.h"
14
15
 
15
16
  struct memprof_postgres_stats {
16
17
  size_t query_calls;
18
+ size_t query_calls_by_type[sql_UNKNOWN+1];
17
19
  };
18
20
 
19
21
  static struct tracer tracer;
@@ -22,11 +24,15 @@ static void * (*orig_PQexec)(void *postgres, const char *stmt);
22
24
 
23
25
  static void *
24
26
  PQexec_tramp(void *postgres, const char *stmt) {
27
+ enum memprof_sql_type type;
25
28
  void *ret;
26
29
 
27
30
  ret = orig_PQexec(postgres, stmt);
28
31
  stats.query_calls++;
29
32
 
33
+ type = memprof_sql_query_type(stmt, strlen(stmt));
34
+ stats.query_calls_by_type[type]++;
35
+
30
36
  return ret;
31
37
  }
32
38
 
@@ -55,9 +61,22 @@ postgres_trace_reset() {
55
61
 
56
62
  static void
57
63
  postgres_trace_dump(json_gen gen) {
64
+ enum memprof_sql_type i;
65
+
58
66
  if (stats.query_calls > 0) {
59
67
  json_gen_cstr(gen, "queries");
60
68
  json_gen_integer(gen, stats.query_calls);
69
+
70
+ json_gen_cstr(gen, "types");
71
+ json_gen_map_open(gen);
72
+ for (i=0; i<=sql_UNKNOWN; i++) {
73
+ json_gen_cstr(gen, memprof_sql_type_str(i));
74
+ json_gen_map_open(gen);
75
+ json_gen_cstr(gen, "queries");
76
+ json_gen_integer(gen, stats.query_calls_by_type[i]);
77
+ json_gen_map_close(gen);
78
+ }
79
+ json_gen_map_close(gen);
61
80
  }
62
81
  }
63
82
 
@@ -15,14 +15,14 @@ struct memprof_resources_stats {
15
15
  long inblock;
16
16
  long oublock;
17
17
 
18
- double utime;
19
- double stime;
18
+ int64_t utime;
19
+ int64_t stime;
20
20
  };
21
21
 
22
22
  static struct tracer tracer;
23
23
  static struct memprof_resources_stats stats;
24
24
 
25
- #define TVAL_TO_DBL(tv) ((double)tv.tv_sec + (double)tv.tv_usec * 1e-6)
25
+ #define TVAL_TO_INT64(tv) ((int64_t)tv.tv_sec*1e3 + (int64_t)tv.tv_usec*1e-3)
26
26
 
27
27
  static void
28
28
  resources_trace_start() {
@@ -34,8 +34,8 @@ resources_trace_start() {
34
34
  stats.inblock = -usage.ru_inblock;
35
35
  stats.oublock = -usage.ru_oublock;
36
36
 
37
- stats.stime = -TVAL_TO_DBL(usage.ru_stime);
38
- stats.utime = -TVAL_TO_DBL(usage.ru_utime);
37
+ stats.stime = -TVAL_TO_INT64(usage.ru_stime);
38
+ stats.utime = -TVAL_TO_INT64(usage.ru_utime);
39
39
  }
40
40
 
41
41
  static void
@@ -49,8 +49,8 @@ resources_trace_dump(json_gen gen) {
49
49
  stats.inblock += usage.ru_inblock;
50
50
  stats.oublock += usage.ru_oublock;
51
51
 
52
- stats.stime += TVAL_TO_DBL(usage.ru_stime);
53
- stats.utime += TVAL_TO_DBL(usage.ru_utime);
52
+ stats.stime += TVAL_TO_INT64(usage.ru_stime);
53
+ stats.utime += TVAL_TO_INT64(usage.ru_utime);
54
54
  }
55
55
 
56
56
  json_gen_cstr(gen, "signals");
@@ -63,10 +63,10 @@ resources_trace_dump(json_gen gen) {
63
63
  json_gen_integer(gen, stats.oublock);
64
64
 
65
65
  json_gen_cstr(gen, "stime");
66
- json_gen_double(gen, stats.stime);
66
+ json_gen_integer(gen, stats.stime);
67
67
 
68
68
  json_gen_cstr(gen, "utime");
69
- json_gen_double(gen, stats.utime);
69
+ json_gen_integer(gen, stats.utime);
70
70
  }
71
71
 
72
72
  static void
@@ -83,7 +83,7 @@ void install_resources_tracer()
83
83
  tracer.stop = resources_trace_stop;
84
84
  tracer.reset = resources_trace_reset;
85
85
  tracer.dump = resources_trace_dump;
86
- tracer.id = "resource";
86
+ tracer.id = "resources";
87
87
 
88
88
  trace_insert(&tracer);
89
89
  }
data/ext/tracers/sql.c ADDED
@@ -0,0 +1,56 @@
1
+ #include <tracers/sql.h>
2
+
3
+ enum memprof_sql_type
4
+ memprof_sql_query_type(const char *stmt, unsigned long length)
5
+ {
6
+ int i;
7
+
8
+ for (i=0; i<length && i<10; i++) {
9
+ switch (stmt[i]) {
10
+ case ' ':
11
+ case '\n':
12
+ case '\r':
13
+ continue;
14
+ break;
15
+
16
+ case 'S':
17
+ case 's':
18
+ return sql_SELECT;
19
+
20
+ case 'I':
21
+ case 'i':
22
+ return sql_INSERT;
23
+
24
+ case 'U':
25
+ case 'u':
26
+ return sql_UPDATE;
27
+
28
+ case 'D':
29
+ case 'd':
30
+ return sql_DELETE;
31
+
32
+ default:
33
+ return sql_UNKNOWN;
34
+ }
35
+ }
36
+
37
+ return sql_UNKNOWN;
38
+ }
39
+
40
+ const char *
41
+ memprof_sql_type_str(enum memprof_sql_type type)
42
+ {
43
+ switch (type) {
44
+ case sql_SELECT:
45
+ return "select";
46
+ case sql_UPDATE:
47
+ return "update";
48
+ case sql_INSERT:
49
+ return "insert";
50
+ case sql_DELETE:
51
+ return "delete";
52
+ default:
53
+ case sql_UNKNOWN:
54
+ return "unknown";
55
+ }
56
+ }
data/ext/tracers/sql.h ADDED
@@ -0,0 +1,18 @@
1
+ #if !defined(_sql_h_)
2
+ #define _sql_h_
3
+
4
+ enum memprof_sql_type {
5
+ sql_SELECT,
6
+ sql_UPDATE,
7
+ sql_INSERT,
8
+ sql_DELETE,
9
+ sql_UNKNOWN // last
10
+ };
11
+
12
+ enum memprof_sql_type
13
+ memprof_sql_query_type(const char *stmt, unsigned long length);
14
+
15
+ const char *
16
+ memprof_sql_type_str(enum memprof_sql_type);
17
+
18
+ #endif
data/ext/util.c CHANGED
@@ -89,3 +89,11 @@ timeofday()
89
89
  gettimeofday(&tv, NULL);
90
90
  return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
91
91
  }
92
+
93
+ uint64_t
94
+ timeofday_ms()
95
+ {
96
+ struct timeval tv;
97
+ gettimeofday(&tv, NULL);
98
+ return (uint64_t)tv.tv_sec*1e3 + (uint64_t)tv.tv_usec*1e-3;
99
+ }
data/ext/util.h CHANGED
@@ -1,6 +1,8 @@
1
1
  #if !defined(__util_h__)
2
2
  #define __util_h__
3
3
 
4
+ #include <stdint.h>
5
+
4
6
  #if defined(_MEMPROF_DEBUG)
5
7
  #include <stdio.h>
6
8
  #define dbg_printf(...) do {\
@@ -73,9 +75,13 @@ struct memprof_config {
73
75
  unsigned long
74
76
  gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len);
75
77
 
78
+ /* Copy of timeofday() implementation inside ruby 1.8, used w/ thread state */
79
+ double
80
+ timeofday();
81
+
76
82
  /* Use this function for time tracking. It will (interally) try to use an
77
83
  * appropriately granual timing function.
78
84
  */
79
- double
80
- timeofday();
85
+ uint64_t
86
+ timeofday_ms();
81
87
  #endif
data/memprof.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = 'memprof'
3
- s.version = '0.3.7'
3
+ s.version = '0.3.8'
4
4
  s.summary = 'Ruby Memory Profiler'
5
5
  s.description = "Ruby memory profiler similar to bleak_house, but without patches to the Ruby VM"
6
6
  s.homepage = "http://github.com/ice799/memprof"
data/spec/tracing_spec.rb CHANGED
@@ -38,9 +38,9 @@ describe 'Memprof tracers' do
38
38
  select(nil, nil, nil, 0.15)
39
39
  end
40
40
 
41
- filedata.should =~ /"select":\{"calls":1,"time":0\.1[567]/
41
+ filedata.should =~ /"select":\{"calls":1,"time":1[567]\d/
42
42
  time = filedata[/"select":\{"calls":\d+,"time":([\d.]+)/, 1].to_f
43
- time.should.be.close(0.15, 0.1)
43
+ time.should.be.close(150, 10)
44
44
  end
45
45
 
46
46
  should 'trace objects created for block' do
@@ -79,7 +79,7 @@ describe 'Memprof tracers' do
79
79
 
80
80
  filedata.should =~ /"mysql":\{"queries":5,"time":([\d.]+)/
81
81
  time = filedata[/"mysql":\{"queries":5,"time":([\d.]+)/, 1].to_f
82
- time.should.be.close(0.25, 0.1)
82
+ time.should.be.close(250, 25)
83
83
  end
84
84
  rescue Mysql::Error => e
85
85
  raise unless e.message =~ /connect/
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memprof
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 7
10
- version: 0.3.7
9
+ - 8
10
+ version: 0.3.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Joe Damato
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2011-01-28 00:00:00 -08:00
21
+ date: 2011-01-31 00:00:00 -08:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
@@ -91,6 +91,8 @@ files:
91
91
  - ext/tracers/objects.c
92
92
  - ext/tracers/postgres.c
93
93
  - ext/tracers/resources.c
94
+ - ext/tracers/sql.c
95
+ - ext/tracers/sql.h
94
96
  - ext/tramp.c
95
97
  - ext/tramp.h
96
98
  - ext/util.c