memprof 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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