Android 10 و بالاتر از یک لایه انتزاعی گروه کنترل (cgroup) با نمایههای وظیفه استفاده میکند، که توسعهدهندگان میتوانند از آن برای توصیف مجموعه (یا مجموعههایی) از محدودیتها برای اعمال بر روی یک رشته یا یک فرآیند استفاده کنند. سپس سیستم اقدامات تجویز شده پروفایل های وظیفه را دنبال می کند تا یک یا چند cgroup مناسب را انتخاب کند، که از طریق آن محدودیت ها اعمال می شود و تغییرات در مجموعه ویژگی های cgroup زیربنایی می تواند بدون تأثیر بر لایه های نرم افزار بالاتر انجام شود.
درباره cgroups
گروههای C مکانیزمی برای جمعآوری و تقسیمبندی مجموعههای وظایف (که شامل فرآیندها، رشتهها و همه فرزندان آینده آنها هستند) به گروههای سلسله مراتبی با رفتار تخصصی ارائه میکنند. Android از cgroup ها برای کنترل و حساب کردن منابع سیستم مانند استفاده و تخصیص CPU و حافظه، با پشتیبانی از هسته لینوکس cgroups v1 و cgroups v2 استفاده می کند.
اندروید 9 و پایین تر
در اندروید 9 و پایینتر، اسکریپت مقداردهی اولیه init.rc
شامل مجموعهای از cgroupهای موجود، نقاط نصب و نسخههای آنها بود. در حالی که میتوان این موارد را تغییر داد، چارچوب اندروید انتظار داشت که مجموعهای از cgroupها در مکانهای خاص با یک نسخه خاص و سلسله مراتب زیرگروه، بر اساس اسکریپت وجود داشته باشند. این توانایی انتخاب نسخه بعدی cgroup برای استفاده یا تغییر سلسله مراتب cgroup برای استفاده از ویژگی های جدید را محدود می کرد.
اندروید 10 و بالاتر
Android 10 و بالاتر از cgroup ها با نمایه های وظیفه استفاده می کند:
- راه اندازی Cgroup. توسعه دهندگان تنظیمات cgroups را در فایل
cgroups.json
خود توصیف می کنند تا مجموعه ای از cgroup ها و مکان ها و ویژگی های نصب آنها را تعریف کنند. همه cgroup ها در مرحله اولیه اولیه فرآیند اولیه سازی نصب می شوند. - پروفایل های وظیفه اینها انتزاعی را ارائه می دهند که عملکرد مورد نیاز را از جزئیات اجرای آن جدا می کند. چارچوب Android پروفایل های وظیفه را همانطور که در فایل
task_profiles.json
توضیح داده شده است در یک فرآیند یا رشته با استفاده ازSetTaskProfiles
وSetProcessProfiles
API اعمال می کند. (این APIها مختص اندروید 11 و بالاتر هستند.)
برای ارائه سازگاری به عقب، توابع قدیمی set_cpuset_policy
، set_sched_policy
، و get_sched_policy
همان API و عملکرد را ارائه میکنند، اما اجرای آنها برای استفاده از پروفایلهای وظیفه اصلاح شده است. برای موارد استفاده جدید، AOSP استفاده از APIهای پروفایل وظیفه جدید را به جای تابع set_sched_policy
قدیمی توصیه می کند.
فایل توضیحات Cgroups
Cgroup ها در فایل cgroups.json
واقع در <ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/
توضیح داده می شوند. هر کنترل کننده در یک زیربخش توضیح داده شده است و باید حداقل موارد زیر را داشته باشد:
- نام، توسط فیلد Controller تعریف شده است.
- مسیر نصب، که توسط فیلد 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"
}
]
}
}
این فایل مثال شامل دو بخش Cgroups (توضیح کنترلرهای cgroup v1) و Cgroups2 (توضیح کنترلرهای cgroup v2) است. همه کنترلرهای سلسله مراتب cgroups v2 در یک مکان نصب شده اند. بنابراین، بخش Cgroups2 ویژگی های Path ، Mode ، UID و GID خود را دارد تا مکان و ویژگی های ریشه سلسله مراتب را توصیف کند. ویژگی Path برای Controllers در Cgroups2 نسبت به آن مسیر ریشه است. در اندروید 12 و بالاتر، میتوانید یک کنترلر cgroup را که با مسیر و حالت بهعنوان "Optional"
مشخص شده است، با تنظیم آن روی true
تعریف کنید.
فایل cgroups.json
به عنوان بخشی از فرآیند init، در مرحله اولیه init تجزیه می شود و cgroups در مکان های مشخص شده سوار می شوند. برای اینکه بعداً مکانهای نصب cgroup را بدست آورید، از تابع 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 نام ویژگی را مشخص می کند.
- فیلد کنترلر به یک کنترلر cgroup از فایل
cgroups.json
با نام آن اشاره می کند. - فیلد فایل یک فایل خاص را تحت این کنترلر نامگذاری می کند.
ویژگی ها ارجاعاتی در تعاریف پروفایل کار هستند. خارج از نمایههای وظیفه، تنها زمانی از آنها استفاده کنید که چارچوب نیاز به دسترسی مستقیم به آن فایلها داشته باشد، و دسترسی را نمیتوان با استفاده از نمایههای وظیفه انتزاعی کرد. در تمام موارد دیگر، از پروفایل های وظیفه استفاده کنید. آنها جداسازی بهتری بین رفتار مورد نیاز و جزئیات اجرای آن فراهم می کنند.
بخش پروفایل ها شامل تعاریف پروفایل کار با موارد زیر است:
- فیلد Name نام پروفایل را مشخص می کند.
بخش اقدامات مجموعه ای از اقدامات انجام شده در هنگام اعمال نمایه را فهرست می کند. هر عمل دارای موارد زیر است:
- فیلد Name عمل را مشخص می کند.
- بخش Params مجموعه ای از پارامترها را برای عمل مشخص می کند.
اقدامات پشتیبانی شده در جدول ذکر شده است:
اقدام | پارامتر | توضیحات |
---|---|---|
SetTimerSlack | Slack | تایمر شل در ns |
SetAttribute | Name | نامی که به یک ویژگی از بخش Attributes اشاره می کند | Value | مقداری که باید در فایلی که با ویژگی نامگذاری شده نشان داده می شود، نوشته شود |
WriteFile | FilePath | مسیر فایل | Value | مقداری که باید در فایل نوشته شود |
JoinCgroup | Controller | نامی از کنترلر cgroup از cgroups.json |
Path | یک مسیر زیر گروه در سلسله مراتب کنترلر cgroup |
اندروید 12 و بالاتر دارای بخش AggregateProfiles است که حاوی نمایههای انبوه است که هر کدام نام مستعار مجموعهای از یک یا چند نمایه است. تعاریف نمایه کل شامل موارد زیر است:
- فیلد Name نام نمایه انبوه را مشخص می کند.
- فیلد پروفایل ها نام پروفایل های موجود در نمایه انبوه را فهرست می کند.
هنگامی که یک نمایه انبوه اعمال می شود، تمام نمایه های حاوی نیز به طور خودکار اعمال می شوند. نمایههای انبوه میتوانند هم نمایههای مجزا یا سایر نمایههای انبوه را داشته باشند، تا زمانی که هیچ بازگشتی وجود نداشته باشد (نمایهای که شامل خود میشود).
دستور task_profiles init language
دستور task_profiles
در Android Init Language برای اندروید 12 و بالاتر برای تسهیل فعالسازی نمایه وظیفه برای یک فرآیند خاص در دسترس است. این دستور جایگزین دستور writepid
(منسوخ شده در اندروید 12) می شود که برای انتقال یک فرآیند بین cgroup ها استفاده می شد. دستور task_profiles
انعطافپذیری را برای تغییر پیادهسازیهای زیربنایی بدون تأثیر بر لایههای بالایی فراهم میکند. در مثال زیر، این دو دستور به طور موثر عملیات مشابهی را انجام می دهند:
writepid /dev/cpuctl/top-app/tasks
منسوخ شده در اندروید 12، از این برای نوشتن PID کار فعلی در فایل
/dev/cpuctl/top-app/tasks
استفاده میشد.task_profiles MaxPerformance
فرآیند فعلی را به گروه برنامه برتر تحت کنترلر "cpu" (
cpuctl
) می پیوندد، که منجر به نوشتن PID فرآیند درdev/cpuctl/top-app/tasks
می شود.
همیشه از دستور task_profiles
برای انتقال وظایف در سلسله مراتب cgroup در اندروید 12 و بالاتر استفاده کنید. این یک یا چند پارامتر را می پذیرد که نشان دهنده نام پروفایل های مشخص شده در فایل task_profiles.json
است.
براساس پروفایل های وظیفه در سطح API
در Android 12 و بالاتر، میتوانید تعاریف را در فایلهای cgroups.json
و task_profiles.json
پیشفرض اصلاح یا لغو کنید، یا تغییر خود را بر اساس سطح Android API یا از پارتیشن فروشنده ایجاد کنید.
برای نادیده گرفتن تعاریف بر اساس سطح API، فایل های زیر باید در دستگاه موجود باشد:
/system/etc/task_profiles/cgroups_<API level>.json
از این برای cgroup های خاص یک سطح API استفاده کنید.
/system/etc/task_profiles/task_profiles_<API level>.json
از این برای نمایه های مخصوص سطح API استفاده کنید.
برای نادیده گرفتن تعاریف از پارتیشن فروشنده، فایل های زیر باید در دستگاه موجود باشد:
-
/vendor/etc/cgroups.json
-
/vendor/etc/task_profiles.json
اگر یک ویژگی یا یک تعریف نمایه در این فایلها از همان نامی که در فایل پیشفرض است استفاده کند، تعریف فایل (سطح API یا سطح فروشنده) تعریف قبلی را لغو میکند. همچنین توجه داشته باشید که تعاریف در سطح فروشنده، تعاریف سطح API را لغو می کنند. اگر تعریف جدید نام جدیدی داشته باشد، مجموعه ویژگی ها یا پروفایل ها با تعریف جدید اصلاح می شوند.
سیستم اندروید فایل های cgroup
و task_profile
را به ترتیب بارگذاری می کند:
- فایل های
cgroups.json
وtask_profiles.json
پیش فرض. - فایلهای مخصوص سطح API، در صورت وجود.
- فایل های پارتیشن فروشنده، در صورت وجود.
تغییرات در API موجود
اندروید 10 و بالاتر، عملکردهای set_cpuset_policy
، set_sched_policy
و get_sched_policy
را بدون تغییر در API حفظ میکند. با این حال، Android 10 این توابع را به libprocessgroup
منتقل میکند، که اکنون شامل تمام عملکردهای مرتبط با cgroup است.
اگرچه هدر cutils/sched_policy.h
هنوز وجود دارد، برای جلوگیری از شکستن کد موجود، اطمینان حاصل کنید که کد جدید شامل یک هدر processgroup/sched_policy.h
جدید است.
ماژول هایی که از هر یک از این توابع استفاده می کنند باید وابستگی به کتابخانه libprocessgroup
به فایل اصلی خود اضافه کنند. اگر یک ماژول از هیچ عملکرد libcutils
دیگری استفاده نمی کند، وابستگی کتابخانه libcutils
را از makefile حذف کنید.
APIهای پروفایل وظیفه
APIهای خصوصی در processgroup/processgroup.h
در جدول تعریف شده اند:
تایپ کنید | API و تعریف |
---|---|
bool | SetTaskProfiles(int tid, const std::vector & profiles) SetTaskProfiles(int tid, const std::vector & profiles) پروفایل های وظیفه مشخص شده در profiles را با استفاده از پارامتر tid آن بر روی رشته مشخص شده توسط یک شناسه رشته (tid) اعمال می کند. |
bool | SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles) SetProcessProfiles(uid_t uid, pid_t pid, const std::vector & profiles) پروفایل های وظیفه مشخص شده در profiles را با استفاده از پارامترهای uid و pid در فرآیند مشخص شده توسط کاربر و شناسه های پردازش اعمال می کند. |
bool | CgroupGetControllerPath(const std::string& cgroup_name, std::string* path) نشان می دهد که آیا یک کنترلر cgroup مشخص شده توسط cgroup_name وجود دارد یا خیر. اگر true ، متغیر path را روی ریشه آن cgroup قرار می دهد |
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() نشان می دهد که آیا سیستم برای استفاده از cgroup های حافظه هر برنامه پیکربندی شده است یا خیر. |