| 506 | } |
| 507 | |
| 508 | int |
| 509 | EventProcessor::start(int n_event_threads, size_t stacksize) |
| 510 | { |
| 511 | using Graph = EThread::Metrics::Graph; |
| 512 | // do some sanity checking. |
| 513 | static bool started = false; |
| 514 | ink_release_assert(!started); |
| 515 | ink_release_assert(n_event_threads > 0 && n_event_threads <= MAX_EVENT_THREADS); |
| 516 | started = true; |
| 517 | |
| 518 | Thread_Affinity_Initializer.init(); |
| 519 | // Least ugly thing - this needs to be the first callback from the thread but by the time this |
| 520 | // method is called other spawn callbacks have been registered. This forces thread affinity |
| 521 | // first. The other alternative would be to require a call to an @c init method which I like even |
| 522 | // less because this cannot be done in the constructor - that depends on too much other |
| 523 | // infrastructure being in place (e.g. the proxy allocators). |
| 524 | thread_group[ET_CALL]._spawnQueue.push(make_event_for_scheduling(&Thread_Affinity_Initializer, EVENT_IMMEDIATE, nullptr)); |
| 525 | |
| 526 | // Get our statistics set up |
| 527 | RecRawStatBlock *rsb = RecAllocateRawStatBlock(EThread::Metrics::N_STATS); |
| 528 | unsigned stat_idx = 0; |
| 529 | char name[256]; |
| 530 | |
| 531 | // Enumerated statistics, one set per time scale. |
| 532 | for (unsigned ts_idx = 0; ts_idx < EThread::Metrics::N_TIMESCALES; ++ts_idx) { |
| 533 | auto sample_count = EThread::Metrics::SLICE_SAMPLE_COUNT[ts_idx]; |
| 534 | for (unsigned id = 0; id < EThread::Metrics::Slice::N_STAT_ID; ++id) { |
| 535 | snprintf(name, sizeof(name), "%s.%ds", EThread::Metrics::Slice::STAT_NAME[id], sample_count); |
| 536 | RecRegisterRawStat(rsb, RECT_PROCESS, name, RECD_INT, RECP_NON_PERSISTENT, stat_idx++, NULL); |
| 537 | } |
| 538 | } |
| 539 | |
| 540 | // Event loop timings. |
| 541 | for (Graph::raw_type id = 0; id < Graph::N_BUCKETS; ++id) { |
| 542 | snprintf(name, sizeof(name), "%s%zums", EThread::Metrics::LOOP_HISTOGRAM_STAT_STEM.data(), |
| 543 | static_cast<size_t>(EThread::Metrics::LOOP_HISTOGRAM_BUCKET_SIZE.count() * Graph::min_for_bucket(id))); |
| 544 | RecRegisterRawStat(rsb, RECT_PROCESS, name, RECD_INT, RECP_NON_PERSISTENT, stat_idx++, NULL); |
| 545 | } |
| 546 | |
| 547 | // plugin API timings |
| 548 | for (Graph::raw_type id = 0; id < Graph::N_BUCKETS; ++id) { |
| 549 | snprintf(name, sizeof(name), "%s%zums", EThread::Metrics::API_HISTOGRAM_STAT_STEM.data(), |
| 550 | static_cast<size_t>(EThread::Metrics::API_HISTOGRAM_BUCKET_SIZE.count() * Graph::min_for_bucket(id))); |
| 551 | RecRegisterRawStat(rsb, RECT_PROCESS, name, RECD_INT, RECP_NON_PERSISTENT, stat_idx++, NULL); |
| 552 | } |
| 553 | |
| 554 | // Name must be that of a stat, pick one at random since we do all of them in one pass/callback. |
| 555 | RecRegisterRawStatSyncCb(name, EventMetricStatSync, rsb, 0); |
| 556 | |
| 557 | this->spawn_event_threads(ET_CALL, n_event_threads, stacksize); |
| 558 | |
| 559 | Dbg(dbg_ctl_iocore_thread, "Created event thread group id %d with %d threads", ET_CALL, n_event_threads); |
| 560 | return 0; |
| 561 | } |
| 562 | |
| 563 | void |
| 564 | EventProcessor::shutdown() |
no test coverage detected