| 363 | } |
| 364 | |
| 365 | static int cx_run(const char *root, const char *db_path, CxMetrics *out) { |
| 366 | memset(out, 0, sizeof(*out)); |
| 367 | |
| 368 | uint64_t d0; |
| 369 | uint64_t b0; |
| 370 | uint64_t f0; |
| 371 | uint64_t x0; |
| 372 | cbm_pxc_filter_stats(&d0, &b0, &f0, &x0); |
| 373 | uint64_t tl0 = atomic_load_explicit(&g_lsp_tail_lookups, memory_order_relaxed); |
| 374 | uint64_t tc0 = atomic_load_explicit(&g_lsp_tail_candidates, memory_order_relaxed); |
| 375 | uint64_t fb0 = cbm_pp_lsp_linear_fallback_rows(); |
| 376 | |
| 377 | atomic_store_explicit(&g_cx_pass_count, 0, memory_order_relaxed); |
| 378 | cbm_log_set_sink_ex(cx_pass_sink, CBM_LOG_SINK_TEE); |
| 379 | |
| 380 | double t0 = cx_now_s(); |
| 381 | cbm_pipeline_t *p = cbm_pipeline_new(root, db_path, CBM_MODE_FULL); |
| 382 | if (!p) { |
| 383 | return -1; |
| 384 | } |
| 385 | int rc = cbm_pipeline_run(p); |
| 386 | out->wall_s = cx_now_s() - t0; |
| 387 | cbm_log_set_sink(NULL); |
| 388 | int captured = atomic_load_explicit(&g_cx_pass_count, memory_order_relaxed); |
| 389 | out->pass_count = captured < CX_MAX_PASSES ? captured : CX_MAX_PASSES; |
| 390 | memcpy(out->passes, g_cx_passes, (size_t)out->pass_count * sizeof(CxPassMs)); |
| 391 | |
| 392 | char project[512]; |
| 393 | snprintf(project, sizeof(project), "%s", cbm_pipeline_project_name(p)); |
| 394 | cbm_pipeline_free(p); |
| 395 | if (rc != 0) { |
| 396 | return rc; |
| 397 | } |
| 398 | |
| 399 | uint64_t d1; |
| 400 | uint64_t b1; |
| 401 | uint64_t f1; |
| 402 | uint64_t x1; |
| 403 | cbm_pxc_filter_stats(&d1, &b1, &f1, &x1); |
| 404 | out->perfile_defs = d1 - d0; |
| 405 | out->build_files = b1 - b0; |
| 406 | out->filter_failed = x1 - x0; |
| 407 | out->tail_lookups = atomic_load_explicit(&g_lsp_tail_lookups, memory_order_relaxed) - tl0; |
| 408 | out->tail_candidates = atomic_load_explicit(&g_lsp_tail_candidates, memory_order_relaxed) - tc0; |
| 409 | out->fallback_rows = cbm_pp_lsp_linear_fallback_rows() - fb0; |
| 410 | |
| 411 | cbm_store_t *s = cbm_store_open_path(db_path); |
| 412 | if (!s) { |
| 413 | return -1; |
| 414 | } |
| 415 | out->nodes = cbm_store_count_nodes(s, project); |
| 416 | out->edges = cbm_store_count_edges(s, project); |
| 417 | for (int t = 0; t < CX_TEMPLATE_COUNT; t++) { |
| 418 | out->lang_nodes[t] = cbm_store_count_nodes_scoped(s, project, CX_TEMPLATES[t].dirname); |
| 419 | out->lang_edges[t] = cbm_store_count_edges_scoped(s, project, CX_TEMPLATES[t].dirname); |
| 420 | } |
| 421 | cbm_store_close(s); |
| 422 | return 0; |
no test coverage detected