int main (int argc, char *argv[]) { cairo_perf_t perf; const char *trace_dir = "cairo-traces:/usr/src/cairo-traces:/usr/share/cairo-traces"; unsigned int n; int i; parse_options (&perf, argc, argv); signal (SIGINT, interrupt); if (getenv ("CAIRO_TRACE_DIR") != NULL) trace_dir = getenv ("CAIRO_TRACE_DIR"); perf.targets = cairo_boilerplate_get_targets (&perf.num_targets, NULL); perf.times = xmalloc (perf.iterations * sizeof (cairo_perf_ticks_t)); /* do we have a list of filenames? */ perf.exact_names = have_trace_filenames (&perf); for (i = 0; i < perf.num_targets; i++) { const cairo_boilerplate_target_t *target = perf.targets[i]; if (! perf.list_only && ! target->is_measurable) continue; perf.target = target; perf.test_number = 0; if (perf.exact_names) { for (n = 0; n < perf.num_names; n++) { struct stat st; if (stat (perf.names[n], &st) == 0) { if (S_ISDIR (st.st_mode)) { cairo_perf_trace_dir (&perf, target, perf.names[n]); } else cairo_perf_trace (&perf, target, perf.names[n]); } } } else { int num_traces = 0; const char *dir; dir = trace_dir; do { char buf[1024]; const char *end = strchr (dir, ':'); if (end != NULL) { memcpy (buf, dir, end-dir); buf[end-dir] = '\0'; end++; dir = buf; } num_traces += cairo_perf_trace_dir (&perf, target, dir); dir = end; } while (dir != NULL); if (num_traces == 0) { warn_no_traces ("Found no traces in", trace_dir); return 1; } } if (perf.list_only) break; } cairo_perf_fini (&perf); return 0; }
int main (int argc, char *argv[]) { int i, j; cairo_perf_t perf; cairo_surface_t *surface; parse_options (&perf, argc, argv); if (check_cpu_affinity()) { fputs( "NOTICE: cairo-perf and the X server should be bound to CPUs (either the same\n" "or separate) on SMP systems. Not doing so causes random results when the X\n" "server is moved to or from cairo-perf's CPU during the benchmarks:\n" "\n" " $ sudo taskset -cp 0 $(pidof X)\n" " $ taskset -cp 1 $$\n" "\n" "See taskset(1) for information about changing CPU affinity.\n", stderr); } perf.targets = cairo_boilerplate_get_targets (&perf.num_targets, NULL); perf.times = xmalloc (perf.iterations * sizeof (cairo_perf_ticks_t)); for (i = 0; i < perf.num_targets; i++) { cairo_boilerplate_target_t *target = perf.targets[i]; if (! target_is_measurable (target)) continue; perf.target = target; perf.test_number = 0; for (j = 0; perf_cases[j].run; j++) { const cairo_perf_case_t *perf_case = &perf_cases[j]; for (perf.size = perf_case->min_size; perf.size <= perf_case->max_size; perf.size *= 2) { void *closure; surface = (target->create_surface) (NULL, target->content, perf.size, perf.size, perf.size, perf.size, CAIRO_BOILERPLATE_MODE_PERF, 0, &closure); if (surface == NULL) { fprintf (stderr, "Error: Failed to create target surface: %s\n", target->name); continue; } cairo_perf_timer_set_synchronize (target->synchronize, closure); perf.cr = cairo_create (surface); perf_case->run (&perf, perf.cr, perf.size, perf.size); if (cairo_status (perf.cr)) { fprintf (stderr, "Error: Test left cairo in an error state: %s\n", cairo_status_to_string (cairo_status (perf.cr))); } cairo_destroy (perf.cr); cairo_surface_destroy (surface); if (target->cleanup) target->cleanup (closure); } } } cairo_perf_fini (&perf); return 0; }