Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1fa3a71 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Make LongArrayMultiStateCounter parcelable"

parents 482316c2 e5292b4a
Loading
Loading
Loading
Loading
+27 −27
Original line number Original line Diff line number Diff line
@@ -37,15 +37,15 @@ public class LongArrayMultiStateCounterPerfTest {


    /**
    /**
     * A complete line-for-line reimplementation of
     * A complete line-for-line reimplementation of
     * {@link }com.android.internal.os.CpuTimeInFreqMultiStateCounter}, only in Java instead of
     * {@link com.android.internal.os.LongArrayMultiStateCounter}, only in Java instead of
     * native.
     * native.
     */
     */
    private static class TestLongArrayMultiStateCounter {
    private static class TestLongArrayMultiStateCounter {
        private final int mStateCount;
        private final int mStateCount;
        private final int mArrayLength;
        private final int mArrayLength;
        private int mCurrentState;
        private int mCurrentState;
        private long mLastStateChangeTimestampMs;
        private long mLastStateChangeTimestampMs = -1;
        private long mLastUpdateTimestampMs;
        private long mLastUpdateTimestampMs = -1;


        private static class State {
        private static class State {
            private long mTimeInStateSinceUpdate;
            private long mTimeInStateSinceUpdate;
@@ -56,13 +56,9 @@ public class LongArrayMultiStateCounterPerfTest {
        private final long[] mLastTimeInFreq;
        private final long[] mLastTimeInFreq;
        private final long[] mDelta;
        private final long[] mDelta;


        TestLongArrayMultiStateCounter(int stateCount, int arrayLength, int initialState,
        TestLongArrayMultiStateCounter(int stateCount, int arrayLength) {
                long timestampMs) {
            mStateCount = stateCount;
            mStateCount = stateCount;
            mArrayLength = arrayLength;
            mArrayLength = arrayLength;
            mCurrentState = initialState;
            mLastStateChangeTimestampMs = timestampMs;
            mLastUpdateTimestampMs = timestampMs;
            mStates = new State[stateCount];
            mStates = new State[stateCount];
            for (int i = 0; i < mStateCount; i++) {
            for (int i = 0; i < mStateCount; i++) {
                mStates[i] = new State();
                mStates[i] = new State();
@@ -73,6 +69,7 @@ public class LongArrayMultiStateCounterPerfTest {
        }
        }


        public void setState(int state, long timestampMs) {
        public void setState(int state, long timestampMs) {
            if (mLastStateChangeTimestampMs > 0) {
                if (timestampMs >= mLastStateChangeTimestampMs) {
                if (timestampMs >= mLastStateChangeTimestampMs) {
                    mStates[mCurrentState].mTimeInStateSinceUpdate +=
                    mStates[mCurrentState].mTimeInStateSinceUpdate +=
                            timestampMs - mLastStateChangeTimestampMs;
                            timestampMs - mLastStateChangeTimestampMs;
@@ -81,6 +78,7 @@ public class LongArrayMultiStateCounterPerfTest {
                        mStates[i].mTimeInStateSinceUpdate = 0;
                        mStates[i].mTimeInStateSinceUpdate = 0;
                    }
                    }
                }
                }
            }
            mCurrentState = state;
            mCurrentState = state;
            mLastStateChangeTimestampMs = timestampMs;
            mLastStateChangeTimestampMs = timestampMs;
        }
        }
@@ -88,6 +86,7 @@ public class LongArrayMultiStateCounterPerfTest {
        public void updateValue(long[] timeInFreq, long timestampMs) {
        public void updateValue(long[] timeInFreq, long timestampMs) {
            setState(mCurrentState, timestampMs);
            setState(mCurrentState, timestampMs);


            if (mLastUpdateTimestampMs >= 0) {
                if (timestampMs > mLastUpdateTimestampMs) {
                if (timestampMs > mLastUpdateTimestampMs) {
                    if (delta(mLastTimeInFreq, timeInFreq, mDelta)) {
                    if (delta(mLastTimeInFreq, timeInFreq, mDelta)) {
                        long timeSinceUpdate = timestampMs - mLastUpdateTimestampMs;
                        long timeSinceUpdate = timestampMs - mLastUpdateTimestampMs;
@@ -104,6 +103,7 @@ public class LongArrayMultiStateCounterPerfTest {
                } else if (timestampMs < mLastUpdateTimestampMs) {
                } else if (timestampMs < mLastUpdateTimestampMs) {
                    throw new RuntimeException();
                    throw new RuntimeException();
                }
                }
            }
            System.arraycopy(timeInFreq, 0, mLastTimeInFreq, 0, mArrayLength);
            System.arraycopy(timeInFreq, 0, mLastTimeInFreq, 0, mArrayLength);
            mLastUpdateTimestampMs = timestampMs;
            mLastUpdateTimestampMs = timestampMs;
        }
        }
@@ -142,7 +142,7 @@ public class LongArrayMultiStateCounterPerfTest {
    @Test
    @Test
    public void javaImplementation() {
    public void javaImplementation() {
        TestLongArrayMultiStateCounter counter =
        TestLongArrayMultiStateCounter counter =
                new TestLongArrayMultiStateCounter(2, 4, 0, 1000);
                new TestLongArrayMultiStateCounter(2, 4);
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        long time = 1000;
        long time = 1000;
        long[] timeInFreq = {100, 200, 300, 400};
        long[] timeInFreq = {100, 200, 300, 400};
@@ -156,7 +156,7 @@ public class LongArrayMultiStateCounterPerfTest {


    @Test
    @Test
    public void nativeImplementation() {
    public void nativeImplementation() {
        LongArrayMultiStateCounter counter = new LongArrayMultiStateCounter(2, 4, 0, 1000);
        LongArrayMultiStateCounter counter = new LongArrayMultiStateCounter(2, 4);
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
        long time = 1000;
        long time = 1000;
        LongArrayMultiStateCounter.LongArrayContainer timeInFreq =
        LongArrayMultiStateCounter.LongArrayContainer timeInFreq =
+54 −6
Original line number Original line Diff line number Diff line
@@ -16,6 +16,11 @@


package com.android.internal.os;
package com.android.internal.os;


import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.util.Preconditions;

import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
import dalvik.annotation.optimization.FastNative;


@@ -47,7 +52,7 @@ import libcore.util.NativeAllocationRegistry;
 *
 *
 * @hide
 * @hide
 */
 */
public class LongArrayMultiStateCounter {
public final class LongArrayMultiStateCounter implements Parcelable {


    /**
    /**
     * Container for a native equivalent of a long[].
     * Container for a native equivalent of a long[].
@@ -112,14 +117,22 @@ public class LongArrayMultiStateCounter {
    // methods.
    // methods.
    final long mNativeObject;
    final long mNativeObject;


    public LongArrayMultiStateCounter(int stateCount, int arrayLength, int initialState,
    public LongArrayMultiStateCounter(int stateCount, int arrayLength) {
            long timestampMs) {
        Preconditions.checkArgumentPositive(stateCount, "stateCount must be greater than 0");
        mStateCount = stateCount;
        mStateCount = stateCount;
        mLength = arrayLength;
        mLength = arrayLength;
        mNativeObject = native_init(stateCount, arrayLength, initialState, timestampMs);
        mNativeObject = native_init(stateCount, arrayLength);
        sRegistry.registerNativeAllocation(this, mNativeObject);
        sRegistry.registerNativeAllocation(this, mNativeObject);
    }
    }


    private LongArrayMultiStateCounter(Parcel in) {
        mNativeObject = native_initFromParcel(in);
        sRegistry.registerNativeAllocation(this, mNativeObject);

        mStateCount = native_getStateCount(mNativeObject);
        mLength = native_getArrayLength(mNativeObject);
    }

    /**
    /**
     * Sets the current state to the supplied value.
     * Sets the current state to the supplied value.
     */
     */
@@ -161,9 +174,32 @@ public class LongArrayMultiStateCounter {
        return native_toString(mNativeObject);
        return native_toString(mNativeObject);
    }
    }


    @Override
    public void writeToParcel(Parcel dest, int flags) {
        native_writeToParcel(mNativeObject, dest, flags);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<LongArrayMultiStateCounter> CREATOR =
            new Creator<LongArrayMultiStateCounter>() {
                @Override
                public LongArrayMultiStateCounter createFromParcel(Parcel in) {
                    return new LongArrayMultiStateCounter(in);
                }

                @Override
                public LongArrayMultiStateCounter[] newArray(int size) {
                    return new LongArrayMultiStateCounter[size];
                }
            };


    @CriticalNative
    @CriticalNative
    private static native long native_init(int stateCount, int arrayLength, int initialState,
    private static native long native_init(int stateCount, int arrayLength);
            long timestampMs);


    @CriticalNative
    @CriticalNative
    private static native long native_getReleaseFunc();
    private static native long native_getReleaseFunc();
@@ -181,4 +217,16 @@ public class LongArrayMultiStateCounter {


    @FastNative
    @FastNative
    private native String native_toString(long nativeObject);
    private native String native_toString(long nativeObject);

    @FastNative
    private native void native_writeToParcel(long nativeObject, Parcel dest, int flags);

    @FastNative
    private static native long native_initFromParcel(Parcel parcel);

    @CriticalNative
    private static native int native_getStateCount(long nativeObject);

    @CriticalNative
    private static native int native_getArrayLength(long nativeObject);
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -263,6 +263,7 @@ cc_library_shared {
                "libdebuggerd_client",
                "libdebuggerd_client",
                "libutils",
                "libutils",
                "libbinder",
                "libbinder",
                "libbinder_ndk",
                "libui",
                "libui",
                "libgraphicsenv",
                "libgraphicsenv",
                "libgui",
                "libgui",
+99 −4
Original line number Original line Diff line number Diff line
@@ -14,17 +14,22 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#include <android/binder_parcel.h>
#include <android/binder_parcel_jni.h>
#include <android/binder_parcel_utils.h>
#include <android_runtime/Log.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedPrimitiveArray.h>

#include <cstring>
#include <cstring>

#include "LongArrayMultiStateCounter.h"
#include "LongArrayMultiStateCounter.h"
#include "core_jni_helpers.h"
#include "core_jni_helpers.h"


namespace android {
namespace android {


static jlong native_init(jint stateCount, jint arrayLength, jint initialState, jlong timestamp) {
static jlong native_init(jint stateCount, jint arrayLength) {
    battery::LongArrayMultiStateCounter *counter =
    battery::LongArrayMultiStateCounter *counter =
            new battery::LongArrayMultiStateCounter(stateCount, initialState,
            new battery::LongArrayMultiStateCounter(stateCount, std::vector<uint64_t>(arrayLength));
                                                    std::vector<uint64_t>(arrayLength), timestamp);
    return reinterpret_cast<jlong>(counter);
    return reinterpret_cast<jlong>(counter);
}
}


@@ -69,13 +74,95 @@ static jobject native_toString(JNIEnv *env, jobject self, jlong nativePtr) {
    return env->NewStringUTF(counter->toString().c_str());
    return env->NewStringUTF(counter->toString().c_str());
}
}


static void throwWriteRE(JNIEnv *env, binder_status_t status) {
    ALOGE("Could not write LongArrayMultiStateCounter to Parcel, status = %d", status);
    jniThrowRuntimeException(env, "Could not write LongArrayMultiStateCounter to Parcel");
}

#define THROW_ON_WRITE_ERROR(expr)     \
    {                                  \
        binder_status_t status = expr; \
        if (status != STATUS_OK) {     \
            throwWriteRE(env, status); \
        }                              \
    }

static void native_writeToParcel(JNIEnv *env, jobject self, jlong nativePtr, jobject jParcel,
                                 jint flags) {
    battery::LongArrayMultiStateCounter *counter =
            reinterpret_cast<battery::LongArrayMultiStateCounter *>(nativePtr);
    AParcel *parcel = AParcel_fromJavaParcel(env, jParcel);

    uint16_t stateCount = counter->getStateCount();
    THROW_ON_WRITE_ERROR(AParcel_writeInt32(parcel, stateCount));

    // LongArrayMultiStateCounter has at least state 0
    const std::vector<uint64_t> &anyState = counter->getCount(0);
    THROW_ON_WRITE_ERROR(AParcel_writeInt32(parcel, anyState.size()));

    for (battery::state_t state = 0; state < stateCount; state++) {
        THROW_ON_WRITE_ERROR(ndk::AParcel_writeVector(parcel, counter->getCount(state)));
    }
}

static void throwReadRE(JNIEnv *env, binder_status_t status) {
    ALOGE("Could not read LongArrayMultiStateCounter from Parcel, status = %d", status);
    jniThrowRuntimeException(env, "Could not read LongArrayMultiStateCounter from Parcel");
}

#define THROW_ON_READ_ERROR(expr)      \
    {                                  \
        binder_status_t status = expr; \
        if (status != STATUS_OK) {     \
            throwReadRE(env, status);  \
        }                              \
    }

static jlong native_initFromParcel(JNIEnv *env, jclass theClass, jobject jParcel) {
    AParcel *parcel = AParcel_fromJavaParcel(env, jParcel);

    int32_t stateCount;
    THROW_ON_READ_ERROR(AParcel_readInt32(parcel, &stateCount));

    int32_t arrayLength;
    THROW_ON_READ_ERROR(AParcel_readInt32(parcel, &arrayLength));

    battery::LongArrayMultiStateCounter *counter =
            new battery::LongArrayMultiStateCounter(stateCount, std::vector<uint64_t>(arrayLength));

    std::vector<uint64_t> value;
    value.reserve(arrayLength);

    for (battery::state_t state = 0; state < stateCount; state++) {
        THROW_ON_READ_ERROR(ndk::AParcel_readVector(parcel, &value));
        counter->setValue(state, value);
    }

    return reinterpret_cast<jlong>(counter);
}

static jint native_getStateCount(jlong nativePtr) {
    battery::LongArrayMultiStateCounter *counter =
            reinterpret_cast<battery::LongArrayMultiStateCounter *>(nativePtr);
    return counter->getStateCount();
}

static jint native_getArrayLength(jlong nativePtr) {
    battery::LongArrayMultiStateCounter *counter =
            reinterpret_cast<battery::LongArrayMultiStateCounter *>(nativePtr);

    // LongArrayMultiStateCounter has at least state 0
    const std::vector<uint64_t> &anyState = counter->getCount(0);
    return anyState.size();
}

static jlong native_init_LongArrayContainer(jint length) {
static jlong native_init_LongArrayContainer(jint length) {
    return reinterpret_cast<jlong>(new std::vector<uint64_t>(length));
    return reinterpret_cast<jlong>(new std::vector<uint64_t>(length));
}
}


static const JNINativeMethod g_LongArrayMultiStateCounter_methods[] = {
static const JNINativeMethod g_LongArrayMultiStateCounter_methods[] = {
        // @CriticalNative
        // @CriticalNative
        {"native_init", "(IIIJ)J", (void *)native_init},
        {"native_init", "(II)J", (void *)native_init},
        // @CriticalNative
        // @CriticalNative
        {"native_getReleaseFunc", "()J", (void *)native_getReleaseFunc},
        {"native_getReleaseFunc", "()J", (void *)native_getReleaseFunc},
        // @CriticalNative
        // @CriticalNative
@@ -86,6 +173,14 @@ static const JNINativeMethod g_LongArrayMultiStateCounter_methods[] = {
        {"native_getCounts", "(JJI)V", (void *)native_getCounts},
        {"native_getCounts", "(JJI)V", (void *)native_getCounts},
        // @FastNative
        // @FastNative
        {"native_toString", "(J)Ljava/lang/String;", (void *)native_toString},
        {"native_toString", "(J)Ljava/lang/String;", (void *)native_toString},
        // @FastNative
        {"native_writeToParcel", "(JLandroid/os/Parcel;I)V", (void *)native_writeToParcel},
        // @FastNative
        {"native_initFromParcel", "(Landroid/os/Parcel;)J", (void *)native_initFromParcel},
        // @CriticalNative
        {"native_getStateCount", "(J)I", (void *)native_getStateCount},
        // @CriticalNative
        {"native_getArrayLength", "(J)I", (void *)native_getArrayLength},
};
};


/////////////////////// LongArrayMultiStateCounter.LongArrayContainer ////////////////////////
/////////////////////// LongArrayMultiStateCounter.LongArrayContainer ////////////////////////
+6 −2
Original line number Original line Diff line number Diff line
@@ -282,7 +282,11 @@ public class KernelSingleUidTimeReaderTest {


    @Test
    @Test
    public void testAddDeltaFromBpf() {
    public void testAddDeltaFromBpf() {
        LongArrayMultiStateCounter counter = new LongArrayMultiStateCounter(2, 5, 0, 0);
        LongArrayMultiStateCounter counter = new LongArrayMultiStateCounter(2, 5);
        counter.setState(0, 0);
        mInjector.setCpuTimeInStatePerClusterNs(new long[][]{{0, 0, 0}, {0, 0}});
        boolean success = mInjector.addDelta(TEST_UID, counter, 0);
        assertThat(success).isTrue();


        // Nanoseconds
        // Nanoseconds
        mInjector.setCpuTimeInStatePerClusterNs(
        mInjector.setCpuTimeInStatePerClusterNs(
@@ -290,7 +294,7 @@ public class KernelSingleUidTimeReaderTest {
                        {1_000_000, 2_000_000, 3_000_000},
                        {1_000_000, 2_000_000, 3_000_000},
                        {4_000_000, 5_000_000}});
                        {4_000_000, 5_000_000}});


        boolean success = mInjector.addDelta(TEST_UID, counter, 2000);
        success = mInjector.addDelta(TEST_UID, counter, 2000);
        assertThat(success).isTrue();
        assertThat(success).isTrue();


        LongArrayMultiStateCounter.LongArrayContainer array =
        LongArrayMultiStateCounter.LongArrayContainer array =
Loading