git

Форк
0
/
tr2_tgt_perf.c 
631 строка · 17.8 Кб
1
#include "git-compat-util.h"
2
#include "config.h"
3
#include "repository.h"
4
#include "run-command.h"
5
#include "quote.h"
6
#include "version.h"
7
#include "json-writer.h"
8
#include "trace2/tr2_dst.h"
9
#include "trace2/tr2_sid.h"
10
#include "trace2/tr2_sysenv.h"
11
#include "trace2/tr2_tbuf.h"
12
#include "trace2/tr2_tgt.h"
13
#include "trace2/tr2_tls.h"
14
#include "trace2/tr2_tmr.h"
15

16
static struct tr2_dst tr2dst_perf = {
17
	.sysenv_var = TR2_SYSENV_PERF,
18
};
19

20
/*
21
 * Use TR2_SYSENV_PERF_BRIEF to omit the "<time> <file>:<line>"
22
 * fields from each line written to the builtin performance target.
23
 *
24
 * Unit tests may want to use this to help with testing.
25
 */
26
static int tr2env_perf_be_brief;
27

28
#define TR2FMT_PERF_FL_WIDTH (28)
29
#define TR2FMT_PERF_MAX_EVENT_NAME (12)
30
#define TR2FMT_PERF_REPO_WIDTH (3)
31
#define TR2FMT_PERF_CATEGORY_WIDTH (12)
32

33
#define TR2_INDENT (2)
34
#define TR2_INDENT_LENGTH(ctx) (((ctx)->nr_open_regions - 1) * TR2_INDENT)
35

36
static int fn_init(void)
37
{
38
	int want = tr2_dst_trace_want(&tr2dst_perf);
39
	int want_brief;
40
	const char *brief;
41

42
	if (!want)
43
		return want;
44

45
	brief = tr2_sysenv_get(TR2_SYSENV_PERF_BRIEF);
46
	if (brief && *brief &&
47
	    ((want_brief = git_parse_maybe_bool(brief)) != -1))
48
		tr2env_perf_be_brief = want_brief;
49

50
	return want;
51
}
52

53
static void fn_term(void)
54
{
55
	tr2_dst_trace_disable(&tr2dst_perf);
56
}
57

58
/*
59
 * Format trace line prefix in human-readable classic format for
60
 * the performance target:
61
 *     "[<time> [<file>:<line>] <bar>] <nr_parents> <bar>
62
 *         <thread_name> <bar> <event_name> <bar> [<repo>] <bar>
63
 *         [<elapsed_absolute>] [<elapsed_relative>] <bar>
64
 *         [<category>] <bar> [<dots>] "
65
 */
66
static void perf_fmt_prepare(const char *event_name,
67
			     struct tr2tls_thread_ctx *ctx, const char *file,
68
			     int line, const struct repository *repo,
69
			     uint64_t *p_us_elapsed_absolute,
70
			     uint64_t *p_us_elapsed_relative,
71
			     const char *category, struct strbuf *buf)
72
{
73
	int len;
74

75
	strbuf_setlen(buf, 0);
76

77
	if (!tr2env_perf_be_brief) {
78
		struct tr2_tbuf tb_now;
79
		size_t fl_end_col;
80

81
		tr2_tbuf_local_time(&tb_now);
82
		strbuf_addstr(buf, tb_now.buf);
83
		strbuf_addch(buf, ' ');
84

85
		fl_end_col = buf->len + TR2FMT_PERF_FL_WIDTH;
86

87
		if (file && *file) {
88
			struct strbuf buf_fl = STRBUF_INIT;
89

90
			strbuf_addf(&buf_fl, "%s:%d", file, line);
91

92
			if (buf_fl.len <= TR2FMT_PERF_FL_WIDTH)
93
				strbuf_addbuf(buf, &buf_fl);
94
			else {
95
				size_t avail = TR2FMT_PERF_FL_WIDTH - 3;
96
				strbuf_addstr(buf, "...");
97
				strbuf_add(buf,
98
					   &buf_fl.buf[buf_fl.len - avail],
99
					   avail);
100
			}
101

102
			strbuf_release(&buf_fl);
103
		}
104

105
		while (buf->len < fl_end_col)
106
			strbuf_addch(buf, ' ');
107

108
		strbuf_addstr(buf, " | ");
109
	}
110

111
	strbuf_addf(buf, "d%d | ", tr2_sid_depth());
112
	strbuf_addf(buf, "%-*s | %-*s | ", TR2_MAX_THREAD_NAME,
113
		    ctx->thread_name, TR2FMT_PERF_MAX_EVENT_NAME,
114
		    event_name);
115

116
	len = buf->len + TR2FMT_PERF_REPO_WIDTH;
117
	if (repo)
118
		strbuf_addf(buf, "r%d ", repo->trace2_repo_id);
119
	while (buf->len < len)
120
		strbuf_addch(buf, ' ');
121
	strbuf_addstr(buf, " | ");
122

123
	if (p_us_elapsed_absolute)
124
		strbuf_addf(buf, "%9.6f | ",
125
			    ((double)(*p_us_elapsed_absolute)) / 1000000.0);
126
	else
127
		strbuf_addf(buf, "%9s | ", " ");
128

129
	if (p_us_elapsed_relative)
130
		strbuf_addf(buf, "%9.6f | ",
131
			    ((double)(*p_us_elapsed_relative)) / 1000000.0);
132
	else
133
		strbuf_addf(buf, "%9s | ", " ");
134

135
	strbuf_addf(buf, "%-*.*s | ", TR2FMT_PERF_CATEGORY_WIDTH,
136
		    TR2FMT_PERF_CATEGORY_WIDTH, (category ? category : ""));
137

138
	if (ctx->nr_open_regions > 0)
139
		strbuf_addchars(buf, '.', TR2_INDENT_LENGTH(ctx));
140
}
141

142
static void perf_io_write_fl(const char *file, int line, const char *event_name,
143
			     const struct repository *repo,
144
			     uint64_t *p_us_elapsed_absolute,
145
			     uint64_t *p_us_elapsed_relative,
146
			     const char *category,
147
			     const struct strbuf *buf_payload)
148
{
149
	struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
150
	struct strbuf buf_line = STRBUF_INIT;
151

152
	perf_fmt_prepare(event_name, ctx, file, line, repo,
153
			 p_us_elapsed_absolute, p_us_elapsed_relative, category,
154
			 &buf_line);
155
	strbuf_addbuf(&buf_line, buf_payload);
156
	tr2_dst_write_line(&tr2dst_perf, &buf_line);
157
	strbuf_release(&buf_line);
158
}
159

160
static void fn_version_fl(const char *file, int line)
161
{
162
	const char *event_name = "version";
163
	struct strbuf buf_payload = STRBUF_INIT;
164

165
	strbuf_addstr(&buf_payload, git_version_string);
166

167
	perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
168
			 &buf_payload);
169
	strbuf_release(&buf_payload);
170
}
171

172
static void fn_start_fl(const char *file, int line,
173
			uint64_t us_elapsed_absolute, const char **argv)
174
{
175
	const char *event_name = "start";
176
	struct strbuf buf_payload = STRBUF_INIT;
177

178
	sq_append_quote_argv_pretty(&buf_payload, argv);
179

180
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
181
			 NULL, NULL, &buf_payload);
182
	strbuf_release(&buf_payload);
183
}
184

185
static void fn_exit_fl(const char *file, int line, uint64_t us_elapsed_absolute,
186
		       int code)
187
{
188
	const char *event_name = "exit";
189
	struct strbuf buf_payload = STRBUF_INIT;
190

191
	strbuf_addf(&buf_payload, "code:%d", code);
192

193
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
194
			 NULL, NULL, &buf_payload);
195
	strbuf_release(&buf_payload);
196
}
197

198
static void fn_signal(uint64_t us_elapsed_absolute, int signo)
199
{
200
	const char *event_name = "signal";
201
	struct strbuf buf_payload = STRBUF_INIT;
202

203
	strbuf_addf(&buf_payload, "signo:%d", signo);
204

205
	perf_io_write_fl(__FILE__, __LINE__, event_name, NULL,
206
			 &us_elapsed_absolute, NULL, NULL, &buf_payload);
207
	strbuf_release(&buf_payload);
208
}
209

210
static void fn_atexit(uint64_t us_elapsed_absolute, int code)
211
{
212
	const char *event_name = "atexit";
213
	struct strbuf buf_payload = STRBUF_INIT;
214

215
	strbuf_addf(&buf_payload, "code:%d", code);
216

217
	perf_io_write_fl(__FILE__, __LINE__, event_name, NULL,
218
			 &us_elapsed_absolute, NULL, NULL, &buf_payload);
219
	strbuf_release(&buf_payload);
220
}
221

222
static void maybe_append_string_va(struct strbuf *buf, const char *fmt,
223
				   va_list ap)
224
{
225
	if (fmt && *fmt) {
226
		va_list copy_ap;
227

228
		va_copy(copy_ap, ap);
229
		strbuf_vaddf(buf, fmt, copy_ap);
230
		va_end(copy_ap);
231
		return;
232
	}
233
}
234

235
static void fn_error_va_fl(const char *file, int line, const char *fmt,
236
			   va_list ap)
237
{
238
	const char *event_name = "error";
239
	struct strbuf buf_payload = STRBUF_INIT;
240

241
	maybe_append_string_va(&buf_payload, fmt, ap);
242

243
	perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
244
			 &buf_payload);
245
	strbuf_release(&buf_payload);
246
}
247

248
static void fn_command_path_fl(const char *file, int line, const char *pathname)
249
{
250
	const char *event_name = "cmd_path";
251
	struct strbuf buf_payload = STRBUF_INIT;
252

253
	strbuf_addstr(&buf_payload, pathname);
254

255
	perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
256
			 &buf_payload);
257
	strbuf_release(&buf_payload);
258
}
259

260
static void fn_command_ancestry_fl(const char *file, int line, const char **parent_names)
261
{
262
	const char *event_name = "cmd_ancestry";
263
	struct strbuf buf_payload = STRBUF_INIT;
264

265
	strbuf_addstr(&buf_payload, "ancestry:[");
266
	/* It's not an argv but the rules are basically the same. */
267
	sq_append_quote_argv_pretty(&buf_payload, parent_names);
268
	strbuf_addch(&buf_payload, ']');
269

270
	perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
271
			 &buf_payload);
272
	strbuf_release(&buf_payload);
273
}
274

275
static void fn_command_name_fl(const char *file, int line, const char *name,
276
			       const char *hierarchy)
277
{
278
	const char *event_name = "cmd_name";
279
	struct strbuf buf_payload = STRBUF_INIT;
280

281
	strbuf_addstr(&buf_payload, name);
282
	if (hierarchy && *hierarchy)
283
		strbuf_addf(&buf_payload, " (%s)", hierarchy);
284

285
	perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
286
			 &buf_payload);
287
	strbuf_release(&buf_payload);
288
}
289

290
static void fn_command_mode_fl(const char *file, int line, const char *mode)
291
{
292
	const char *event_name = "cmd_mode";
293
	struct strbuf buf_payload = STRBUF_INIT;
294

295
	strbuf_addstr(&buf_payload, mode);
296

297
	perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
298
			 &buf_payload);
299
	strbuf_release(&buf_payload);
300
}
301

302
static void fn_alias_fl(const char *file, int line, const char *alias,
303
			const char **argv)
304
{
305
	const char *event_name = "alias";
306
	struct strbuf buf_payload = STRBUF_INIT;
307

308
	strbuf_addf(&buf_payload, "alias:%s argv:[", alias);
309
	sq_append_quote_argv_pretty(&buf_payload, argv);
310
	strbuf_addch(&buf_payload, ']');
311

312
	perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL,
313
			 &buf_payload);
314
	strbuf_release(&buf_payload);
315
}
316

317
static void fn_child_start_fl(const char *file, int line,
318
			      uint64_t us_elapsed_absolute,
319
			      const struct child_process *cmd)
320
{
321
	const char *event_name = "child_start";
322
	struct strbuf buf_payload = STRBUF_INIT;
323

324
	if (cmd->trace2_hook_name) {
325
		strbuf_addf(&buf_payload, "[ch%d] class:hook hook:%s",
326
			    cmd->trace2_child_id, cmd->trace2_hook_name);
327
	} else {
328
		const char *child_class =
329
			cmd->trace2_child_class ? cmd->trace2_child_class : "?";
330
		strbuf_addf(&buf_payload, "[ch%d] class:%s",
331
			    cmd->trace2_child_id, child_class);
332
	}
333

334
	if (cmd->dir) {
335
		strbuf_addstr(&buf_payload, " cd:");
336
		sq_quote_buf_pretty(&buf_payload, cmd->dir);
337
	}
338

339
	strbuf_addstr(&buf_payload, " argv:[");
340
	if (cmd->git_cmd) {
341
		strbuf_addstr(&buf_payload, "git");
342
		if (cmd->args.nr)
343
			strbuf_addch(&buf_payload, ' ');
344
	}
345
	sq_append_quote_argv_pretty(&buf_payload, cmd->args.v);
346
	strbuf_addch(&buf_payload, ']');
347

348
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
349
			 NULL, NULL, &buf_payload);
350
	strbuf_release(&buf_payload);
351
}
352

353
static void fn_child_exit_fl(const char *file, int line,
354
			     uint64_t us_elapsed_absolute, int cid, int pid,
355
			     int code, uint64_t us_elapsed_child)
356
{
357
	const char *event_name = "child_exit";
358
	struct strbuf buf_payload = STRBUF_INIT;
359

360
	strbuf_addf(&buf_payload, "[ch%d] pid:%d code:%d", cid, pid, code);
361

362
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
363
			 &us_elapsed_child, NULL, &buf_payload);
364
	strbuf_release(&buf_payload);
365
}
366

367
static void fn_child_ready_fl(const char *file, int line,
368
			      uint64_t us_elapsed_absolute, int cid, int pid,
369
			      const char *ready, uint64_t us_elapsed_child)
370
{
371
	const char *event_name = "child_ready";
372
	struct strbuf buf_payload = STRBUF_INIT;
373

374
	strbuf_addf(&buf_payload, "[ch%d] pid:%d ready:%s", cid, pid, ready);
375

376
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
377
			 &us_elapsed_child, NULL, &buf_payload);
378
	strbuf_release(&buf_payload);
379
}
380

381
static void fn_thread_start_fl(const char *file, int line,
382
			       uint64_t us_elapsed_absolute)
383
{
384
	const char *event_name = "thread_start";
385
	struct strbuf buf_payload = STRBUF_INIT;
386

387
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
388
			 NULL, NULL, &buf_payload);
389
	strbuf_release(&buf_payload);
390
}
391

392
static void fn_thread_exit_fl(const char *file, int line,
393
			      uint64_t us_elapsed_absolute,
394
			      uint64_t us_elapsed_thread)
395
{
396
	const char *event_name = "thread_exit";
397
	struct strbuf buf_payload = STRBUF_INIT;
398

399
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
400
			 &us_elapsed_thread, NULL, &buf_payload);
401
	strbuf_release(&buf_payload);
402
}
403

404
static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute,
405
		       int exec_id, const char *exe, const char **argv)
406
{
407
	const char *event_name = "exec";
408
	struct strbuf buf_payload = STRBUF_INIT;
409

410
	strbuf_addf(&buf_payload, "id:%d ", exec_id);
411
	strbuf_addstr(&buf_payload, "argv:[");
412
	if (exe) {
413
		strbuf_addstr(&buf_payload, exe);
414
		if (argv[0])
415
			strbuf_addch(&buf_payload, ' ');
416
	}
417
	sq_append_quote_argv_pretty(&buf_payload, argv);
418
	strbuf_addch(&buf_payload, ']');
419

420
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
421
			 NULL, NULL, &buf_payload);
422
	strbuf_release(&buf_payload);
423
}
424

425
static void fn_exec_result_fl(const char *file, int line,
426
			      uint64_t us_elapsed_absolute, int exec_id,
427
			      int code)
428
{
429
	const char *event_name = "exec_result";
430
	struct strbuf buf_payload = STRBUF_INIT;
431

432
	strbuf_addf(&buf_payload, "id:%d code:%d", exec_id, code);
433
	if (code > 0)
434
		strbuf_addf(&buf_payload, " err:%s", strerror(code));
435

436
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
437
			 NULL, NULL, &buf_payload);
438
	strbuf_release(&buf_payload);
439
}
440

441
static void fn_param_fl(const char *file, int line, const char *param,
442
			const char *value, const struct key_value_info *kvi)
443
{
444
	const char *event_name = "def_param";
445
	struct strbuf buf_payload = STRBUF_INIT;
446
	struct strbuf scope_payload = STRBUF_INIT;
447
	enum config_scope scope = kvi->scope;
448
	const char *scope_name = config_scope_name(scope);
449

450
	strbuf_addf(&buf_payload, "%s:%s", param, value);
451
	strbuf_addf(&scope_payload, "%s:%s", "scope", scope_name);
452

453
	perf_io_write_fl(file, line, event_name, NULL, NULL, NULL,
454
			 scope_payload.buf, &buf_payload);
455
	strbuf_release(&buf_payload);
456
	strbuf_release(&scope_payload);
457
}
458

459
static void fn_repo_fl(const char *file, int line,
460
		       const struct repository *repo)
461
{
462
	const char *event_name = "def_repo";
463
	struct strbuf buf_payload = STRBUF_INIT;
464

465
	strbuf_addstr(&buf_payload, "worktree:");
466
	sq_quote_buf_pretty(&buf_payload, repo->worktree);
467

468
	perf_io_write_fl(file, line, event_name, repo, NULL, NULL, NULL,
469
			 &buf_payload);
470
	strbuf_release(&buf_payload);
471
}
472

473
static void fn_region_enter_printf_va_fl(const char *file, int line,
474
					 uint64_t us_elapsed_absolute,
475
					 const char *category,
476
					 const char *label,
477
					 const struct repository *repo,
478
					 const char *fmt, va_list ap)
479
{
480
	const char *event_name = "region_enter";
481
	struct strbuf buf_payload = STRBUF_INIT;
482

483
	if (label)
484
		strbuf_addf(&buf_payload, "label:%s", label);
485
	if (fmt && *fmt) {
486
		strbuf_addch(&buf_payload, ' ');
487
		maybe_append_string_va(&buf_payload, fmt, ap);
488
	}
489

490
	perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute,
491
			 NULL, category, &buf_payload);
492
	strbuf_release(&buf_payload);
493
}
494

495
static void fn_region_leave_printf_va_fl(
496
	const char *file, int line, uint64_t us_elapsed_absolute,
497
	uint64_t us_elapsed_region, const char *category, const char *label,
498
	const struct repository *repo, const char *fmt, va_list ap)
499
{
500
	const char *event_name = "region_leave";
501
	struct strbuf buf_payload = STRBUF_INIT;
502

503
	if (label)
504
		strbuf_addf(&buf_payload, "label:%s", label);
505
	if (fmt && *fmt) {
506
		strbuf_addch(&buf_payload, ' ' );
507
		maybe_append_string_va(&buf_payload, fmt, ap);
508
	}
509

510
	perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute,
511
			 &us_elapsed_region, category, &buf_payload);
512
	strbuf_release(&buf_payload);
513
}
514

515
static void fn_data_fl(const char *file, int line, uint64_t us_elapsed_absolute,
516
		       uint64_t us_elapsed_region, const char *category,
517
		       const struct repository *repo, const char *key,
518
		       const char *value)
519
{
520
	const char *event_name = "data";
521
	struct strbuf buf_payload = STRBUF_INIT;
522

523
	strbuf_addf(&buf_payload, "%s:%s", key, value);
524

525
	perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute,
526
			 &us_elapsed_region, category, &buf_payload);
527
	strbuf_release(&buf_payload);
528
}
529

530
static void fn_data_json_fl(const char *file, int line,
531
			    uint64_t us_elapsed_absolute,
532
			    uint64_t us_elapsed_region, const char *category,
533
			    const struct repository *repo, const char *key,
534
			    const struct json_writer *value)
535
{
536
	const char *event_name = "data_json";
537
	struct strbuf buf_payload = STRBUF_INIT;
538

539
	strbuf_addf(&buf_payload, "%s:%s", key, value->json.buf);
540

541
	perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute,
542
			 &us_elapsed_region, category, &buf_payload);
543
	strbuf_release(&buf_payload);
544
}
545

546
static void fn_printf_va_fl(const char *file, int line,
547
			    uint64_t us_elapsed_absolute, const char *fmt,
548
			    va_list ap)
549
{
550
	const char *event_name = "printf";
551
	struct strbuf buf_payload = STRBUF_INIT;
552

553
	maybe_append_string_va(&buf_payload, fmt, ap);
554

555
	perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute,
556
			 NULL, NULL, &buf_payload);
557
	strbuf_release(&buf_payload);
558
}
559

560
static void fn_timer(const struct tr2_timer_metadata *meta,
561
		     const struct tr2_timer *timer,
562
		     int is_final_data)
563
{
564
	const char *event_name = is_final_data ? "timer" : "th_timer";
565
	struct strbuf buf_payload = STRBUF_INIT;
566
	double t_total = NS_TO_SEC(timer->total_ns);
567
	double t_min = NS_TO_SEC(timer->min_ns);
568
	double t_max = NS_TO_SEC(timer->max_ns);
569

570
	strbuf_addf(&buf_payload, ("name:%s"
571
				   " intervals:%"PRIu64
572
				   " total:%8.6f min:%8.6f max:%8.6f"),
573
		    meta->name,
574
		    timer->interval_count,
575
		    t_total, t_min, t_max);
576

577
	perf_io_write_fl(__FILE__, __LINE__, event_name, NULL, NULL, NULL,
578
			 meta->category, &buf_payload);
579
	strbuf_release(&buf_payload);
580
}
581

582
static void fn_counter(const struct tr2_counter_metadata *meta,
583
		       const struct tr2_counter *counter,
584
		       int is_final_data)
585
{
586
	const char *event_name = is_final_data ? "counter" : "th_counter";
587
	struct strbuf buf_payload = STRBUF_INIT;
588

589
	strbuf_addf(&buf_payload, "name:%s value:%"PRIu64,
590
		    meta->name,
591
		    counter->value);
592

593
	perf_io_write_fl(__FILE__, __LINE__, event_name, NULL, NULL, NULL,
594
			 meta->category, &buf_payload);
595
	strbuf_release(&buf_payload);
596
}
597

598
struct tr2_tgt tr2_tgt_perf = {
599
	.pdst = &tr2dst_perf,
600

601
	.pfn_init = fn_init,
602
	.pfn_term = fn_term,
603

604
	.pfn_version_fl = fn_version_fl,
605
	.pfn_start_fl = fn_start_fl,
606
	.pfn_exit_fl = fn_exit_fl,
607
	.pfn_signal = fn_signal,
608
	.pfn_atexit = fn_atexit,
609
	.pfn_error_va_fl = fn_error_va_fl,
610
	.pfn_command_path_fl = fn_command_path_fl,
611
	.pfn_command_ancestry_fl = fn_command_ancestry_fl,
612
	.pfn_command_name_fl = fn_command_name_fl,
613
	.pfn_command_mode_fl = fn_command_mode_fl,
614
	.pfn_alias_fl = fn_alias_fl,
615
	.pfn_child_start_fl = fn_child_start_fl,
616
	.pfn_child_exit_fl = fn_child_exit_fl,
617
	.pfn_child_ready_fl = fn_child_ready_fl,
618
	.pfn_thread_start_fl = fn_thread_start_fl,
619
	.pfn_thread_exit_fl = fn_thread_exit_fl,
620
	.pfn_exec_fl = fn_exec_fl,
621
	.pfn_exec_result_fl = fn_exec_result_fl,
622
	.pfn_param_fl = fn_param_fl,
623
	.pfn_repo_fl = fn_repo_fl,
624
	.pfn_region_enter_printf_va_fl = fn_region_enter_printf_va_fl,
625
	.pfn_region_leave_printf_va_fl = fn_region_leave_printf_va_fl,
626
	.pfn_data_fl = fn_data_fl,
627
	.pfn_data_json_fl = fn_data_json_fl,
628
	.pfn_printf_va_fl = fn_printf_va_fl,
629
	.pfn_timer = fn_timer,
630
	.pfn_counter = fn_counter,
631
};
632

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.