On Fri, Aug 04, 2017 at 02:35:34PM +0200, Peter Zijlstra wrote: > Something like: > > __update_state_and_time(event, new_state) > { > u64 delta, now = perf_event_time(event); > int old_state = event->state; > > event->tstamp = now; > event->state = new_state; > > delta = now - event->tstamp; Obv should go above the tstamp assignment
> switch (state) { > case STATE_ACTIVE: > WARN_ON_ONCE(old_state != STATE_INACTIVE); > event->total_time_enabled += delta; > break; > > case STATE_INACTIVE: > switch (old_state) { > case STATE_OFF: > /* ignore the OFF -> INACTIVE period */ > break; > > case STATE_ACTIVE: > event->total_time_enabled += delta; > event->total_time_running += delta; > break; > > default: > WARN_ONCE(); > } > break; > > case STATE_OFF: > WARN_ON_ONCE(old_state != STATE_INACTIVE) > event->total_time_enabled += delta; > break; > } > } So that's a straight fwd state machine that deals with: OFF <-> INACTIVE <-> ACTIVE but I think something like: __update_state_and_time(event, new_state) { u64 delta, new = perf_event_time(event); int old_state = event->state; delta = now - event->tstamp; event->tstamp = now; event->state = new_state; if (old_state == STATE_OFF) return; event->total_time_enabled += delta; if (old_state == STATE_ACTIVE) event->total_time_running += delta; } is equivalent and generates smaller code.. but again, double check (also it doesn't validate the state transitions).