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 Diff line number Diff line
@@ -37,15 +37,15 @@ public class LongArrayMultiStateCounterPerfTest {

    /**
     * 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.
     */
    private static class TestLongArrayMultiStateCounter {
        private final int mStateCount;
        private final int mArrayLength;
        private int mCurrentState;
        private long mLastStateChangeTimestampMs;
        private long mLastUpdateTimestampMs;
        private long mLastStateChangeTimestampMs = -1;
        private long mLastUpdateTimestampMs = -1;

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

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

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

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

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

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.FastNative;

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

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

    public LongArrayMultiStateCounter(int stateCount, int arrayLength, int initialState,
            long timestampMs) {
    public LongArrayMultiStateCounter(int stateCount, int arrayLength) {
        Preconditions.checkArgumentPositive(stateCount, "stateCount must be greater than 0");
        mStateCount = stateCount;
        mLength = arrayLength;
        mNativeObject = native_init(stateCount, arrayLength, initialState, timestampMs);
        mNativeObject = native_init(stateCount, arrayLength);
        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.
     */
@@ -161,9 +174,32 @@ public class LongArrayMultiStateCounter {
        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
    private static native long native_init(int stateCount, int arrayLength, int initialState,
            long timestampMs);
    private static native long native_init(int stateCount, int arrayLength);

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

    @FastNative
    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 Diff line number Diff line
@@ -263,6 +263,7 @@ cc_library_shared {
                "libdebuggerd_client",
                "libutils",
                "libbinder",
                "libbinder_ndk",
                "libui",
                "libgraphicsenv",
                "libgui",
+99 −4
Original line number Diff line number Diff line
@@ -14,17 +14,22 @@
 * 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 <cstring>

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

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 =
            new battery::LongArrayMultiStateCounter(stateCount, initialState,
                                                    std::vector<uint64_t>(arrayLength), timestamp);
            new battery::LongArrayMultiStateCounter(stateCount, std::vector<uint64_t>(arrayLength));
    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());
}

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) {
    return reinterpret_cast<jlong>(new std::vector<uint64_t>(length));
}

static const JNINativeMethod g_LongArrayMultiStateCounter_methods[] = {
        // @CriticalNative
        {"native_init", "(IIIJ)J", (void *)native_init},
        {"native_init", "(II)J", (void *)native_init},
        // @CriticalNative
        {"native_getReleaseFunc", "()J", (void *)native_getReleaseFunc},
        // @CriticalNative
@@ -86,6 +173,14 @@ static const JNINativeMethod g_LongArrayMultiStateCounter_methods[] = {
        {"native_getCounts", "(JJI)V", (void *)native_getCounts},
        // @FastNative
        {"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 ////////////////////////
+6 −2
Original line number Diff line number Diff line
@@ -282,7 +282,11 @@ public class KernelSingleUidTimeReaderTest {

    @Test
    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
        mInjector.setCpuTimeInStatePerClusterNs(
@@ -290,7 +294,7 @@ public class KernelSingleUidTimeReaderTest {
                        {1_000_000, 2_000_000, 3_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();

        LongArrayMultiStateCounter.LongArrayContainer array =
Loading