static void record_timeline_event(unsigned int timeline_index, unsigned int type) { struct timespec event_timestamp; struct timespec *event_start = &timeline_event_starttime[timeline_index]; switch (type) { case ACTIVITY_START: /* Get the event time... */ getnstimeofday(&event_timestamp); /* Remember the start time if the activity is not already started */ if (event_start->tv_sec == 0) *event_start = event_timestamp; /* Structure copy */ break; case ACTIVITY_STOP: /* if the counter was started... */ if (event_start->tv_sec != 0) { /* Get the event time... */ getnstimeofday(&event_timestamp); /* Accumulate the duration in us */ timeline_data[timeline_index] += get_duration_us(event_start, &event_timestamp); /* Reset the start time to indicate the activity is stopped. */ event_start->tv_sec = 0; } break; default: /* Other activity events are ignored. */ break; } }
static int read(int **buffer) { int cnt; int len = 0; long sample_interval_us = 0; struct timespec read_timestamp; if (smp_processor_id()!=0) { return 0; } /* Get the start of this sample period. */ getnstimeofday(&read_timestamp); /* * Calculate the sample interval if the previous sample time is valid. * We use tv_sec since it will not be 0. */ if(prev_timestamp.tv_sec != 0) { sample_interval_us = get_duration_us(&prev_timestamp, &read_timestamp); } /* Structure copy. Update the previous timestamp. */ prev_timestamp = read_timestamp; /* * Report the timeline counters (ACTIVITY_START/STOP) */ for (cnt = FIRST_TIMELINE_EVENT; cnt < (FIRST_TIMELINE_EVENT + NUMBER_OF_TIMELINE_EVENTS); cnt++) { mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_TIMELINE_EVENT; unsigned int value; /* If the activity is still running, reset its start time to the start of this sample period * to correct the count. Add the time up to the end of the sample onto the count. */ if(timeline_event_starttime[index].tv_sec != 0) { const long event_duration = get_duration_us(&timeline_event_starttime[index], &read_timestamp); timeline_data[index] += event_duration; timeline_event_starttime[index] = read_timestamp; /* Activity is still running. */ } if(sample_interval_us != 0) { /* Convert the counter to a percent-of-sample value */ value = (timeline_data[index] * 100) / sample_interval_us; } else { pr_debug("gator: Mali-T6xx: setting value to zero\n"); value = 0; } /* Clear the counter value ready for the next sample. */ timeline_data[index] = 0; counter_dump[len++] = counter->key; counter_dump[len++] = value; } } /* Report the software counters */ for (cnt = FIRST_SOFTWARE_COUNTER; cnt < (FIRST_SOFTWARE_COUNTER + NUMBER_OF_SOFTWARE_COUNTERS); cnt++) { const mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_SOFTWARE_COUNTER; counter_dump[len++] = counter->key; counter_dump[len++] = sw_counter_data[index]; /* Set the value to zero for the next time */ sw_counter_data[index] = 0; } } /* Report the accumulators */ for (cnt = FIRST_ACCUMULATOR; cnt < (FIRST_ACCUMULATOR + NUMBER_OF_ACCUMULATORS); cnt++) { const mali_counter *counter = &counters[cnt]; if (counter->enabled) { const int index = cnt - FIRST_ACCUMULATOR; counter_dump[len++] = counter->key; counter_dump[len++] = accumulators_data[index]; /* Do not zero the accumulator */ } } /* Update the buffer */ if (buffer) { *buffer = (int*) counter_dump; } return len; }