MCPcopy Create free account
hub / github.com/async-profiler/async-profiler / timerLoop

Method timerLoop

src/wallClock.cpp:188–269  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

186}
187
188void WallClock::timerLoop() {
189 int self = OS::threadId();
190 ThreadFilter* thread_filter = Profiler::instance()->threadFilter();
191 bool thread_filter_enabled = thread_filter->enabled();
192 Mode mode = _mode;
193
194 ThreadSleepMap thread_sleep_state;
195 ThreadList* thread_list = OS::listThreads();
196 _thread_cpu_time_buf.reset();
197 u64 cycle_start_time = OS::nanotime();
198
199 while (_running) {
200 bool enabled = _enabled;
201
202 for (int signaled_threads = 0; signaled_threads < THREADS_PER_TICK && thread_list->hasNext(); ) {
203 int thread_id = thread_list->next();
204 if (thread_id == self || thread_id <= 0) {
205 // On macOS, task_threads() may sporadically return 0 or -1 among thread IDs
206 continue;
207 }
208 if (thread_filter_enabled && !thread_filter->accept(thread_id)) {
209 continue;
210 }
211
212 if (mode == CPU_ONLY) {
213 if (!enabled || OS::threadState(thread_id) == THREAD_SLEEPING) {
214 continue;
215 }
216 } else if (mode == WALL_BATCH) {
217 ThreadSleepState& tss = thread_sleep_state[thread_id];
218 u64 new_thread_cpu_time = enabled ? OS::threadCpuTime(thread_id) : 0;
219 if (new_thread_cpu_time != 0 && new_thread_cpu_time - tss.last_cpu_time <= RUNNABLE_THRESHOLD_NS) {
220 tss.last_time = TSC::ticks();
221 if (++tss.counter < MAX_IDLE_BATCH) {
222 if (tss.counter == 1) {
223 tss.start_time = tss.last_time;
224 }
225 continue;
226 }
227 }
228 if (tss.counter != 0) {
229 recordWallClock(tss, THREAD_SLEEPING, thread_id);
230 tss.counter = 0;
231 }
232 }
233
234 if (enabled && OS::sendSignalToThread(thread_id, _signal)) {
235 signaled_threads++;
236 }
237 }
238
239 u64 current_time = OS::nanotime();
240 if (thread_list->hasNext()) {
241 // Try to keep interval stable regardless of the number of profiled threads
242 long long sleep_time = cycle_start_time + (u64)_interval * thread_list->index() / thread_list->count() - current_time;
243 OS::uninterruptibleSleep(sleep_time < MIN_INTERVAL ? MIN_INTERVAL : sleep_time, &_running);
244 } else {
245 // Cycle has ended: prepare for the next cycle

Callers

nothing calls this directly

Calls 11

threadFilterMethod · 0.80
hasNextMethod · 0.80
acceptMethod · 0.80
drainMethod · 0.80
endMethod · 0.80
enabledMethod · 0.45
resetMethod · 0.45
nextMethod · 0.45
indexMethod · 0.45
countMethod · 0.45
updateMethod · 0.45

Tested by

no test coverage detected