~drizzle-trunk/drizzle/development

1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
1
/* Copyright (C) 2005 PrimeBase Technologies GmbH
1455.3.1 by Vladimir Kolesnikov
lp:drizzle + pbxt 1.1 + test results
2
 *
3
 * PrimeBase XT
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1455.3.1 by Vladimir Kolesnikov
lp:drizzle + pbxt 1.1 + test results
18
 *
19
 * 2005-02-07	Paul McCullagh
20
 *
21
 * H&G2JCtL
22
 */
23
24
#include "xt_config.h"
25
26
#include <stdio.h>
27
#include <stdarg.h>
28
#include <errno.h>
29
#include <stdlib.h>
30
#include <time.h>
31
32
#include "trace_xt.h"
33
#include "pthread_xt.h"
34
#include "thread_xt.h"
35
36
#ifdef DEBUG
37
//#define PRINT_TRACE
38
//#define RESET_AFTER_DUMP
39
//#define DUMP_TO_STDOUT
40
#endif
41
42
static xtBool			trace_initialized = FALSE;
43
static xt_mutex_type	trace_mutex;
44
static size_t			trace_log_size;
45
static size_t			trace_log_offset;
46
static size_t			trace_log_end;
47
static char				*trace_log_buffer;
48
static u_long			trace_stat_count;
49
static FILE				*trace_dump_file;
50
static xtBool			trace_flush_dump = FALSE;
51
52
#define DEFAULT_TRACE_LOG_SIZE		(40*1024*1204)
53
#define MAX_PRINT_LEN				2000
54
55
xtPublic xtBool xt_init_trace(void)
56
{
57
	int err;
58
59
	err = xt_p_mutex_init_with_autoname(&trace_mutex, NULL);
60
	if (err) {
61
		xt_log_errno(XT_NS_CONTEXT, err);
62
		trace_initialized = FALSE;
63
		return FALSE;
64
	}
65
	trace_initialized = TRUE;
66
	trace_log_buffer = (char *) malloc(DEFAULT_TRACE_LOG_SIZE+1);
67
	if (!trace_log_buffer) {
68
		xt_log_errno(XT_NS_CONTEXT, ENOMEM);
69
		xt_exit_trace();
70
		return FALSE;
71
	}
72
	trace_log_size = DEFAULT_TRACE_LOG_SIZE;
73
	trace_log_offset = 0;
74
	trace_log_end = 0;
75
	trace_stat_count = 0;
76
77
#ifdef XT_TRACK_CONNECTIONS
78
	for (int i=0; i<XT_TRACK_MAX_CONNS; i++)
79
		xt_track_conn_info[i].cu_t_id = i;
80
#endif
81
82
	return TRUE;
83
}
84
85
xtPublic void xt_exit_trace(void)
86
{
87
	if (trace_initialized) {
88
#ifdef DEBUG
89
		xt_dump_trace();
90
#endif
91
		xt_free_mutex(&trace_mutex);
92
		trace_initialized = FALSE;
93
		if (trace_log_buffer)
94
			free(trace_log_buffer);
95
		trace_log_buffer = NULL;
96
		trace_log_size = 0;
97
		trace_log_offset = 0;
98
		trace_log_end = 0;
99
		trace_stat_count = 0;
100
	}
101
	if (trace_dump_file) {
102
		fclose(trace_dump_file);
103
		trace_dump_file = NULL;
104
	}
105
}
106
107
xtPublic void xt_print_trace(void)
108
{
109
	if (trace_log_offset) {
110
		xt_lock_mutex_ns(&trace_mutex);
111
		if (trace_log_end > trace_log_offset+1) {
112
			trace_log_buffer[trace_log_end] = 0;
113
			printf("%s", trace_log_buffer + trace_log_offset + 1);
114
		}
115
		trace_log_buffer[trace_log_offset] = 0;
116
		printf("%s", trace_log_buffer);
117
		trace_log_offset = 0;
118
		trace_log_end = 0;
119
		xt_unlock_mutex_ns(&trace_mutex);
120
	}
121
}
122
123
xtPublic void xt_dump_trace(void)
124
{
125
	if (trace_log_offset) {
126
#ifdef DUMP_TO_STDOUT
127
		if (trace_log_end > trace_log_offset+1) {
128
			trace_log_buffer[trace_log_end] = 0;
129
			printf("%s", trace_log_buffer + trace_log_offset + 1);
130
		}
131
		trace_log_buffer[trace_log_offset] = 0;
132
		printf("%s", trace_log_buffer);
133
		printf("\n");
134
#else
135
		FILE *fp;
136
137
		fp = fopen("pbxt.log", "w");
138
139
		xt_lock_mutex_ns(&trace_mutex);
140
		if (fp) {
141
			if (trace_log_end > trace_log_offset+1) {
142
				trace_log_buffer[trace_log_end] = 0;
143
				fprintf(fp, "%s", trace_log_buffer + trace_log_offset + 1);
144
			}
145
			trace_log_buffer[trace_log_offset] = 0;
146
			fprintf(fp, "%s", trace_log_buffer);
147
			fclose(fp);
148
		}
149
#endif
150
151
#ifdef RESET_AFTER_DUMP
152
		trace_log_offset = 0;
153
		trace_log_end = 0;
154
		trace_stat_count = 0;
155
#endif
156
		xt_unlock_mutex_ns(&trace_mutex);
157
	}
158
159
	if (trace_dump_file) {
160
		xt_lock_mutex_ns(&trace_mutex);
161
		if (trace_dump_file) {
162
			fflush(trace_dump_file);
163
			fclose(trace_dump_file);
164
			trace_dump_file = NULL;
165
		}
166
		xt_unlock_mutex_ns(&trace_mutex);
167
	}
168
}
169
170
xtPublic void xt_trace(const char *fmt, ...)
171
{
172
	va_list	ap;
173
	size_t	len;
174
175
	va_start(ap, fmt);
176
	xt_lock_mutex_ns(&trace_mutex);
177
178
	if (trace_log_offset + MAX_PRINT_LEN > trace_log_size) {
179
		/* Start at the beginning of the buffer again: */
180
		trace_log_end = trace_log_offset;
181
		trace_log_offset = 0;
182
	}
183
184
	len = (size_t) vsnprintf(trace_log_buffer + trace_log_offset, trace_log_size - trace_log_offset, fmt, ap);
185
	trace_log_offset += len;
186
187
	xt_unlock_mutex_ns(&trace_mutex);
188
	va_end(ap);
189
190
#ifdef PRINT_TRACE
191
	xt_print_trace();
192
#endif
193
}
194
195
xtPublic void xt_ttracef(XTThreadPtr self, char *fmt, ...)
196
{
197
	va_list	ap;
198
	size_t	len;
199
200
	va_start(ap, fmt);
201
	xt_lock_mutex_ns(&trace_mutex);
202
203
	if (trace_log_offset + MAX_PRINT_LEN > trace_log_size) {
204
		trace_log_end = trace_log_offset;
205
		trace_log_offset = 0;
206
	}
207
208
	trace_stat_count++;
209
	len = (size_t) sprintf(trace_log_buffer + trace_log_offset, "%lu %s: ", trace_stat_count, self->t_name);
210
	trace_log_offset += len;
211
	len = (size_t) vsnprintf(trace_log_buffer + trace_log_offset, trace_log_size - trace_log_offset, fmt, ap);
212
	trace_log_offset += len;
213
214
	xt_unlock_mutex_ns(&trace_mutex);
215
	va_end(ap);
216
217
#ifdef PRINT_TRACE
218
	xt_print_trace();
219
#endif
220
}
221
222
xtPublic void xt_ttraceq(XTThreadPtr self, char *query)
223
{
224
	size_t	qlen = strlen(query), tlen;
225
	char	*ptr, *qptr;
226
227
	if (!self)
228
		self = xt_get_self();
229
230
	xt_lock_mutex_ns(&trace_mutex);
231
232
	if (trace_log_offset + qlen + 100 >= trace_log_size) {
233
		/* Start at the beginning of the buffer again: */
234
		trace_log_end = trace_log_offset;
235
		trace_log_offset = 0;
236
	}
237
238
	trace_stat_count++;
239
	tlen = (size_t) sprintf(trace_log_buffer + trace_log_offset, "%lu %s: ", trace_stat_count, self->t_name);
240
	trace_log_offset += tlen;
241
242
	ptr = trace_log_buffer + trace_log_offset;
243
	qlen = 0;
244
	qptr = query;
245
	while (*qptr) {
246
		if (*qptr == '\n' || *qptr == '\r')
247
			*ptr = ' ';
248
		else
249
			*ptr = *qptr;
250
		if (*qptr == '\n' || *qptr == '\r' || *qptr == ' ') {
251
			qptr++;
252
			while (*qptr == '\n' || *qptr == '\r' || *qptr == ' ')
253
				qptr++;				
254
		}
255
		else
256
			qptr++;
257
		ptr++;
258
		qlen++;
259
	}
260
261
	trace_log_offset += qlen;
262
	*(trace_log_buffer + trace_log_offset) = '\n';
263
	*(trace_log_buffer + trace_log_offset + 1) = '\0';
264
	trace_log_offset++;
265
	
266
	xt_unlock_mutex_ns(&trace_mutex);
267
268
#ifdef PRINT_TRACE
269
	xt_print_trace();
270
#endif
271
}
272
273
/*
274
 * Returns the time in microseconds.
275
 * (1/1000000 of a second)
276
 */
277
xtPublic xtWord8 xt_trace_clock(void)
278
{
279
	static xtWord8	trace_start_clock = 0;
280
	xtWord8			now;
281
282
#ifdef XT_WIN
283
	now = ((xtWord8) GetTickCount()) * (xtWord8) 1000;
284
#else
285
	struct timeval	tv;
286
287
	gettimeofday(&tv, NULL);
288
	now = (xtWord8) tv.tv_sec * (xtWord8) 1000000 + tv.tv_usec;
289
#endif
290
	if (trace_start_clock)
291
		return now - trace_start_clock;
292
	trace_start_clock = now;
293
	return 0;
294
}
295
296
xtPublic char *xt_trace_clock_str(char *ptr)
297
{
298
	static char	buffer[50];
299
	xtWord8		now = xt_trace_clock();
300
301
	if (!ptr)
302
		ptr = buffer;
303
304
	sprintf(ptr, "%d.%06d", (int) (now / (xtWord8) 1000000), (int) (now % (xtWord8) 1000000));
305
	return ptr;
306
}
307
308
xtPublic char *xt_trace_clock_diff(char *ptr)
309
{
310
	static xtWord8	trace_last_clock = 0;
311
	static char		buffer[50];
312
	xtWord8			now = xt_trace_clock();
313
314
	if (!ptr)
315
		ptr = buffer;
316
317
	sprintf(ptr, "%d.%06d (%d)", (int) (now / (xtWord8) 1000000), (int) (now % (xtWord8) 1000000), (int) (now - trace_last_clock));
318
	trace_last_clock = now;
319
	return ptr;
320
}
321
322
xtPublic char *xt_trace_clock_diff(char *ptr, xtWord8 start_time)
323
{
324
	xtWord8 now = xt_trace_clock();
325
326
	sprintf(ptr, "%d.%06d (%d)", (int) (now / (xtWord8) 1000000), (int) (now % (xtWord8) 1000000), (int) (now - start_time));
327
	return ptr;
328
}
329
330
331
xtPublic void xt_set_fflush(xtBool on)
332
{
333
	trace_flush_dump = on;
334
}
335
336
xtPublic void xt_ftracef(char *fmt, ...)
337
{
338
	va_list	ap;
339
340
	va_start(ap, fmt);
341
	xt_lock_mutex_ns(&trace_mutex);
342
343
	if (!trace_dump_file) {
344
		char buffer[100];
345
346
		for (int i=1; ;i++) {
347
			sprintf(buffer, "pbxt-dump-%d.log", i);
348
			if (!xt_fs_exists(buffer)) {
349
				trace_dump_file = fopen(buffer, "w");
350
				break;
351
			}
352
		}
353
	}
354
355
	vfprintf(trace_dump_file, fmt, ap);
356
	if (trace_flush_dump)
357
		fflush(trace_dump_file);
358
359
	xt_unlock_mutex_ns(&trace_mutex);
360
	va_end(ap);
361
}
362
363
/*
364
 * -----------------------------------------------------------------------
365
 * CONNECTION TRACKING
366
 */
367
368
#ifdef XT_TRACK_CONNECTIONS
369
XTConnInfoRec	xt_track_conn_info[XT_TRACK_MAX_CONNS];
370
371
static int trace_comp_conn_info(const void *a, const void *b)
372
{
373
	XTConnInfoPtr	ci_a = (XTConnInfoPtr) a, ci_b = (XTConnInfoPtr) b;
374
375
	if (ci_a->ci_curr_xact_id > ci_b->ci_curr_xact_id)
376
		return 1;
377
	if (ci_a->ci_curr_xact_id < ci_b->ci_curr_xact_id)
378
		return -1;
379
	return 0;
380
}
381
382
xtPublic void xt_dump_conn_tracking(void)
383
{
384
	XTConnInfoRec	conn_info[XT_TRACK_MAX_CONNS];
385
	XTConnInfoPtr	ptr;
386
387
	memcpy(conn_info, xt_track_conn_info, sizeof(xt_track_conn_info));
388
	qsort(conn_info, XT_TRACK_MAX_CONNS, sizeof(XTConnInfoRec), trace_comp_conn_info);
389
390
	ptr = conn_info;
391
	for (int i=0; i<XT_TRACK_MAX_CONNS; i++) {
392
		if (ptr->ci_curr_xact_id || ptr->ci_prev_xact_id) {
393
			printf("%3d curr=%d prev=%d prev-time=%ld\n", (int) ptr->cu_t_id, (int) ptr->ci_curr_xact_id, (int) ptr->ci_prev_xact_id, (long) ptr->ci_prev_xact_time);
394
			if (i+1<XT_TRACK_MAX_CONNS) {
395
				printf("    diff=%d\n", (int) (ptr+1)->ci_curr_xact_id - (int) ptr->ci_curr_xact_id);
396
			}
397
		}
398
		ptr++;
399
	}
400
}
401
402
#endif
403
404