HIDL MemoryBlock হল hidl_memory, HIDL
@1.0::IAllocator ও HIDL @1.0::IMapper-এর উপর ভিত্তি করে তৈরি একটি অ্যাবস্ট্রাক্ট লেয়ার। এটি HIDL পরিষেবার জন্য ডিজাইন করা হয়েছে
যেখানে একটি মেমরি হিপ শেয়ার করার জন্য একাধিক মেমরি ব্লক থাকে।
পারফর্ম্যান্সের উন্নতি
অ্যাপে MemoryBlock ব্যবহার করলে, mmap/munmap-এর সংখ্যা এবং ব্যবহারকারীর স্পেস সেগমেন্টেশন সংক্রান্ত সমস্যা উল্লেখযোগ্যভাবে কমে যায়, যার ফলে পারফর্ম্যান্স উন্নত হয়।
যেমন:
- প্রতিটি বাফার অ্যালোকেশনের জন্য
hidl_memoryব্যবহার করলে, গড়ে ২৩৮ us/1 অ্যালোকেশন হয়। MemoryBlockব্যবহার করে একটিhidl_memoryশেয়ার করলে, গড়ে ২.৮২ us/1 অ্যালোকেশন হয়।
স্থাপত্যশিল্প
HIDL MemoryBlock আর্কিটেকচারে একাধিক মেমরি
ব্লক সহ HIDL পরিষেবা অন্তর্ভুক্ত থাকে যা একটি মেমরি হিপ শেয়ার করে:
ছবি ১. HIDL MemoryBlock আর্কিটেকচার
সাধারণ ব্যবহার
এই বিভাগে, প্রথমে HAL ঘোষণা করে
তারপর HAL প্রয়োগ করার মাধ্যমে MemoryBlock ব্যবহারের একটি উদাহরণ দেওয়া হয়েছে।
HAL ঘোষণা করা
IFoo HAL-এর নিম্নলিখিত উদাহরণের জন্য:
import android.hidl.memory.block@1.0::MemoryBlock;
interface IFoo {
getSome() generates(MemoryBlock block);
giveBack(MemoryBlock block);
};
Android.bp হল:
hidl_interface {
...
srcs: [
"IFoo.hal",
],
interfaces: [
"android.hidl.memory.block@1.0",
...
};
HAL প্রয়োগ করা
উদাহরণ HAL প্রয়োগ করতে:
hidl_memoryপান (বিস্তারিত জানতে, HIDL C++ দেখুন)।#include <android/hidl/allocator/1.0/IAllocator.h> using ::android::hidl::allocator::V1_0::IAllocator; using ::android::hardware::hidl_memory; ... sp<IAllocator> allocator = IAllocator::getService("ashmem"); allocator->allocate(2048, [&](bool success, const hidl_memory& mem) { if (!success) { /* error */ } // you can now use the hidl_memory object 'mem' or pass it }));অ্যাকোয়ার করা
hidl_memoryদিয়েHidlMemoryDealerইনস্ট্যান্স তৈরি করুন:#include <hidlmemory/HidlMemoryDealer.h> using ::android::hardware::HidlMemoryDealer /* The mem argument is acquired in the Step1, returned by the ashmemAllocator->allocate */ sp<HidlMemoryDealer> memory_dealer = HidlMemoryDealer::getInstance(mem);MemoryBlockবরাদ্দ করুন, যা HIDL-এর মাধ্যমে সংজ্ঞায়িত একটি স্ট্রাক্ট।উদাহরণ
MemoryBlock:struct MemoryBlock { IMemoryToken token; uint64_t size; uint64_t offset; };MemoryBlockবরাদ্দ করার জন্যMemoryDealerব্যবহার করার উদাহরণ:#include <android/hidl/memory/block/1.0/types.h> using ::android::hidl::memory::block::V1_0::MemoryBlock; Return<void> Foo::getSome(getSome_cb _hidl_cb) { MemoryBlock block = memory_dealer->allocate(1024); if(HidlMemoryDealer::isOk(block)){ _hidl_cb(block); ...MemoryBlock-কে ডিঅ্যালোকেট করুন:Return<void> Foo::giveBack(const MemoryBlock& block) { memory_dealer->deallocate(block.offset); ...ডেটা ম্যানিপুলেট করা:
#include <hidlmemory/mapping.h> #include <android/hidl/memory/1.0/IMemory.h> using ::android::hidl::memory::V1_0::IMemory; sp<IMemory> memory = mapMemory(block); uint8_t* data = static_cast<uint8_t*>(static_cast<void*>(memory->getPointer()));কনফিগ
Android.bp:shared_libs: [ "android.hidl.memory@1.0", "android.hidl.memory.block@1.0" "android.hidl.memory.token@1.0", "libhidlbase", "libhidlmemory",আপনার
lockMemoryপ্রয়োজন কিনা তা নির্ধারণ করতে ফ্লো পর্যালোচনা করুন।সাধারণত,
MemoryBlockশেয়ার করাhidl_memoryবজায় রাখতে রেফারেন্স কাউন্ট ব্যবহার করে যা প্রথমবারmmap()করা হয় যখন এর মধ্যে একটিMemoryBlock instances is mapped and ismunmap()-ed when nothing refers to it. To keephidl_memoryalways mapped, you can uselockMemory, a RAII style object that keeps the correspondinghidl_memory` লক লাইফসাইকেল জুড়ে ম্যাপ করা হয়। উদাহরণ:#include <hidlmemory/mapping.h> sp<RefBase> lockMemory(const sp<IMemoryToken> key);
দীর্ঘক্ষণ ব্যবহার
এই বিভাগে MemoryBlock-এর বর্ধিত ব্যবহার সম্পর্কে বিবরণ দেওয়া হয়েছে।
MemoryBlock ম্যানেজ করতে রেফারেন্স কাউন্ট ব্যবহার করা
বেশিরভাগ ক্ষেত্রে, MemoryBlock ব্যবহার করার সবচেয়ে কার্যকর উপায় হল স্পষ্টভাবে
অ্যালোকেট/ডিলিট করা। তবে, জটিল অ্যাপের ক্ষেত্রে রেফারেন্স কাউন্ট ব্যবহার করে
গার্বেজ কালেকশন করা আরও ভালো আইডিয়া হতে পারে। MemoryBlock-এ রেফারেন্স কাউন্ট চালু করতে, আপনি একটি বাইন্ডার অবজেক্টের সাথে MemoryBlock বাইন্ড করতে পারেন, যা রেফারেন্স গণনা করতে এবং গণনা শূন্যে নেমে গেলে MemoryBlock ডিলোক্যাট করতে
সাহায্য করে।
HAL ঘোষণা করুন
HAL ঘোষণা করার সময়, এমন একটি HIDL স্ট্রাক্ট বর্ণনা করুন যাতে একটি MemoryBlock
ইনস্ট্যান্স ও একটি IBase থাকে:
import android.hidl.memory.block@1.0::MemoryBlock;
struct MemoryBlockAllocation {
MemoryBlock block;
IBase refcnt;
};
MemoryBlock-এর পরিবর্তে MemoryBlockAllocation ব্যবহার করুন এবং MemoryBlock ফিরিয়ে দিতে
পদ্ধতিটি সরিয়ে দিন। MemoryBlockAllocation-এর সাহায্যে রেফারেন্স গণনা করে
এটি ডিঅ্যালোকেট করা হয়। উদাহরণ:
interface IFoo {
allocateSome() generates(MemoryBlockAllocation allocation);
};
HAL প্রয়োগ করুন
HAL-এর পরিষেবা সাইড প্রয়োগের উদাহরণ:
class MemoryBlockRefCnt: public virtual IBase {
MemoryBlockRefCnt(uint64_t offset, sp<MemoryDealer> dealer)
: mOffset(offset), mDealer(dealer) {}
~MemoryBlockRefCnt() {
mDealer->deallocate(mOffset);
}
private:
uint64_t mOffset;
sp<MemoryDealer> mDealer;
};
Return<void> Foo::allocateSome(allocateSome_cb _hidl_cb) {
MemoryBlockAllocation allocation;
allocation.block = memory_dealer->allocate(1024);
if(HidlMemoryDealer::isOk(block)){
allocation.refcnt= new MemoryBlockRefCnt(...);
_hidl_cb(allocation);
HAL-এর ক্লায়েন্ট সাইড প্রয়োগের উদাহরণ:
ifoo->allocateSome([&](const MemoryBlockAllocation& allocation){
...
);
মেটাডেটা অ্যাটাচ এবং রিট্রিভ করা
অ্যালোকেট করা MemoryBlock-এর সাথে বাইন্ড করার জন্য কিছু অ্যাপের অতিরিক্ত ডেটা প্রয়োজন।
আপনি দুটি পদ্ধতি ব্যবহার করে মেটাডেটা যোগ করতে ও পেতে পারবেন:
অ্যাপটি যদি ব্লকটির মতোই ঘন ঘন মেটাডেটা অ্যাক্সেস করে, মেটাডেটা যোগ করুন এবং সেগুলি একটি স্ট্রাক্টে পাস করুন। উদাহরণ:
import android.hidl.memory.block@1.0::MemoryBlock; struct MemoryBlockWithMetaData{ MemoryBlock block; MetaDataStruct metaData; };অ্যাপ যদি ব্লকের তুলনায় অনেক কম ঘন ঘন মেটাডেটা অ্যাক্সেস করে, তাহলে ইন্টারফেসের মাধ্যমে প্যাসিভভাবে মেটাডেটা পাস করা আরও বেশি কার্যকর। উদাহরণ:
import android.hidl.memory.block@1.0::MemoryBlock; struct MemoryBlockWithMetaData{ MemoryBlock block; IMetaData metaData; };এরপর,
MemoryDealerব্যবহার করেMemoryBlock-এর সাথে মেটাডেটা বাইন্ড করুন। উদাহরণ:MemoryBlockWithMetaData memory_block; memory_block.block = dealer->allocate(size); if(HidlMemoryDealer::isOk(block)){ memory_block.metaData = new MetaData(...);