~ubuntu-branches/ubuntu/karmic/firebird2.1/karmic

« back to all changes in this revision

Viewing changes to src/jrd/perf.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Damyan Ivanov
  • Date: 2008-05-26 23:59:25 UTC
  • Revision ID: james.westby@ubuntu.com-20080526235925-2pnqj6nxpppoeaer
Tags: upstream-2.1.0.17798-0.ds2
ImportĀ upstreamĀ versionĀ 2.1.0.17798-0.ds2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      PROGRAM:        JRD Access Method
 
3
 *      MODULE:         perf.cpp
 
4
 *      DESCRIPTION:    Performance monitoring routines
 
5
 *
 
6
 * The contents of this file are subject to the Interbase Public
 
7
 * License Version 1.0 (the "License"); you may not use this file
 
8
 * except in compliance with the License. You may obtain a copy
 
9
 * of the License at http://www.Inprise.com/IPL.html
 
10
 *
 
11
 * Software distributed under the License is distributed on an
 
12
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 
13
 * or implied. See the License for the specific language governing
 
14
 * rights and limitations under the License.
 
15
 *
 
16
 * The Original Code was created by Inprise Corporation
 
17
 * and its predecessors. Portions created by Inprise Corporation are
 
18
 * Copyright (C) Inprise Corporation.
 
19
 *
 
20
 * All Rights Reserved.
 
21
 * Contributor(s): ______________________________________.
 
22
 *
 
23
 * 2002.02.15 Sean Leyne - Code Cleanup, removed obsolete "DELTA" port
 
24
 * 2002.02.15 Sean Leyne - Code Cleanup, removed obsolete "IMP" port
 
25
 *
 
26
 * 2002.10.30 Sean Leyne - Removed support for obsolete "PC_PLATFORM" define
 
27
 *
 
28
 */
 
29
 
 
30
#include "firebird.h"
 
31
#include <stdio.h>
 
32
#include <limits.h>
 
33
#include "../common/classes/timestamp.h"
 
34
#include "../jrd/common.h"
 
35
#include "../jrd/ibase.h"
 
36
#include "../jrd/perf.h"
 
37
#include "../jrd/gds_proto.h"
 
38
#include "../jrd/perf_proto.h"
 
39
#include "../jrd/gdsassert.h"
 
40
 
 
41
#ifdef HAVE_SYS_TIMES_H
 
42
#include <sys/times.h>
 
43
#endif
 
44
#ifdef HAVE_SYS_TIMEB_H
 
45
# include <sys/timeb.h>
 
46
#endif
 
47
 
 
48
 
 
49
static SLONG get_parameter(const SCHAR**);
 
50
#ifndef HAVE_TIMES
 
51
static void times(struct tms*);
 
52
#endif
 
53
 
 
54
static const SCHAR items[] = {
 
55
        isc_info_reads,
 
56
        isc_info_writes,
 
57
        isc_info_fetches,
 
58
        isc_info_marks,
 
59
        isc_info_page_size, isc_info_num_buffers,
 
60
        isc_info_current_memory, isc_info_max_memory
 
61
};
 
62
 
 
63
static const SCHAR* report =
 
64
        "elapsed = !e cpu = !u reads = !r writes = !w fetches = !f marks = !m$";
 
65
 
 
66
#ifdef VMS
 
67
#define TICK    100
 
68
extern void ftime();
 
69
#endif
 
70
 
 
71
#if defined(WIN_NT) && !defined(CLOCKS_PER_SEC)
 
72
#define TICK    100
 
73
#endif
 
74
 
 
75
/* EKU: TICK (sys/param.h) and CLOCKS_PER_SEC (time.h) may both be defined */
 
76
#if !defined(TICK) && defined(CLOCKS_PER_SEC)
 
77
#define TICK ((SLONG)CLOCKS_PER_SEC)
 
78
#endif
 
79
 
 
80
#ifndef TICK
 
81
#define TICK    ((SLONG)CLK_TCK)
 
82
#endif
 
83
 
 
84
 
 
85
int API_ROUTINE perf_format(
 
86
                                                const PERF* before,
 
87
                                                const PERF* after,
 
88
                                                const SCHAR* string, SCHAR* buffer, SSHORT* buf_len)
 
89
{
 
90
/**************************************
 
91
 *
 
92
 *      P E R F _ f o r m a t
 
93
 *
 
94
 **************************************
 
95
 *
 
96
 * Functional description
 
97
 *      Format a buffer with statistical stuff under control of formatting
 
98
 *      string.  Substitute in appropriate stuff.  Return the length of the
 
99
 *      formatting output.
 
100
 *
 
101
 **************************************/
 
102
        SCHAR c;
 
103
 
 
104
        SLONG buffer_length = (buf_len) ? *buf_len : 0;
 
105
        SCHAR* p = buffer;
 
106
 
 
107
        while ((c = *string++) && c != '$') {
 
108
                if (c != '!')
 
109
                        *p++ = c;
 
110
                else {
 
111
                        SLONG delta;
 
112
                        switch (c = *string++) {
 
113
                        case 'r':
 
114
                                delta = after->perf_reads - before->perf_reads;
 
115
                                break;
 
116
                        case 'w':
 
117
                                delta = after->perf_writes - before->perf_writes;
 
118
                                break;
 
119
                        case 'f':
 
120
                                delta = after->perf_fetches - before->perf_fetches;
 
121
                                break;
 
122
                        case 'm':
 
123
                                delta = after->perf_marks - before->perf_marks;
 
124
                                break;
 
125
                        case 'd':
 
126
                                delta =
 
127
                                        after->perf_current_memory - before->perf_current_memory;
 
128
                                break;
 
129
                        case 'p':
 
130
                                delta = after->perf_page_size;
 
131
                                break;
 
132
                        case 'b':
 
133
                                delta = after->perf_buffers;
 
134
                                break;
 
135
                        case 'c':
 
136
                                delta = after->perf_current_memory;
 
137
                                break;
 
138
                        case 'x':
 
139
                                delta = after->perf_max_memory;
 
140
                                break;
 
141
                        case 'e':
 
142
                                delta = after->perf_elapsed - before->perf_elapsed;
 
143
                                break;
 
144
                        case 'u':
 
145
                                delta = after->perf_times.tms_utime -
 
146
                                        before->perf_times.tms_utime;
 
147
                                break;
 
148
                        case 's':
 
149
                                delta = after->perf_times.tms_stime -
 
150
                                        before->perf_times.tms_stime;
 
151
                                break;
 
152
                        default:
 
153
                                sprintf(p, "?%c?", c);
 
154
                                while (*p)
 
155
                                        p++;
 
156
                        }
 
157
 
 
158
                        switch (c) {
 
159
                        case 'r':
 
160
                        case 'w':
 
161
                        case 'f':
 
162
                        case 'm':
 
163
                        case 'd':
 
164
                        case 'p':
 
165
                        case 'b':
 
166
                        case 'c':
 
167
                        case 'x':
 
168
                                sprintf(p, "%"SLONGFORMAT, delta);
 
169
                                while (*p)
 
170
                                        p++;
 
171
                                break;
 
172
 
 
173
                        case 'u':
 
174
                        case 's':
 
175
#ifdef VMS
 
176
                                sprintf(p, "%"SLONGFORMAT".%.2"SLONGFORMAT, delta / 100, (delta % 100));
 
177
#else
 
178
                                sprintf(p, "%"SLONGFORMAT".%.2"SLONGFORMAT, delta / TICK,
 
179
                                                (delta % TICK) * 100 / TICK);
 
180
#endif
 
181
                                while (*p)
 
182
                                        p++;
 
183
                                break;
 
184
 
 
185
                        case 'e':
 
186
                                sprintf(p, "%"SLONGFORMAT".%.2"SLONGFORMAT, delta / 100, delta % 100);
 
187
                                while (*p)
 
188
                                        p++;
 
189
                                break;
 
190
                        }
 
191
                }
 
192
        }
 
193
 
 
194
        *p = 0;
 
195
        const int length = p - buffer;
 
196
        if (buffer_length && (buffer_length -= length) >= 0) {
 
197
                memset(p, ' ', buffer_length);
 
198
        }
 
199
 
 
200
        return length;
 
201
}
 
202
 
 
203
 
 
204
void API_ROUTINE perf_get_info(FB_API_HANDLE* handle, PERF* perf)
 
205
{
 
206
/**************************************
 
207
 *
 
208
 *      P E R F _ g e t _ i n f o
 
209
 *
 
210
 **************************************
 
211
 *
 
212
 * Functional description
 
213
 *      Acquire timing and performance information.  Some info comes
 
214
 *      from the system and some from the database.
 
215
 *
 
216
 **************************************/
 
217
        SSHORT buffer_length, item_length;
 
218
        ISC_STATUS_ARRAY jrd_status;
 
219
#ifdef HAVE_GETTIMEOFDAY
 
220
        struct timeval tp;
 
221
#else
 
222
        struct timeb time_buffer;
 
223
#define LARGE_NUMBER 696600000  /* to avoid overflow, get rid of decades) */
 
224
#endif
 
225
 
 
226
/* If there isn't a database, zero everything out */
 
227
 
 
228
        if (!*handle) {
 
229
                memset(perf, 0, sizeof(PERF));
 
230
        }
 
231
 
 
232
/* Get system times */
 
233
 
 
234
        times(&perf->perf_times);
 
235
 
 
236
#ifdef HAVE_GETTIMEOFDAY
 
237
        GETTIMEOFDAY(&tp);
 
238
        perf->perf_elapsed = tp.tv_sec * 100 + tp.tv_usec / 10000;
 
239
#else
 
240
        ftime(&time_buffer);
 
241
        perf->perf_elapsed =
 
242
                (time_buffer.time - LARGE_NUMBER) * 100 + (time_buffer.millitm / 10);
 
243
#endif
 
244
 
 
245
        if (!*handle)
 
246
                return;
 
247
 
 
248
        SCHAR buffer[256];
 
249
        buffer_length = sizeof(buffer);
 
250
        item_length = sizeof(items);
 
251
        isc_database_info(jrd_status,
 
252
                                          handle,
 
253
                                          item_length, items, buffer_length, buffer);
 
254
 
 
255
        const char* p = buffer;
 
256
 
 
257
        while (true)
 
258
                switch (*p++) {
 
259
                case isc_info_reads:
 
260
                        perf->perf_reads = get_parameter(&p);
 
261
                        break;
 
262
 
 
263
                case isc_info_writes:
 
264
                        perf->perf_writes = get_parameter(&p);
 
265
                        break;
 
266
 
 
267
                case isc_info_marks:
 
268
                        perf->perf_marks = get_parameter(&p);
 
269
                        break;
 
270
 
 
271
                case isc_info_fetches:
 
272
                        perf->perf_fetches = get_parameter(&p);
 
273
                        break;
 
274
 
 
275
                case isc_info_num_buffers:
 
276
                        perf->perf_buffers = get_parameter(&p);
 
277
                        break;
 
278
 
 
279
                case isc_info_page_size:
 
280
                        perf->perf_page_size = get_parameter(&p);
 
281
                        break;
 
282
 
 
283
                case isc_info_current_memory:
 
284
                        perf->perf_current_memory = get_parameter(&p);
 
285
                        break;
 
286
 
 
287
                case isc_info_max_memory:
 
288
                        perf->perf_max_memory = get_parameter(&p);
 
289
                        break;
 
290
 
 
291
                case isc_info_end:
 
292
                        return;
 
293
 
 
294
                case isc_info_error:
 
295
                        if (p[2] == isc_info_marks)
 
296
                                perf->perf_marks = 0;
 
297
                        else if (p[2] == isc_info_current_memory)
 
298
                                perf->perf_current_memory = 0;
 
299
                        else if (p[2] == isc_info_max_memory)
 
300
                                perf->perf_max_memory = 0;
 
301
                        {
 
302
                                const SLONG temp = isc_vax_integer(p, 2);
 
303
                                fb_assert(temp <= MAX_SSHORT);
 
304
                                p += temp + 2;
 
305
                        }
 
306
                        perf->perf_marks = 0;
 
307
                        break;
 
308
 
 
309
                default:
 
310
                        return;
 
311
                }
 
312
}
 
313
 
 
314
 
 
315
void API_ROUTINE perf_report(
 
316
                                                         const PERF* before,
 
317
                                                         const PERF* after, SCHAR* buffer, SSHORT* buf_len)
 
318
{
 
319
/**************************************
 
320
 *
 
321
 *      p e r f _ r e p o r t
 
322
 *
 
323
 **************************************
 
324
 *
 
325
 * Functional description
 
326
 *      Report a common set of parameters.
 
327
 *
 
328
 **************************************/
 
329
 
 
330
        perf_format(before, after, report, buffer, buf_len);
 
331
}
 
332
 
 
333
 
 
334
static SLONG get_parameter(const SCHAR** ptr)
 
335
{
 
336
/**************************************
 
337
 *
 
338
 *      g e t _ p a r a m e t e r
 
339
 *
 
340
 **************************************
 
341
 *
 
342
 * Functional description
 
343
 *      Get a parameter (length is encoded), convert to internal form,
 
344
 *      and return.
 
345
 *
 
346
 **************************************/
 
347
        SSHORT l = *(*ptr)++;
 
348
        l += (*(*ptr)++) << 8;
 
349
        const SLONG parameter = isc_vax_integer(*ptr, l);
 
350
        *ptr += l;
 
351
 
 
352
        return parameter;
 
353
}
 
354
 
 
355
 
 
356
#ifndef HAVE_TIMES
 
357
static void times(struct tms* buffer)
 
358
{
 
359
/**************************************
 
360
 *
 
361
 *      t i m e s
 
362
 *
 
363
 **************************************
 
364
 *
 
365
 * Functional description
 
366
 *      Emulate the good old unix call "times".  Only both with user time.
 
367
 *
 
368
 **************************************/
 
369
 
 
370
        buffer->tms_utime = clock();
 
371
}
 
372
#endif
 
373
 
 
374