অ্যান্ড্রয়েড ১০ এবং এর পরবর্তী সংস্করণগুলো টাস্ক প্রোফাইলসহ একটি কন্ট্রোল গ্রুপ (cgroup) অ্যাবস্ট্রাকশন লেয়ার ব্যবহার করে, যা ডেভেলপাররা কোনো থ্রেড বা প্রসেসের উপর প্রয়োগ করার জন্য এক বা একাধিক বিধিনিষেধের সেট বর্ণনা করতে ব্যবহার করতে পারেন। এরপর সিস্টেমটি টাস্ক প্রোফাইলের নির্ধারিত পদক্ষেপগুলো অনুসরণ করে এক বা একাধিক উপযুক্ত cgroup নির্বাচন করে, যার মাধ্যমে বিধিনিষেধগুলো প্রয়োগ করা হয়, এবং উচ্চতর সফটওয়্যার লেয়ারকে প্রভাবিত না করেই অন্তর্নিহিত cgroup ফিচার সেটে পরিবর্তন আনা যায়।
সিগ্রুপ সম্পর্কে
সি-গ্রুপস (Cgroups) বিভিন্ন টাস্কের সেটকে (যার মধ্যে প্রসেস, থ্রেড এবং তাদের ভবিষ্যৎ সমস্ত চাইল্ড অন্তর্ভুক্ত) বিশেষায়িত আচরণসহ শ্রেণিবদ্ধ গ্রুপে একত্রিত ও বিভক্ত করার একটি পদ্ধতি প্রদান করে। অ্যান্ড্রয়েড সিপিইউ এবং মেমরির ব্যবহার ও বরাদ্দের মতো সিস্টেম রিসোর্স নিয়ন্ত্রণ ও হিসাব রাখার জন্য সি-গ্রুপস ব্যবহার করে, এবং এটি লিনাক্স কার্নেলের সি-গ্রুপস ভি১ ও ভি২ সমর্থন করে।
অ্যান্ড্রয়েড ৯ এবং এর নিচের সংস্করণ
অ্যান্ড্রয়েড ৯ এবং এর পূর্ববর্তী সংস্করণগুলোতে, init.rc ইনিশিয়ালাইজেশন স্ক্রিপ্টটিতে উপলব্ধ সি-গ্রুপগুলোর তালিকা, তাদের মাউন্টিং পয়েন্ট এবং ভার্সন অন্তর্ভুক্ত থাকত। যদিও এগুলো পরিবর্তন করা যেত, অ্যান্ড্রয়েড ফ্রেমওয়ার্ক আশা করত যে স্ক্রিপ্টটির উপর ভিত্তি করে নির্দিষ্ট স্থানে একটি নির্দিষ্ট ভার্সন এবং সাবগ্রুপের স্তরবিন্যাসসহ সি-গ্রুপগুলোর একটি নির্দিষ্ট সেট বিদ্যমান থাকবে। এর ফলে পরবর্তী কোন সি-গ্রুপ ভার্সন ব্যবহার করা হবে তা বেছে নেওয়ার, অথবা নতুন ফিচার ব্যবহারের জন্য সি-গ্রুপের স্তরবিন্যাস পরিবর্তন করার ক্ষমতা সীমিত হয়ে যেত।
অ্যান্ড্রয়েড ১০ এবং উচ্চতর
অ্যান্ড্রয়েড ১০ এবং এর পরবর্তী সংস্করণগুলো টাস্ক প্রোফাইলের সাথে সি-গ্রুপস (cgroups) ব্যবহার করে:
- সি-গ্রুপ সেটআপ। ডেভেলপাররা তাদের
cgroups.jsonফাইলে সি-গ্রুপের সেট, তাদের মাউন্টিং লোকেশন এবং অ্যাট্রিবিউটগুলো সংজ্ঞায়িত করার জন্য সি-গ্রুপ সেটআপের বর্ণনা দেন। ইনিশিয়ালাইজেশন প্রক্রিয়ার আর্লি-ইনিট পর্যায়ে সমস্ত সি-গ্রুপ মাউন্ট করা হয়। - টাস্ক প্রোফাইল। এগুলো এমন একটি অ্যাবস্ট্রাকশন প্রদান করে যা প্রয়োজনীয় কার্যকারিতাকে তার বাস্তবায়নের খুঁটিনাটি থেকে বিচ্ছিন্ন রাখে। অ্যান্ড্রয়েড ফ্রেমওয়ার্ক
task_profiles.jsonফাইলে বর্ণিত টাস্ক প্রোফাইলগুলোকেSetTaskProfilesএবংSetProcessProfilesAPI ব্যবহার করে কোনো প্রসেস বা থ্রেডে প্রয়োগ করে। (এই API-গুলো শুধুমাত্র অ্যান্ড্রয়েড ১১ এবং তার পরবর্তী সংস্করণগুলোর জন্য প্রযোজ্য।)
পূর্ববর্তী সংস্করণের সাথে সামঞ্জস্যতা বজায় রাখার জন্য, লিগ্যাসি ফাংশন set_cpuset_policy , set_sched_policy , এবং get_sched_policy একই API এবং কার্যকারিতা প্রদান করে, কিন্তু টাস্ক প্রোফাইল ব্যবহার করার জন্য এদের বাস্তবায়ন পরিবর্তন করা হয়েছে। নতুন ব্যবহারের ক্ষেত্রে AOSP লিগ্যাসি set_sched_policy ফাংশনের পরিবর্তে নতুন টাস্ক প্রোফাইল API ব্যবহার করার পরামর্শ দেয়।
Cgroups বর্ণনা ফাইল
<ANDROID_BUILD_TOP>/system/core/libprocessgroup/profiles/ এর অধীনে অবস্থিত cgroups.json ফাইলে Cgroup-গুলোর বর্ণনা দেওয়া আছে। প্রতিটি কন্ট্রোলার একটি উপ-বিভাগে বর্ণিত থাকে এবং এতে ন্যূনতম নিম্নলিখিত বিষয়গুলো অবশ্যই থাকতে হবে:
- নাম, যা কন্ট্রোলার ফিল্ড দ্বারা নির্ধারিত।
- মাউন্টিং পাথ, যা Path ফিল্ড দ্বারা সংজ্ঞায়িত।
- এই পাথের অধীনে থাকা ফাইলগুলির মালিকানা এবং অ্যাক্সেস মোড বর্ণনা করে এমন Mode , 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 অ্যাট্রিবিউট রয়েছে। Cgroups2- এর অধীনে থাকা কন্ট্রোলারগুলোর জন্য Path অ্যাট্রিবিউটটি সেই রুট পাথের সাপেক্ষে নির্ধারিত হয়। Android 12 এবং তার পরবর্তী সংস্করণগুলোতে, আপনি path এবং mode-কে "Optional" হিসেবে নির্দিষ্ট করে একটি cgroup কন্ট্রোলারকে true সেট করার মাধ্যমে সংজ্ঞায়িত করতে পারেন।
init প্রক্রিয়ার অংশ হিসেবে, early-init পর্যায়ে cgroups.json ফাইলটি পার্স করা হয় এবং cgroup-গুলো নির্দিষ্ট স্থানে মাউন্ট করা হয়। পরবর্তীতে 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" ]
}
}
আপনার অ্যাট্রিবিউটস তালিকায় এন্ট্রি হিসেবে নির্দিষ্ট সিগ্রুপ ফাইলগুলোর নাম নির্ধারণ করুন। প্রতিটি এন্ট্রিতে নিম্নলিখিত বিষয়গুলো থাকে:
- Name ফিল্ডটি অ্যাট্রিবিউটের নাম নির্দিষ্ট করে।
- কন্ট্রোলার ফিল্ডটি
cgroups.jsonফাইল থেকে একটি cgroup কন্ট্রোলারকে তার নাম দ্বারা রেফারেন্স করে। - ফাইল ফিল্ডটি এই কন্ট্রোলারের অধীনে থাকা একটি নির্দিষ্ট ফাইলের নাম দেয়।
অ্যাট্রিবিউট হলো টাস্ক প্রোফাইল সংজ্ঞার রেফারেন্স। টাস্ক প্রোফাইলের বাইরে, কেবল তখনই অ্যাট্রিবিউট ব্যবহার করুন যখন ফ্রেমওয়ার্কের সেই ফাইলগুলিতে সরাসরি অ্যাক্সেসের প্রয়োজন হয় এবং টাস্ক প্রোফাইল ব্যবহার করে সেই অ্যাক্সেসকে অ্যাবস্ট্রাক্ট করা যায় না। অন্য সব ক্ষেত্রে, টাস্ক প্রোফাইল ব্যবহার করুন; এগুলো প্রয়োজনীয় আচরণ এবং তার বাস্তবায়নের বিবরণের মধ্যে আরও ভালো ডিকাপলিং প্রদান করে।
প্রোফাইল বিভাগে নিম্নলিখিত বিষয়সহ টাস্ক প্রোফাইলের সংজ্ঞা রয়েছে:
- Name ফিল্ডটি প্রোফাইলের নাম নির্ধারণ করে।
অ্যাকশনস সেকশনে প্রোফাইল প্রয়োগ করার সময় সম্পাদিত কাজগুলোর একটি তালিকা দেওয়া থাকে। প্রতিটি কাজের নিম্নলিখিত বৈশিষ্ট্যগুলো রয়েছে:
- Name ফিল্ডটি কাজটি নির্দিষ্ট করে।
- প্যারামস সেকশনটি অ্যাকশনটির জন্য এক সেট প্যারামিটার নির্দিষ্ট করে।
সমর্থিত কার্যক্রমগুলো সারণিতে তালিকাভুক্ত করা হলো:
| পদক্ষেপ | প্যারামিটার | বর্ণনা |
|---|---|---|
SetTimerSlack | Slack | ন্যানোসেকেন্ডে টাইমারের স্ল্যাক |
SetAttribute | Name | অ্যাট্রিবিউটস সেকশনের কোনো অ্যাট্রিবিউটকে নির্দেশকারী একটি নাম | Value | নামযুক্ত অ্যাট্রিবিউট দ্বারা নির্দেশিত একটি মান যা ফাইলে লেখা হবে। |
WriteFile | FilePath | ফাইলের পথ | Value | ফাইলে লেখার জন্য একটি মান |
JoinCgroup | Controller | cgroups.json থেকে cgroup কন্ট্রোলারের নাম |
Path | সিগ্রুপ কন্ট্রোলারের হায়ারার্কিতে একটি সাব-গ্রুপ পাথ |
অ্যান্ড্রয়েড ১২ এবং এর পরবর্তী সংস্করণগুলোতে একটি ‘AggregateProfiles’ সেকশন রয়েছে, যেখানে অ্যাগ্রিগেট প্রোফাইলগুলো থাকে। এই অ্যাগ্রিগেট প্রোফাইলগুলোর প্রতিটি হলো এক বা একাধিক প্রোফাইলের একটি সেটের উপনাম (alias)। অ্যাগ্রিগেট প্রোফাইলের সংজ্ঞাগুলো নিম্নরূপ:
- Name ফিল্ডটি অ্যাগ্রিগেট প্রোফাইলের নাম নির্দিষ্ট করে।
- প্রোফাইল ফিল্ডে সামগ্রিক প্রোফাইলে অন্তর্ভুক্ত প্রোফাইলগুলোর নাম তালিকাভুক্ত করা হয়।
যখন একটি অ্যাগ্রিগেট প্রোফাইল প্রয়োগ করা হয়, তখন এর অন্তর্ভুক্ত সমস্ত প্রোফাইলও স্বয়ংক্রিয়ভাবে প্রয়োগ হয়ে যায়। অ্যাগ্রিগেট প্রোফাইলগুলিতে স্বতন্ত্র প্রোফাইল বা অন্যান্য অ্যাগ্রিগেট প্রোফাইল উভয়ই থাকতে পারে, যতক্ষণ পর্যন্ত কোনো পুনরাবৃত্তি (অর্থাৎ এমন কোনো প্রোফাইল যা নিজেকেই অন্তর্ভুক্ত করে) না থাকে।
task_profiles init language command
অ্যান্ড্রয়েড ১২ এবং তার পরবর্তী সংস্করণগুলোতে একটি নির্দিষ্ট প্রসেসের জন্য টাস্ক প্রোফাইল সক্রিয় করার সুবিধার্থে অ্যান্ড্রয়েড ইনিট ল্যাঙ্গুয়েজে ` task_profiles কমান্ডটি উপলব্ধ রয়েছে। এটি writepid কমান্ডকে (যা অ্যান্ড্রয়েড ১২-এ অপ্রচলিত) প্রতিস্থাপন করে, যা আগে একটি প্রসেসকে বিভিন্ন `cgroups`-এর মধ্যে স্থানান্তর করতে ব্যবহৃত হতো। task_profiles কমান্ডটি উপরের স্তরগুলোতে কোনো প্রভাব না ফেলেই অন্তর্নিহিত ইমপ্লিমেন্টেশন পরিবর্তন করার নমনীয়তা প্রদান করে। নিচের উদাহরণে, এই দুটি কমান্ড কার্যকরভাবে একই কাজ সম্পাদন করে:
writepid /dev/cpuctl/top-app/tasksঅ্যান্ড্রয়েড ১২-এ এটি অপ্রচলিত ঘোষণা করা হয়েছে। এটি বর্তমান টাস্কের পিআইডি (PID)
/dev/cpuctl/top-app/tasksফাইলে লেখার জন্য ব্যবহৃত হতো।task_profiles MaxPerformanceবর্তমান প্রসেসটিকে 'cpu' কন্ট্রোলারের (
cpuctl) অধীনে top-app গ্রুপে যুক্ত করে, যার ফলে প্রসেসটির PIDdev/cpuctl/top-app/tasksফাইলে লেখা হয়।
অ্যান্ড্রয়েড ১২ এবং তার পরবর্তী সংস্করণগুলিতে cgroup হায়ারার্কিতে টাস্ক মাইগ্রেট করার জন্য সর্বদা task_profiles কমান্ডটি ব্যবহার করুন। এটি এক বা একাধিক প্যারামিটার গ্রহণ করে, যা task_profiles.json ফাইলে নির্দিষ্ট করা প্রোফাইলগুলির নাম নির্দেশ করে।
এপিআই-স্তরের টাস্ক প্রোফাইল অনুসারে
অ্যান্ড্রয়েড ১২ এবং এর পরবর্তী সংস্করণগুলোতে, আপনি অ্যান্ড্রয়েড এপিআই লেভেলের উপর ভিত্তি করে অথবা ভেন্ডর পার্টিশন থেকে ডিফল্ট cgroups.json এবং task_profiles.json ফাইলগুলোর সংজ্ঞা সংশোধন বা ওভাররাইড করতে পারেন।
এপিআই লেভেলের উপর ভিত্তি করে সংজ্ঞাগুলো ওভাররাইড করতে হলে, ডিভাইসে নিম্নলিখিত ফাইলগুলো অবশ্যই উপস্থিত থাকতে হবে:
/system/etc/task_profiles/cgroups_<API level>.jsonকোনো এপিআই লেভেলের জন্য নির্দিষ্ট সি-গ্রুপগুলোর ক্ষেত্রে এটি ব্যবহার করুন।
/system/etc/task_profiles/task_profiles_<API level>.jsonএপিআই লেভেল-নির্দিষ্ট প্রোফাইলগুলোর জন্য এটি ব্যবহার করুন।
ভেন্ডর পার্টিশনের সংজ্ঞাগুলো ওভাররাইড করতে হলে, ডিভাইসে নিম্নলিখিত ফাইলগুলো অবশ্যই উপস্থিত থাকতে হবে:
-
/vendor/etc/cgroups.json -
/vendor/etc/task_profiles.json
এই ফাইলগুলিতে থাকা কোনো অ্যাট্রিবিউট বা প্রোফাইল ডেফিনিশনের নাম যদি ডিফল্ট ফাইলের নামের সাথে মিলে যায়, তাহলে ফাইলটির (এপিআই-লেভেল বা ভেন্ডর-লেভেল) ডেফিনিশনটি পূর্ববর্তী ডেফিনিশনটিকে ওভাররাইড করে। আরও মনে রাখবেন যে, ভেন্ডর-লেভেল ডেফিনিশনগুলো এপিআই-লেভেল ডেফিনিশনগুলোকে ওভাররাইড করে। যদি নতুন ডেফিনিশনটির একটি নতুন নাম থাকে, তাহলে অ্যাট্রিবিউট বা প্রোফাইলের সেটটি সেই নতুন ডেফিনিশন দ্বারা সংশোধিত হয়।
অ্যান্ড্রয়েড সিস্টেম cgroup এবং task_profile ফাইলগুলো এই ক্রমে লোড করে:
- ডিফল্ট
cgroups.jsonএবংtask_profiles.jsonফাইল। - এপিআই লেভেল-নির্দিষ্ট ফাইল, যদি থাকে।
- ভেন্ডর পার্টিশন ফাইল, যদি থাকে।
বিদ্যমান API-তে পরিবর্তন
অ্যান্ড্রয়েড ১০ এবং এর পরবর্তী সংস্করণগুলোতে set_cpuset_policy , set_sched_policy , এবং get_sched_policy ফাংশনগুলোর API-তে কোনো পরিবর্তন আনা হয়নি। তবে, অ্যান্ড্রয়েড ১০ এই ফাংশনগুলোকে libprocessgroup মধ্যে স্থানান্তর করেছে, যেটিতে এখন cgroup-সম্পর্কিত সমস্ত কার্যকারিতা রয়েছে।
যদিও cutils/sched_policy.h হেডারটি এখনও বিদ্যমান, বিদ্যমান কোডের কার্যকারিতা যাতে ব্যাহত না হয়, সেজন্য নিশ্চিত করুন যে নতুন কোডে এর পরিবর্তে একটি নতুন processgroup/sched_policy.h হেডার অন্তর্ভুক্ত করা হয়েছে।
যেসব মডিউল এই ফাংশনগুলোর কোনোটি ব্যবহার করে, তাদের মেকফাইলে libprocessgroup লাইব্রেরির উপর ডিপেন্ডেন্সি যোগ করতে হবে। যদি কোনো মডিউল libcutils অন্য কোনো কার্যকারিতা ব্যবহার না করে, তাহলে মেকফাইল থেকে libcutils লাইব্রেরির ডিপেন্ডেন্সি বাদ দিন।
টাস্ক প্রোফাইল এপিআই
processgroup/processgroup.h এ থাকা প্রাইভেট এপিআইগুলো নিম্নলিখিত টেবিলে সংজ্ঞায়িত করা হয়েছে:
| প্রকার | এপিআই এবং সংজ্ঞা |
|---|---|
bool | SetTaskProfiles(int tid, const std::vectorএর tid প্যারামিটার ব্যবহার করে, profiles উল্লেখিত টাস্ক প্রোফাইলগুলিকে একটি থ্রেড আইডি (tid) দ্বারা নির্দিষ্ট থ্রেডে প্রয়োগ করে। |
bool | SetProcessProfiles(uid_t uid, pid_t pid, const std::vectoruid এবং pid প্যারামিটার ব্যবহার করে, profiles উল্লেখিত টাস্ক প্রোফাইলগুলিকে তার ব্যবহারকারী এবং প্রসেস আইডি দ্বারা নির্দিষ্ট প্রসেসের উপর প্রয়োগ করে। |
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 দ্বারা নির্দিষ্ট প্রোফাইল অ্যাট্রিবিউটটি বিদ্যমান কিনা তা ফেরত দেয়; যদি true , তাহলে path ভেরিয়েবলটিকে সেই প্রোফাইল অ্যাট্রিবিউটের সাথে যুক্ত ফাইলের পাথে সেট করে। |
bool | CgroupGetAttributePathForTask(const std::string& attr_name, int tid, std::string* path)attr_name দ্বারা নির্দিষ্ট কোনো প্রোফাইল অ্যাট্রিবিউট বিদ্যমান আছে কিনা তা ফেরত দেয়; যদি true , তাহলে path ভেরিয়েবলটিকে সেই প্রোফাইল অ্যাট্রিবিউটের সাথে যুক্ত ফাইলের পাথে এবং tid প্যারামিটার ব্যবহার করে তার থ্রেড আইডি দ্বারা নির্দিষ্ট থ্রেডে সেট করে। |
bool | UsePerAppMemcg()সিস্টেমটি প্রতি-অ্যাপ মেমরি সি-গ্রুপ ব্যবহার করার জন্য কনফিগার করা আছে কিনা তা ফেরত দেয়। |