+ int pairs = 0;
+ char *end;
+ bool pet = false;
+
+ assert(config != NULL);
+
+ ktrace_start_single_threaded();
+
+ ktrace_kernel_configure(KTRACE_KPERF);
+
+ if (config[0] == 'p') {
+ pet = true;
+ config++;
+ }
+
+ do {
+ uint32_t action_samplers;
+ uint64_t timer_period_ns;
+ uint64_t timer_period;
+
+ pairs += 1;
+ kperf_action_set_count(pairs);
+ kperf_timer_set_count(pairs);
+
+ action_samplers = (uint32_t)strtouq(config, &end, 0);
+ if (config == end) {
+ kprintf("kperf: unable to parse '%s' as action sampler\n", config);
+ goto out;
+ }
+ config = end;
+
+ kperf_action_set_samplers(pairs, action_samplers);
+
+ if (config[0] == '\0') {
+ kprintf("kperf: missing timer period in config\n");
+ goto out;
+ }
+ config++;
+
+ timer_period_ns = strtouq(config, &end, 0);
+ if (config == end) {
+ kprintf("kperf: unable to parse '%s' as timer period\n", config);
+ goto out;
+ }
+ nanoseconds_to_absolutetime(timer_period_ns, &timer_period);
+ config = end;
+
+ kperf_timer_set_period(pairs - 1, timer_period);
+ kperf_timer_set_action(pairs - 1, pairs);
+
+ if (pet) {
+ kperf_timer_set_petid(pairs - 1);
+ kperf_set_lightweight_pet(1);
+ pet = false;
+ }
+ } while (*(config++) == ',');
+
+ kperf_sampling_enable();
+
+out:
+ ktrace_end_single_threaded();