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;
}