Android 10 以上版本會使用控制組 (cgroup) 包含工作設定檔的抽象層,可供開發人員描述集合 要套用至執行緒或程序的限制 (或多組)。接著,系統會 按照工作設定檔的操作步驟選取一或多個項目 套用限制的 cgroups 可以在不影響高階軟體的情況下建立基礎 Cgroup 功能 包含四個不同的層
關於 cgroups
Cgroups 提供將工作組合匯總與分區的機制 分為不同階層群組 (包含程序、執行緒及未來所有子項) 和特殊行為Android 會透過 cgroups 系統資源,例如 CPU 和記憶體用量和分配 Linux 核心 cgroups v1 和 cgroups v2。
Android 9 以下版本
在 Android 9 以下版本中,init.rc
初始化指令碼包含一組
可用的 cgroups、其掛接點和版本。雖然這些格式
因此 Android 架構預期有一組特定的 cgroups 存在
含有特定版本和子群組階層的特定位置
指令碼導致無法選擇使用下一個 cgroup 版本,或
變更 cgroup 階層以使用新功能。
Android 10 以上版本
Android 10 以上版本會使用具有工作設定檔的 cgroups:
- 群組設定。開發人員會在
cgroups.json
中說明 cgroups 設定 檔案定義一組 cgroups 以及其掛接位置和屬性。 所有 cgroups 都會在初始化的早期階段掛接 上傳資料集之後,您可以運用 AutoML 自動完成部分資料準備工作 - 工作設定檔。這些 API 會提供抽象層
導入新功能後Android 架構
按照
task_profiles.json
檔案所述,將工作設定檔套用至 運用SetTaskProfiles
和SetProcessProfiles
API 處理資料或執行緒 (這些 API 在 Android 11 以上版本中專有)。
為了提供回溯相容性,舊版函式 set_cpuset_policy
。
set_sched_policy
和 get_sched_policy
提供相同的 API 和功能。
但已修改實作方式,改為使用工作設定檔。新用途
AOSP 會建議使用新的工作設定檔 API,而非舊版
set_sched_policy
函式。
Cgroups 說明檔案
如需 Cgroups 的說明,請參閱cgroups.json
檔案位於 <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
下。
每個控制器都會透過子章節說明,且至少須符合下列最低要求:
- 名稱,由「Controller」欄位定義。
- 由「Path」欄位定義的掛接路徑。
- Mode、UID (使用者 ID) 和 GID (群組 ID),用於描述擁有者和 此路徑下檔案的存取模式 (所有選用)。
- 選用屬性,設為 true 可讓系統忽略因核心不支援的 cgroup 控制器所導致的掛載錯誤。
cgroups.json 檔案範例
以下範例是 Cgroup v1 (Cgroups
) 和 cgroup v2 的說明
(Cgroups2
) 控制器及其各自的路徑。
{
"Cgroups": [
{
"Controller": "cpu",
"Path": "/dev/cpuctl",
"Mode": "0755",
"UID": "system",
"GID": "system"
},
{
"Controller": "memory",
"Path": "/dev/memcg",
"Mode": "0700",
"Optional": true
}
],
"Cgroups2": {
"Path": "/sys/fs/cgroup",
"Mode": "0755",
"UID": "system",
"GID": "system",
"Controllers": [
{
"Controller": "freezer",
"Path": ".",
"Mode": "0755",
"UID": "system",
"GID": "system"
}
]
}
}
這個範例檔案包含兩個區段 Cgroups (說明 cgroup v1)
控制器) 和 Cgroups2 (說明 cgroup v2 控制器)。所有語言
cgroups v2 階層中的 cgroups 控制器皆存放在相同位置。
因此,Cgroups2 區段有專屬的 Path、Mode、UID 和
GID 屬性用來描述根部位置和屬性
階層Cgroups2 底下「Controllers」的「Path」屬性會相對於該根路徑。在 Android 12 以上版本中,您可以定義 cgroup
將路徑和模式指定為 "Optional"
的控制器
方法是將其設為 true
在初始化階段的早期,系統會在初始化程序中剖析 cgroups.json
檔案,並在指定位置掛載 cgroups。稍後取得
請使用 CgroupGetControllerPath
API 函式。
工作設定檔
task_profiles.json
檔案位於 <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
下。
可用於描述要套用至程序或執行緒的特定動作組合。一組動作會與設定檔名稱建立關聯,
SetTaskProfiles
和 SetProcessProfiles
呼叫叫用設定檔動作。
task_profiles.json 檔案範例
{
"Attributes": [
{
"Name": "MemSoftLimit",
"Controller": "memory",
"File": "memory.soft_limit_in_bytes"
},
{
"Name": "MemSwappiness",
"Controller": "memory",
"File": "memory.swappiness"
}
],
"Profiles": [
{
"Name": "MaxPerformance",
"Actions" : [
{
"Name" : "JoinCgroup",
"Params" :
{
"Controller": "schedtune",
"Path": "top-app"
}
}
]
},
{
"Name": "TimerSlackHigh",
"Actions" : [
{
"Name" : "SetTimerSlack",
"Params" :
{
"Slack": "40000000"
}
}
]
},
{
"Name": "LowMemoryUsage",
"Actions" : [
{
"Name" : "SetAttribute",
"Params" :
{
"Name" : "MemSoftLimit",
"Value" : "16MB"
}
},
{
"Name" : "SetAttribute",
"Params" :
{
"Name" : "MemSwappiness",
"Value" : "150"
}
}
]
}
]
"AggregateProfiles": [
{
"Name": "SCHED_SP_DEFAULT",
"Profiles": [ "TimerSlackHigh", "MaxPerformance" ]
},
{
"Name": "SCHED_SP_BACKGROUND",
"Profiles": [ "LowMemoryUsage" ]
}
}
將特定 cgroup 檔案的名稱指派為「屬性」清單中的項目。 每個項目都包含下列項目:
- 「Name」欄位會指定屬性名稱。
- 「控制器」欄位參照
cgroups.json
的 cgroup 控制器 檔案。 - 「File」欄位會命名這個控制器底下的特定檔案。
「屬性」是工作設定檔定義中的參照。工作之外 但請在架構需要直接存取這些設定檔時,才使用這類設定檔 也無法使用工作設定檔將存取權抽象化。在其他情況下 使用工作設定檔就能更有效地將必要行為與 以及實作細節
「Profiles」區段包含設定如下的工作設定檔定義:
- 「Name」欄位定義設定檔名稱。
「動作」部分會列出套用設定檔時執行的一組動作。每個動作都包含以下部分:
- 「Name」欄位會指定動作。
- 「Params」區段會指定一組動作的參數。
下表列出支援的動作:
動作 | 參數 | 說明 |
---|---|---|
SetTimerSlack |
Slack |
計時器鬆弛時間 (以奈秒為單位) |
SetAttribute |
Name |
參照「屬性」部分中屬性的名稱 |
Value |
要寫入由命名屬性代表的檔案的值 | |
WriteFile | FilePath | 檔案路徑 |
Value | 要寫入檔案的值 | |
JoinCgroup |
Controller |
cgroups.json 中的 cgroup 控制器名稱 |
Path |
cgroup 控制器階層中的子群組路徑 |
Android 12 以上版本提供 AggregateProfiles 區段,其中包含匯總個人資料,其中每個設定檔都是一組 的別名 一或多個設定檔匯總設定檔定義包含下列項目:
- 「Name」欄位會指定匯總設定檔的名稱。
- Profiles 欄位會列出 匯總設定檔
套用匯總設定檔時,所有內含的設定檔也會一併套用 自動套用最佳化建議。匯總剖析資料可同時包含個別設定檔 或其他匯總概況資料,前提是沒有遞展 (也就是 包括本體)。
task_profiles init 語言指令
在 Android 初始化語言中,Android 12 以上版本提供 task_profiles
指令,可協助啟用特定程序的工作設定檔。用於取代 writepid
指令 (在 Android 12 中已淘汰)
使用 cgroupstask_profiles
指令可彈性地變更基礎實作項目,且不會對上層造成影響。在
下列範例中,這兩個指令可有效執行相同的作業:
writepid /dev/cpuctl/top-app/tasks
已於 Android 12 淘汰,這會用來寫入 PID 放入
/dev/cpuctl/top-app/tasks
檔案中task_profiles MaxPerformance
將目前的程序加入「cpu」控制器 (
cpuctl
) 下的頂層應用程式群組,這會導致將程序的 PID 寫入dev/cpuctl/top-app/tasks
。
請一律使用 task_profiles
指令遷移以下目錄階層中的工作:
Android 12 以上版本。它可接受一或多個參數,用來代表
task_profiles.json
檔案中指定的設定檔名稱。
依 API 級別工作資料夾
在 Android 12 以上版本中,您可以變更或覆寫這項設定
預設 cgroups.json
和 task_profiles.json
檔案中的定義,這兩個
在 Android API 級別上進行變更,或從供應商執行變更
如要根據 API 級別覆寫定義,瀏覽器必須具備下列檔案 都顯示:
/system/etc/task_profiles/cgroups_<API level>.json
適用於 API 級別專用的 Cgroups。
/system/etc/task_profiles/task_profiles_<API level>.json
此類型適用於特定 API 級別的設定檔。
如要覆寫供應商分區的定義,下列檔案必須 :
/vendor/etc/cgroups.json
/vendor/etc/task_profiles.json
如果這些檔案中的屬性或設定檔定義名稱與 在預設檔案中,檔案 (API 層級或供應商層級) 定義會覆寫 先前的定義另請注意,供應商層級定義會覆寫供應商層級的定義 API 層級定義。如果新定義使用不同的名稱,則 屬性或個人資料都會採用新的定義。
Android 系統會按照下列順序載入 cgroup
和 task_profile
檔案:
- 預設
cgroups.json
和task_profiles.json
檔案。 - API 級別專屬檔案 (如果有)。
- 供應商分區檔案 (如有)。
現有 API 的變更
Android 10 以上版本會保留 set_cpuset_policy
、set_sched_policy
和 get_sched_policy
函式,但不會變更 API。不過,Android 10 會將這些函式
libprocessgroup
:現在包含所有 cgroup 相關功能。
雖然 cutils/sched_policy.h
標頭仍然存在,但為避免破壞
現有程式碼,確保新程式碼包含新的 processgroup/sched_policy.h
標題。
使用上述任一函式的模組應新增
libprocessgroup
程式庫新增至 makefile。如果模組未使用任何其他模組
libcutils
功能,放置 libcutils
makefile 中的程式庫依附元件
工作設定檔 API
下表定義了 processgroup/processgroup.h
中的私人 API:
類型 | API 與定義 |
---|---|
bool |
SetTaskProfiles(int tid, const std::vector
將 profiles 中指定的工作設定檔套用至
使用 tid 參數的執行緒 ID (tid)。 |
bool |
SetProcessProfiles(uid_t uid, pid_t pid, const std::vector
將 profiles 中指定的工作設定檔套用至指定的程序
,並使用 uid 和 pid 參數來處理 ID |
bool |
CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
傳回 cgroup_name 指定的 cgroup 控制器是否存在;
如果為 true ,則將 path 變數設為該 cgroup 的根 |
bool |
CgroupGetAttributePath(const std::string& attr_name, std::string* path)
會傳回 attr_name 指定的設定檔屬性是否存在;如果存在,就會將 path 變數設為與該設定檔屬性相關聯的檔案路徑。 |
bool |
CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
傳回 attr_name 指定的個人資料屬性是否存在;如果
true ,會將 path 變數設為相關聯的檔案路徑
該設定檔屬性,以及由執行緒 ID 指定的執行緒
tid 參數。 |
bool |
UsePerAppMemcg()
傳回系統是否設為使用個別應用程式記憶體 cgroups。 |