Home | History | Annotate | Download | only in perf

Lines Matching defs:sched

103 	int (*switch_event)(struct perf_sched *sched, struct perf_evsel *evsel,
106 int (*runtime_event)(struct perf_sched *sched, struct perf_evsel *evsel,
109 int (*wakeup_event)(struct perf_sched *sched, struct perf_evsel *evsel,
113 int (*fork_event)(struct perf_sched *sched, union perf_event *event,
116 int (*migrate_task_event)(struct perf_sched *sched,
183 static void burn_nsecs(struct perf_sched *sched, u64 nsecs)
189 } while (T1 + sched->run_measurement_overhead < T0 + nsecs);
202 static void calibrate_run_measurement_overhead(struct perf_sched *sched)
209 burn_nsecs(sched, 0);
214 sched->run_measurement_overhead = min_delta;
219 static void calibrate_sleep_measurement_overhead(struct perf_sched *sched)
232 sched->sleep_measurement_overhead = min_delta;
265 static void add_sched_event_run(struct perf_sched *sched, struct task_desc *task,
275 sched->nr_run_events_optimized++;
285 sched->nr_run_events++;
288 static void add_sched_event_wakeup(struct perf_sched *sched, struct task_desc *task,
299 sched->targetless_wakeups++;
303 sched->multitarget_wakeups++;
312 sched->nr_wakeup_events++;
315 static void add_sched_event_sleep(struct perf_sched *sched, struct task_desc *task,
322 sched->nr_sleep_events++;
325 static struct task_desc *register_pid(struct perf_sched *sched,
332 task = sched->pid_to_task[pid];
339 task->nr = sched->nr_tasks;
345 add_sched_event_sleep(sched, task, 0, 0);
347 sched->pid_to_task[pid] = task;
348 sched->nr_tasks++;
349 sched->tasks = realloc(sched->tasks, sched->nr_tasks * sizeof(struct task_task *));
350 BUG_ON(!sched->tasks);
351 sched->tasks[task->nr] = task;
354 printf("registered task #%ld, PID %ld (%s)\n", sched->nr_tasks, pid, comm);
360 static void print_task_traces(struct perf_sched *sched)
365 for (i = 0; i < sched->nr_tasks; i++) {
366 task = sched->tasks[i];
372 static void add_cross_task_wakeups(struct perf_sched *sched)
377 for (i = 0; i < sched->nr_tasks; i++) {
378 task1 = sched->tasks[i];
380 if (j == sched->nr_tasks)
382 task2 = sched->tasks[j];
383 add_sched_event_wakeup(sched, task1, 0, task2);
387 static void perf_sched__process_event(struct perf_sched *sched,
394 burn_nsecs(sched, atom->duration);
459 struct perf_sched *sched;
466 struct perf_sched *sched = parms->sched;
482 ret = pthread_mutex_lock(&sched->start_work_mutex);
484 ret = pthread_mutex_unlock(&sched->start_work_mutex);
491 perf_sched__process_event(sched, this_task->atoms[i]);
499 ret = pthread_mutex_lock(&sched->work_done_wait_mutex);
501 ret = pthread_mutex_unlock(&sched->work_done_wait_mutex);
507 static void create_tasks(struct perf_sched *sched)
519 err = pthread_mutex_lock(&sched->start_work_mutex);
521 err = pthread_mutex_lock(&sched->work_done_wait_mutex);
523 for (i = 0; i < sched->nr_tasks; i++) {
526 parms->task = task = sched->tasks[i];
527 parms->sched = sched;
537 static void wait_for_tasks(struct perf_sched *sched)
543 sched->start_time = get_nsecs();
544 sched->cpu_usage = 0;
545 pthread_mutex_unlock(&sched->work_done_wait_mutex);
547 for (i = 0; i < sched->nr_tasks; i++) {
548 task = sched->tasks[i];
553 ret = pthread_mutex_lock(&sched->work_done_wait_mutex);
558 pthread_mutex_unlock(&sched->start_work_mutex);
560 for (i = 0; i < sched->nr_tasks; i++) {
561 task = sched->tasks[i];
565 sched->cpu_usage += task->cpu_usage;
570 if (!sched->runavg_cpu_usage)
571 sched->runavg_cpu_usage = sched->cpu_usage;
572 sched->runavg_cpu_usage = (sched->runavg_cpu_usage * 9 + sched->cpu_usage) / 10;
574 sched->parent_cpu_usage = cpu_usage_1 - cpu_usage_0;
575 if (!sched->runavg_parent_cpu_usage)
576 sched->runavg_parent_cpu_usage = sched->parent_cpu_usage;
577 sched->runavg_parent_cpu_usage = (sched->runavg_parent_cpu_usage * 9 +
578 sched->parent_cpu_usage)/10;
580 ret = pthread_mutex_lock(&sched->start_work_mutex);
583 for (i = 0; i < sched->nr_tasks; i++) {
584 task = sched->tasks[i];
590 static void run_one_test(struct perf_sched *sched)
595 wait_for_tasks(sched);
599 sched->sum_runtime += delta;
600 sched->nr_runs++;
602 avg_delta = sched->sum_runtime / sched->nr_runs;
607 sched->sum_fluct += fluct;
608 if (!sched->run_avg)
609 sched->run_avg = delta;
610 sched->run_avg = (sched->run_avg * 9 + delta) / 10;
612 printf("#%-3ld: %0.3f, ", sched->nr_runs, (double)delta / 1000000.0);
614 printf("ravg: %0.2f, ", (double)sched->run_avg / 1e6);
617 (double)sched->cpu_usage / 1e6, (double)sched->runavg_cpu_usage / 1e6);
622 * accurate than the sched->sum_exec_runtime based statistics:
625 (double)sched->parent_cpu_usage/1e6,
626 (double)sched->runavg_parent_cpu_usage/1e6);
631 if (sched->nr_sleep_corrections)
632 printf(" (%ld sleep corrections)\n", sched->nr_sleep_corrections);
633 sched->nr_sleep_corrections = 0;
636 static void test_calibrations(struct perf_sched *sched)
641 burn_nsecs(sched, 1e6);
654 replay_wakeup_event(struct perf_sched *sched,
668 waker = register_pid(sched, sample->tid, "<unknown>");
669 wakee = register_pid(sched, pid, comm);
671 add_sched_event_wakeup(sched, waker, sample->time, wakee);
675 static int replay_switch_event(struct perf_sched *sched,
696 timestamp0 = sched->cpu_last_switched[cpu];
710 prev = register_pid(sched, prev_pid, prev_comm);
711 next = register_pid(sched, next_pid, next_comm);
713 sched->cpu_last_switched[cpu] = timestamp;
715 add_sched_event_run(sched, prev, timestamp, delta);
716 add_sched_event_sleep(sched, prev, timestamp, prev_state);
721 static int replay_fork_event(struct perf_sched *sched,
744 register_pid(sched, parent->tid, parent->comm);
745 register_pid(sched, child->tid, child->comm);
823 static int thread_atoms_insert(struct perf_sched *sched, struct thread *thread)
833 __thread_latency_insert(&sched->atom_root, atoms, &sched->cmp_pid);
911 static int latency_switch_event(struct perf_sched *sched,
927 timestamp0 = sched->cpu_last_switched[cpu];
928 sched->cpu_last_switched[cpu] = timestamp;
942 out_events = thread_atoms_search(&sched->atom_root, sched_out, &sched->cmp_pid);
944 if (thread_atoms_insert(sched, sched_out))
946 out_events = thread_atoms_search(&sched->atom_root, sched_out, &sched->cmp_pid);
955 in_events = thread_atoms_search(&sched->atom_root, sched_in, &sched->cmp_pid);
957 if (thread_atoms_insert(sched, sched_in))
959 in_events = thread_atoms_search(&sched->atom_root, sched_in, &sched->cmp_pid);
976 static int latency_runtime_event(struct perf_sched *sched,
984 struct work_atoms *atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
990 if (thread_atoms_insert(sched, thread))
992 atoms = thread_atoms_search(&sched->atom_root, thread, &sched->cmp_pid);
1005 static int latency_wakeup_event(struct perf_sched *sched,
1022 atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid);
1024 if (thread_atoms_insert(sched, wakee))
1026 atoms = thread_atoms_search(&sched->atom_root, wakee, &sched->cmp_pid);
1044 if (sched->profile_cpu == -1 && atom->state != THREAD_SLEEPING)
1045 sched->nr_state_machine_bugs++;
1047 sched->nr_timestamps++;
1049 sched->nr_unordered_timestamps++;
1058 static int latency_migrate_task_event(struct perf_sched *sched,
1072 if (sched->profile_cpu == -1)
1076 atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);
1078 if (thread_atoms_insert(sched, migrant))
1080 register_pid(sched, migrant->tid, migrant->comm);
1081 atoms = thread_atoms_search(&sched->atom_root, migrant, &sched->cmp_pid);
1095 sched->nr_timestamps++;
1098 sched->nr_unordered_timestamps++;
1103 static void output_lat_thread(struct perf_sched *sched, struct work_atoms *work_list)
1117 sched->all_runtime += work_list->total_runtime;
1118 sched->all_count += work_list->nb_atoms;
1237 static void perf_sched__sort_lat(struct perf_sched *sched)
1243 node = rb_first(&sched->atom_root);
1247 rb_erase(node, &sched->atom_root);
1249 __thread_latency_insert(&sched->sorted_atom_root, data, &sched->sort_list);
1258 struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
1260 if (sched->tp_handler->wakeup_event)
1261 return sched->tp_handler->wakeup_event(sched, evsel, sample, machine);
1266 static int map_switch_event(struct perf_sched *sched, struct perf_evsel *evsel,
1279 if (this_cpu > sched->max_cpu)
1280 sched->max_cpu = this_cpu;
1282 timestamp0 = sched->cpu_last_switched[this_cpu];
1283 sched->cpu_last_switched[this_cpu] = timestamp;
1297 sched->curr_thread[this_cpu] = sched_in;
1303 sched_in->shortname[0] = sched->next_shortname1;
1304 sched_in->shortname[1] = sched->next_shortname2;
1306 if (sched->next_shortname1 < 'Z') {
1307 sched->next_shortname1++;
1309 sched->next_shortname1='A';
1310 if (sched->next_shortname2 < '9') {
1311 sched->next_shortname2++;
1313 sched->next_shortname2='0';
1319 for (cpu = 0; cpu <= sched->max_cpu; cpu++) {
1325 if (sched->curr_thread[cpu]) {
1326 if (sched->curr_thread[cpu]->tid)
1327 printf("%2s ", sched->curr_thread[cpu]->shortname);
1350 struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
1355 if (sched->curr_pid[this_cpu] != (u32)-1) {
1360 if (sched->curr_pid[this_cpu] != prev_pid)
1361 sched->nr_context_switch_bugs++;
1364 if (sched->tp_handler->switch_event)
1365 err = sched->tp_handler->switch_event(sched, evsel, sample, machine);
1367 sched->curr_pid[this_cpu] = next_pid;
1376 struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
1378 if (sched->tp_handler->runtime_event)
1379 return sched->tp_handler->runtime_event(sched, evsel, sample, machine);
1389 struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
1395 if (sched->tp_handler->fork_event)
1396 return sched->tp_handler->fork_event(sched, event, machine);
1406 struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
1408 if (sched->tp_handler->migrate_task_event)
1409 return sched->tp_handler->migrate_task_event(sched, evsel, sample, machine);
1438 static int perf_sched__read_events(struct perf_sched *sched,
1442 { "sched:sched_switch", process_sched_switch_event, },
1443 { "sched:sched_stat_runtime", process_sched_runtime_event, },
1444 { "sched:sched_wakeup", process_sched_wakeup_event, },
1445 { "sched:sched_wakeup_new", process_sched_wakeup_event, },
1446 { "sched:sched_migrate_task", process_sched_migrate_task_event, },
1450 session = perf_session__new(input_name, O_RDONLY, 0, false, &sched->tool);
1460 int err = perf_session__process_events(session, &sched->tool);
1466 sched->nr_events = session->stats.nr_events[0];
1467 sched->nr_lost_events = session->stats.total_lost;
1468 sched->nr_lost_chunks = session->stats.nr_events[PERF_RECORD_LOST];
1483 static void print_bad_events(struct perf_sched *sched)
1485 if (sched->nr_unordered_timestamps && sched->nr_timestamps) {
1487 (double)sched->nr_unordered_timestamps/(double)sched->nr_timestamps*100.0,
1488 sched->nr_unordered_timestamps, sched->nr_timestamps);
1490 if (sched->nr_lost_events && sched->nr_events) {
1492 (double)sched->nr_lost_events/(double)sched->nr_events * 100.0,
1493 sched->nr_lost_events, sched->nr_events, sched->nr_lost_chunks);
1495 if (sched->nr_state_machine_bugs && sched->nr_timestamps) {
1497 (double)sched->nr_state_machine_bugs/(double)sched->nr_timestamps*100.0,
1498 sched->nr_state_machine_bugs, sched->nr_timestamps);
1499 if (sched->nr_lost_events)
1503 if (sched->nr_context_switch_bugs && sched->nr_timestamps) {
1505 (double)sched->nr_context_switch_bugs/(double)sched->nr_timestamps*100.0,
1506 sched->nr_context_switch_bugs, sched->nr_timestamps);
1507 if (sched->nr_lost_events)
1513 static int perf_sched__lat(struct perf_sched *sched)
1521 if (perf_sched__read_events(sched, &session))
1524 perf_sched__sort_lat(sched);
1530 next = rb_first(&sched->sorted_atom_root);
1536 output_lat_thread(sched, work_list);
1542 (double)sched->all_runtime / 1e6, sched->all_count);
1546 print_bad_events(sched);
1553 static int perf_sched__map(struct perf_sched *sched)
1555 sched->max_cpu = sysconf(_SC_NPROCESSORS_CONF);
1558 if (perf_sched__read_events(sched, NULL))
1560 print_bad_events(sched);
1564 static int perf_sched__replay(struct perf_sched *sched)
1568 calibrate_run_measurement_overhead(sched);
1569 calibrate_sleep_measurement_overhead(sched);
1571 test_calibrations(sched);
1573 if (perf_sched__read_events(sched, NULL))
1576 printf("nr_run_events: %ld\n", sched->nr_run_events);
1577 printf("nr_sleep_events: %ld\n", sched->nr_sleep_events);
1578 printf("nr_wakeup_events: %ld\n", sched->nr_wakeup_events);
1580 if (sched->targetless_wakeups)
1581 printf("target-less wakeups: %ld\n", sched->targetless_wakeups);
1582 if (sched->multitarget_wakeups)
1583 printf("multi-target wakeups: %ld\n", sched->multitarget_wakeups);
1584 if (sched->nr_run_events_optimized)
1586 sched->nr_run_events_optimized);
1588 print_task_traces(sched);
1589 add_cross_task_wakeups(sched);
1591 create_tasks(sched);
1593 for (i = 0; i < sched->replay_repeat; i++)
1594 run_one_test(sched);
1599 static void setup_sorting(struct perf_sched *sched, const struct option *options,
1602 char *tmp, *tok, *str = strdup(sched->sort_order);
1606 if (sort_dimension__add(tok, &sched->sort_list) < 0) {
1614 sort_dimension__add("pid", &sched->cmp_pid);
1627 "-e", "sched:sched_switch",
1628 "-e", "sched:sched_stat_wait",
1629 "-e", "sched:sched_stat_sleep",
1630 "-e", "sched:sched_stat_iowait",
1631 "-e", "sched:sched_stat_runtime",
1632 "-e", "sched:sched_process_fork",
1633 "-e", "sched:sched_wakeup",
1634 "-e", "sched:sched_migrate_task",
1655 static struct perf_sched sched = {
1663 .cmp_pid = LIST_HEAD_INIT(sched.cmp_pid),
1664 .sort_list = LIST_HEAD_INIT(sched.sort_list),
1678 OPT_STRING('s', "sort", &sched.sort_order, "key[,key2...]",
1682 OPT_INTEGER('C', "CPU", &sched.profile_cpu,
1689 OPT_UINTEGER('r', "repeat", &sched.replay_repeat,
1707 "perf sched latency [<options>]",
1711 "perf sched replay [<options>]",
1715 "perf sched [<options>] {record|latency|map|replay|script}",
1748 sched.tp_handler = &lat_ops;
1754 setup_sorting(&sched, latency_options, latency_usage);
1755 return perf_sched__lat(&sched);
1757 sched.tp_handler = &map_ops;
1758 setup_sorting(&sched, latency_options, latency_usage);
1759 return perf_sched__map(&sched);
1761 sched.tp_handler = &replay_ops;
1767 return perf_sched__replay(&sched);