Android 10 ขึ้นไปจะใช้กลุ่มควบคุม (cgroup) Abstraction Layer ที่มีโปรไฟล์งาน ซึ่งนักพัฒนาซอฟต์แวร์สามารถใช้อธิบายชุดข้อมูล (หรือชุด) ข้อจำกัดที่จะใช้กับชุดข้อความหรือกระบวนการ จากนั้นระบบจะดำเนินการตามที่กำหนดไว้ในโปรไฟล์งานเพื่อเลือก cgroup ที่เหมาะสมอย่างน้อย 1 รายการ ซึ่งจะใช้ข้อจำกัด และสามารถเปลี่ยนแปลงชุดฟีเจอร์ cgroup ที่อยู่เบื้องหลังได้โดยไม่ส่งผลต่อเลเยอร์ซอฟต์แวร์ระดับสูงขึ้น
เกี่ยวกับ cgroups
Cgroups มีกลไกสำหรับการรวมและแบ่งพาร์ติชันชุดงาน (ซึ่งประกอบด้วยกระบวนการ ชุดข้อความ และองค์ประกอบย่อยทั้งหมดในอนาคต) เป็นกลุ่มแบบลำดับชั้น ด้วยการทำงานเฉพาะทาง Android ใช้ cgroups เพื่อควบคุมและพิจารณา ทรัพยากรระบบ เช่น การใช้และการจัดสรร CPU และหน่วยความจำ โดยรองรับ เคอร์เนล cgroups v1 ใน Linux และ cgroups v2
Android 9 และต่ำกว่า
ใน Android 9 และเวอร์ชันที่ต่ำกว่า สคริปต์เริ่มต้น init.rc
มีชุด cgroups, จุดต่อเชื่อม และเวอร์ชันที่ใช้ได้ แม้ว่าสิ่งเหล่านี้อาจเป็น
เฟรมเวิร์กของ Android ก็คาดหวังให้กลุ่ม cgroups ที่เฉพาะเจาะจงเกิดขึ้นที่
สถานที่ตั้งเฉพาะเจาะจงที่มีเวอร์ชันและลำดับชั้นของกลุ่มย่อย โดยอิงตาม
สคริปต์ การดำเนินการนี้จะจำกัดความสามารถในการเลือกเวอร์ชัน cgroup ถัดไปที่จะใช้ หรือ
เปลี่ยนลำดับชั้นของกลุ่มเพื่อใช้ฟีเจอร์ใหม่
Android 10 ขึ้นไป
Android 10 ขึ้นไปจะใช้กลุ่มที่มีโปรไฟล์งานดังนี้
- การตั้งค่า Cgroup นักพัฒนาแอปอธิบายการตั้งค่า cgroups ใน
cgroups.json
เพื่อกำหนดชุดของ cgroups รวมถึงตำแหน่งและแอตทริบิวต์การต่อเชื่อม ต่อเชื่อมกลุ่มทั้งหมดในระหว่างการเริ่มต้นช่วงเริ่มต้น ขั้นตอนได้ - โปรไฟล์งาน ซึ่งเป็นนามธรรมที่แยกองค์ประกอบที่จำเป็น
ฟังก์ชันการทำงานจากรายละเอียดการใช้งาน เฟรมเวิร์ก Android จะใช้โปรไฟล์งานตามที่อธิบายไว้ในไฟล์
task_profiles.json
กับกระบวนการหรือเธรดโดยใช้SetTaskProfiles
และSetProcessProfiles
API (API เหล่านี้มีให้ใช้งานเฉพาะใน Android 11 ขึ้นไป)
ฟังก์ชันเดิม set_cpuset_policy
เพื่อระบุความเข้ากันได้แบบย้อนหลัง
set_sched_policy
และ get_sched_policy
มี API และฟังก์ชันการทำงานเดียวกัน
แต่มีการปรับเปลี่ยนการใช้งานให้ใช้โปรไฟล์งาน สำหรับการใช้งานใหม่
กรณีที่ AOSP แนะนำให้ใช้ API โปรไฟล์งานใหม่แทน API เดิม
set_sched_policy
ไฟล์คำอธิบายกลุ่ม
เราได้อธิบายกลุ่มไว้ในcgroups.json
ที่อยู่ภายใต้ <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
ตัวควบคุมแต่ละตัวจะอธิบายไว้ในส่วนย่อยและต้องมีคุณสมบัติต่อไปนี้เป็นอย่างน้อย
- ชื่อที่กำหนดโดยช่องตัวควบคุม
- เส้นทางการต่อเชื่อมที่กําหนดโดยช่อง Path
- โหมด, UID (รหัสผู้ใช้) และ GID (รหัสกลุ่ม) ที่อธิบายเจ้าของ และ โหมดการเข้าถึงสำหรับไฟล์ภายใต้เส้นทางนี้ (ไม่บังคับทั้งหมด)
- แอตทริบิวต์ไม่บังคับ ซึ่งตั้งค่าเป็น 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"
}
]
}
}
ไฟล์ตัวอย่างนี้มี 2 ส่วน ได้แก่ Cgroups (อธิบายตัวควบคุม cgroup v1) และ Cgroups2 (อธิบายตัวควบคุม cgroup v2) ทั้งหมด
ตัวควบคุมในลําดับชั้น cgroups v2 จะต่อเชื่อมที่ตําแหน่งเดียวกัน
ดังนั้นส่วน Cgroups2 จึงมีเส้นทาง, โหมด, UID ของตัวเอง และ
GID เพื่ออธิบายตำแหน่งและแอตทริบิวต์สำหรับรากของ
ลำดับชั้น แอตทริบิวต์เส้นทางสำหรับตัวควบคุมภายใต้ Cgroups2 คือ
สัมพันธ์กับเส้นทางรากนั้น ใน Android 12 ขึ้นไป คุณจะกำหนด cgroup ได้
ตัวควบคุมที่ระบุด้วยเส้นทางและโหมดเป็น "Optional"
โดยตั้งค่าเป็น true
ไฟล์ cgroups.json
จะได้รับการแยกวิเคราะห์เป็นส่วนหนึ่งของกระบวนการเริ่มต้น ระหว่างช่วงเริ่มต้นใช้งานก่อนเปิดตัว
และ cgroups จะได้รับการต่อเชื่อมในตำแหน่งที่ระบุ รับข้อมูลในภายหลัง
ตำแหน่งการต่อเชื่อม Cgroup ให้ใช้ฟังก์ชัน API ของ CgroupGetControllerPath
ไฟล์โปรไฟล์งาน
task_profiles.json
อยู่ภายใต้ <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
ใช้เพื่ออธิบายชุดการดำเนินการที่เฉพาะเจาะจงซึ่งจะนำไปใช้กับกระบวนการหรือ
ชุดข้อความ ชุดการทำงานจะเชื่อมโยงกับชื่อโปรไฟล์ ซึ่งใช้ใน
SetTaskProfiles
และ SetProcessProfiles
เรียกใช้การดำเนินการกับโปรไฟล์
ตัวอย่างไฟล์ Tasks_profile.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 จะระบุชื่อของแอตทริบิวต์
- ช่องตัวควบคุมอ้างอิงตัวควบคุม cgroup จาก
cgroups.json
โดยใช้ชื่อไฟล์ดังกล่าว - ช่องไฟล์จะตั้งชื่อไฟล์ที่ต้องการภายใต้ตัวควบคุมนี้
แอตทริบิวต์คือข้อมูลอ้างอิงในคำจำกัดความของโปรไฟล์งาน นอกงาน ให้ใช้โปรไฟล์ดังกล่าวเฉพาะเมื่อเฟรมเวิร์กจำเป็นต้องเข้าถึงโปรไฟล์เหล่านั้นโดยตรง และไม่สามารถใช้โปรไฟล์งานเป็นนามธรรมได้ ในกรณีอื่นๆ ทั้งหมด ใช้โปรไฟล์งาน ซึ่งทำให้สามารถแยกระหว่างพฤติกรรมที่จำเป็นกับ รายละเอียดการนำไปใช้งาน
ส่วนโปรไฟล์มีคำจำกัดความของโปรไฟล์งานดังต่อไปนี้
- ช่องชื่อจะกำหนดชื่อโปรไฟล์
ส่วนการดำเนินการจะแสดงชุดการดำเนินการที่เกิดขึ้นเมื่อโปรไฟล์ ใช้แล้ว การดำเนินการแต่ละรายการมีข้อมูลต่อไปนี้
- ชื่อจะระบุการดำเนินการ
- ส่วน Params จะระบุชุดพารามิเตอร์สําหรับการดําเนินการ
การดำเนินการที่รองรับแสดงในตาราง
การทำงาน | พารามิเตอร์ | คำอธิบาย |
---|---|---|
SetTimerSlack |
Slack |
ตัวจับเวลาถอยหลังในหน่วยวินาที |
SetAttribute |
Name |
ชื่อที่อ้างอิงแอตทริบิวต์จากส่วนแอตทริบิวต์ |
Value |
ค่าที่จะเขียนลงในไฟล์ซึ่งแสดงด้วยแอตทริบิวต์ที่มีชื่อ | |
WriteFile | FilePath | เส้นทางไปยังไฟล์ |
Value | ค่าที่จะเขียนลงในไฟล์ | |
JoinCgroup |
Controller |
ชื่อของตัวควบคุมกลุ่มจาก cgroups.json |
Path |
เส้นทางกลุ่มย่อยในลำดับชั้นของตัวควบคุม cgroup |
Android 12 ขึ้นไปจะมีโปรไฟล์แบบรวม ที่มีโปรไฟล์รวม โดยแต่ละโปรไฟล์เป็นชื่อแทนของชุดของ โปรไฟล์อย่างน้อยหนึ่งโปรไฟล์ คำจำกัดความของโปรไฟล์รวมประกอบด้วยข้อมูลต่อไปนี้
- ช่องชื่อจะระบุชื่อของโปรไฟล์แบบรวม
- ช่องโปรไฟล์จะแสดงชื่อโปรไฟล์ที่รวมอยู่ใน รวมทั้งโปรไฟล์
เมื่อใช้โปรไฟล์รวม โปรไฟล์ทั้งหมดที่มี โดยอัตโนมัติ โปรไฟล์รวมสามารถมีได้ทั้งโปรไฟล์ส่วนบุคคล หรือโปรไฟล์รวมอื่นๆ ตราบเท่าที่ไม่มีการเกิดซ้ำ (โปรไฟล์ที่ ซึ่งรวมตัวเอง)
คำสั่งภาษา Tasks_profile init
คำสั่ง task_profiles
ใน Android Init Language
พร้อมให้ใช้งานใน Android 12 ขึ้นไป
การเปิดใช้งานโปรไฟล์งานสำหรับกระบวนการที่เฉพาะเจาะจง ฟีเจอร์นี้แทนที่ writepid
(เลิกใช้งานแล้วใน Android 12) ที่ใช้ในการย้ายข้อมูล
กระบวนการระหว่างกลุ่ม คำสั่ง task_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
เสมอเพื่อย้ายข้อมูลงานในลําดับชั้น cgroup ใน Android 12 ขึ้นไป ยอมรับพารามิเตอร์อย่างน้อย 1 รายการ ซึ่งแสดงถึง
ชื่อของโปรไฟล์ที่ระบุในไฟล์ task_profiles.json
ตามโปรไฟล์งานระดับ API
ใน Android 12 ขึ้นไป คุณจะแก้ไขหรือลบล้างได้
ในไฟล์ cgroups.json
และ task_profiles.json
เริ่มต้น
พิจารณาการเปลี่ยนแปลงของคุณในระดับ API ของ Android หรือดำเนินการจากผู้ให้บริการ
พาร์ติชัน
หากต้องการลบล้างคำจำกัดความตามระดับ API ไฟล์ต่อไปนี้จะต้อง ที่มีอยู่บนอุปกรณ์:
/system/etc/task_profiles/cgroups_<API level>.json
ใช้สำหรับกลุ่มเฉพาะในระดับ API
/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
ใหม่
ส่วนหัวแทน
โมดูลที่ใช้ฟังก์ชันใดๆ เหล่านี้ควรเพิ่มทรัพยากร Dependency ที่เกี่ยวกับ
ไลบรารี libprocessgroup
ลงในไฟล์ Makefile หากโมดูลไม่ได้ใช้ข้อกำหนดอื่น
ฟังก์ชัน libcutils
วาง libcutils
Dependency ของไลบรารีจาก คุณสามารถสร้าง
API โปรไฟล์งาน
API ส่วนตัวใน processgroup/processgroup.h
ได้รับการกําหนดไว้ในตารางต่อไปนี้
ประเภท | API และคำจำกัดความ |
---|---|
bool |
SetTaskProfiles(int tid, const std::vector
ใช้โปรไฟล์งานที่ระบุใน profiles กับชุดข้อความที่ระบุโดย
รหัสชุดข้อความ (tid) โดยใช้พารามิเตอร์ tid |
bool |
SetProcessProfiles(uid_t uid, pid_t pid, const std::vector
ใช้โปรไฟล์งานที่ระบุไว้ใน profiles กับกระบวนการที่ระบุ
ตามรหัสผู้ใช้และรหัสกระบวนการที่ใช้พารามิเตอร์ uid และ pid |
bool |
CgroupGetControllerPath(const std::string& cgroup_name, std::string* path)
ส่งคืนว่ามีตัวควบคุมกลุ่มรหัสที่ระบุโดย cgroup_name หรือไม่
หากเป็น true ให้กำหนดตัวแปร path เป็นรูทของกลุ่มนั้น |
bool |
CgroupGetAttributePath(const std::string& attr_name, std::string* path)
แสดงผลว่ามีแอตทริบิวต์โปรไฟล์ที่ระบุโดย attr_name หรือไม่ ถ้า
true ตั้งค่าตัวแปร path ให้กับเส้นทางของไฟล์ที่เชื่อมโยงกับ
แอตทริบิวต์โปรไฟล์นั้น |
bool |
CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)
แสดงผลว่ามีแอตทริบิวต์โปรไฟล์ที่ระบุโดย attr_name หรือไม่ ถ้า
true ตั้งค่าตัวแปร path ให้กับเส้นทางของไฟล์ที่เชื่อมโยงกับ
แอตทริบิวต์โปรไฟล์นั้น และชุดข้อความที่ระบุโดยรหัสชุดข้อความโดยใช้
พารามิเตอร์ tid |
bool |
UsePerAppMemcg()
แสดงผลว่าระบบได้รับการกำหนดค่าให้ใช้กลุ่มหน่วยความจำต่อแอปหรือไม่ |