AndroidV上讀取proc/pressure/cpu失敗

一蜓洪、問(wèn)題與調(diào)試

在做cpu負(fù)載問(wèn)題的是纤勒,需要讀取/proc/pressure/cpu/的數(shù)據(jù),發(fā)現(xiàn)打開(kāi)文件失敗

#define KERNEL_INFO_CPU "proc/pressure/cpu"
......
    int fd = TEMP_FAILURE_RETRY(open(KERNEL_INFO_CPU, O_WRONLY | O_CLOEXEC));
    if (fd < 0) {
        ALOGE("open failed (errno=%d)", errno);
        return -1;
    }  
......

\color {red}{報(bào)錯(cuò) open failed (errno =13)}

#define EACCES 13 /* Permission denied */   意思就是沒(méi)有權(quán)限

查看一下

進(jìn)入 proc/pressure/目錄下  ls -alh
-r--r--r-- 1 root root 0 2024-06-11 20:01 cpu
-rw-rw-r-- 1 system system 0 2024-06-11 19:42 io
-rw-rw-r-- 1 system system 0 2024-06-11 19:41 memory

可以看到 cpu 訪問(wèn)需要root權(quán)限隆檀, 那就修改

system/core/rootdir/init.rc
在init.rc文件中加入如下
chown system system /proc/pressure/cpu
chmod 0664 /proc/pressure/cpu

調(diào)試編譯也簡(jiǎn)單摇天,直接在system/core/rootdir/ mm,編譯產(chǎn)生的文件在
target\product\XXXX\system\etc\init\hw\init.rc 恐仑,然后 push init.rc system/etc/init/hw 替換其中的init.rc
當(dāng)然直接把機(jī)器中的init.rc pull 出來(lái)闸翅,然后修改push進(jìn)去也可以。

二菊霜、jni的配置例子

接著整理一下jni的使用坚冀,不跨進(jìn)程,system_server進(jìn)程中的jni使用鉴逞。
主要涉及的文件

java 文件
....../services/core/java/com/android/server/am/NameJavaTemp.java
cpp 文件
....../services/jni/NameCppTemp.cpp
....../ services/jni/onload.cpp
....../services/jni/Android.bp

1记某、java 文件
....../services/core/java/com/android/server/am/NameJavaTemp.java

public class NameJavaTemp {
    public  NameJavaTemp(){
        init();
    }
    private void init(){
        new Thread(){
            @Override
            public void run(){
                javaToNative();
            }
        }.start();
    }
    private native void javaToNative();
    public void nativeTojava(String str){}
}

2构捡、....../services/jni/Android.bp

......
    srcs: [
        "onload.cpp",
        "com_android_server_am_NameCppTemp.cpp",
    ],
......

3液南、....../ services/jni/onload.cpp

namespace android {
......
int register_android_server_NameCppTemp(JNIEnv* env);
......
};

extern "C" jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
......
    register_android_server_NameCppTemp(env);
......
    return JNI_VERSION_1_4;
}

4、
如下代碼就包括從Java層通過(guò)jni調(diào)用到cpp層 javaToNative的具體實(shí)現(xiàn)勾徽,滑凉。

NameCppTemp.cpp
......
namespace android{
    static int initM(JNIEnv* env, jobject clazz) {
          ......
        jclass cls = env->GetObjectClass(clazz);
        jmethodID methodId = env->GetMethodID(cls, "nativeTojava", "(Ljava/lang/String;)V");
        if (methodId == nullptr) {
            // error
            return -1;
        }
        jstring arg = env->NewStringUTF("1");
        env->CallVoidMethod(clazz, methodId, arg);
    }
    static const JNINativeMethod gMethods[] = {
        { "javaToNative","()V",(void*) initM},   //javaToNative就是 java端聲明的native方法,initM就是具體實(shí)現(xiàn)的方法名
    };

    int register_android_server_NameCppTemp(JNIEnv *env) {
        return jniRegisterNativeMethods(env, "com/android/server/am/NameJavaTemp", gMethods,NELEM(gMethods)); //NameJavaTemp就是java端的類(lèi)名
    }
}

三、epoll機(jī)制例子

實(shí)現(xiàn)了 epoll機(jī)制 監(jiān)聽(tīng) proc/pressure/cpu的 閾值喘帚,

....../services/jni/NameCppTemp.cpp
#define KERNEL_INFO_CPU "proc/pressure/cpu"
#include <stdio.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>

#include <string>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <utils/misc.h>
#include <nativehelper/JNIHelp.h>
#include <errno.h>
#include <log/log.h>
#include "jni.h"
#include<iostream>
#include<fstream>
#include<string>

#define MAX_POLL_EVENT 256
namespace android{
static int epollfd = -1;
static JNIEnv* g_env;

static int initM(JNIEnv* env, jobject clazz) {
    const char trig[] = "some 500000 1000000";
    epollfd = epoll_create(MAX_POLL_EVENT);
    if (epollfd == -1) {
        ALOGE("epoll_create failed: %s", strerror(errno));
        return -1;
    }
    int fd = TEMP_FAILURE_RETRY(open(KERNEL_INFO_CPU, O_WRONLY | O_CLOEXEC));
    if (fd < 0) {
        ALOGE("open failed (errno=%d)", errno);
        return -1;
    }   
 int res;
    struct epoll_event epev;
    epev.events = EPOLLPRI;

    if (write(fd, trig, strlen(trig) + 1) < 0) {
        ALOGD("/proc/pressure/cpu write error: %s\n", strerror(errno));
        return -1;
    }
    res = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &epev);
    if (res < 0) {
        ALOGE("epoll_ctl for monitor failed; errno=%d", errno);
    }
    while(true) {
        struct epoll_event events[20];
        int eventCount = 0;
        eventCount = epoll_wait(epollfd, events, 20, -1);
        if (eventCount < 0) {
            if (errno == EINTR) {
                continue;
             }
            ALOGE("epoll_wait failed (errno=%d)", errno);
            return -1;
        }
        //ALOGD("The eventCount %d", eventCount);
        jclass cls = env->GetObjectClass(clazz);
        jmethodID methodId = env->GetMethodID(cls, "nativeTojava", "(Ljava/lang/String;)V");
        if (methodId == nullptr) {
            // error
            return -1;
        }
        jstring arg = env->NewStringUTF("1");
        env->CallVoidMethod(clazz, methodId, arg);
        //test
        std::ifstream file("proc/pressure/cpu");
        if (!file.is_open()) {
            ALOGD("open file failure");
            return -1;
        }
        std::string buf;
        getline(file, buf);
        ALOGD("ZZZZ %s", buf.c_str());
    }
}
static const JNINativeMethod gMethods[] = {
    { "javaToNative","()V",(void*) initM},   //javaToNative就是 java端聲明的native方法

};
int register_android_server_NameCppTemp(JNIEnv *env) {
    return jniRegisterNativeMethods(env, "com/android/server/am/NameJavaTemp", gMethods,NELEM(gMethods)); //NameJavaTemp就是java端的類(lèi)名
}
}

四畅姊、所涉及的jni 相關(guān)信息
1、JNI編程中JNIEnv吹由、jobject和jclass這三種基本類(lèi)型

  • JavaVm是虛擬機(jī)在jni層的代表若未,?個(gè)進(jìn)程只有?個(gè)JavaVm,所有線程共??個(gè)JavaVM倾鲫。

  • JNIEnv 是?個(gè)線程相關(guān)的結(jié)構(gòu)體粗合,它代表了java的運(yùn)?環(huán)境 萍嬉。每?個(gè)線程都會(huì)有?個(gè),不同的線程中
    不能相互調(diào)?隙疚,每個(gè)JNIEnv都是線程專(zhuān)有的壤追。 jni中可以擁有很多個(gè)JNIEnv,可以使?它來(lái)進(jìn)?java層
    和native層的調(diào)?供屉。

  • JNIEnv 是?個(gè)指針大诸,指向?個(gè)線程相關(guān)的結(jié)構(gòu),線程相關(guān)結(jié)構(gòu)指向了JNI函數(shù)指針數(shù)組贯卦。這個(gè)數(shù)組??
    定義了?量的JNI函數(shù)指針。

  • 在同?個(gè)線程中焙贷,多次調(diào)?JNI層?法撵割,傳?的JNIEnv都是相同的。
    在java層定義的本地?法辙芍,可以在不同的線程中調(diào)?啡彬,因此是可以接受不同的JNIEnv。

  • jobject:實(shí)例引?(C++的說(shuō)法:對(duì)象引?)(普通函數(shù))

  • jclass: 類(lèi)引? (靜態(tài)函數(shù))

static int initM(JNIEnv* env, jobject clazz) {......}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末故硅,一起剝皮案震驚了整個(gè)濱河市庶灿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吃衅,老刑警劉巖往踢,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異徘层,居然都是意外死亡峻呕,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)趣效,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瘦癌,“玉大人,你說(shuō)我怎么就攤上這事跷敬⊙端剑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵西傀,是天一觀的道長(zhǎng)斤寇。 經(jīng)常有香客問(wèn)我,道長(zhǎng)拥褂,這世上最難降的妖魔是什么抡驼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮肿仑,結(jié)果婚禮上致盟,老公的妹妹穿的比我還像新娘碎税。我一直安慰自己,他們只是感情好馏锡,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布雷蹂。 她就那樣靜靜地躺著,像睡著了一般杯道。 火紅的嫁衣襯著肌膚如雪匪煌。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,046評(píng)論 1 285
  • 那天党巾,我揣著相機(jī)與錄音萎庭,去河邊找鬼。 笑死齿拂,一個(gè)胖子當(dāng)著我的面吹牛驳规,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播署海,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吗购,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了砸狞?” 一聲冷哼從身側(cè)響起捻勉,我...
    開(kāi)封第一講書(shū)人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刀森,沒(méi)想到半個(gè)月后踱启,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡研底,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年禽捆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片飘哨。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胚想,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芽隆,到底是詐尸還是另有隱情浊服,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布胚吁,位于F島的核電站牙躺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏腕扶。R本人自食惡果不足惜孽拷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望半抱。 院中可真熱鬧脓恕,春花似錦膜宋、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至乃秀,卻和暖如春肛著,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背跺讯。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工枢贿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刀脏。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓局荚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親火本。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容