HIDL MemoryBlock হল একটি বিমূর্ত স্তর যা hidl_memory
, HIDL @1.0::IAllocator
এবং HIDL @1.0::IMapper
এর উপর নির্মিত। এটি HIDL পরিষেবাগুলির জন্য ডিজাইন করা হয়েছে যেখানে একাধিক মেমরি ব্লক রয়েছে যাতে একটি একক মেমরি হিপ শেয়ার করা যায়।
কর্মক্ষমতা উন্নতি
অ্যাপ্লিকেশনগুলিতে MemoryBlock ব্যবহার করে উল্লেখযোগ্যভাবে mmap
/ munmap
এবং ব্যবহারকারীর স্থান বিভাজন ত্রুটির সংখ্যা কমাতে পারে, এইভাবে কর্মক্ষমতা উন্নত হয়। উদাহরণ স্বরূপ:
- প্রতিটি বাফার বরাদ্দের জন্য প্রতি
hidl_memory
ব্যবহার করে গড় 238 us/1 বরাদ্দ। -
MemoryBlock
ব্যবহার করা এবং একটি এককhidl_memory
শেয়ার করা গড় 2.82 us/1 বরাদ্দ।
স্থাপত্য
এইচআইডিএল মেমরিব্লক আর্কিটেকচারে একাধিক মেমরি ব্লকের সাথে একটি একক মেমরি হিপ শেয়ার করে এইচআইডিএল পরিষেবা অন্তর্ভুক্ত রয়েছে:
চিত্র 1. 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
করতে হবে কিনা তা নির্ধারণ করতে প্রবাহটি পর্যালোচনা করুন।সাধারণত, মেমরিব্লক শেয়ার করা
hidl_memory
বজায় রাখার জন্য রেফারেন্স কাউন্ট ব্যবহার করে যাmmap()
-ed প্রথমবার এরMemoryBlock
একটি ম্যাপ করা হয় এবংmunmap()
-ed হয় যখন কিছুই উল্লেখ করে না।hidl_memory
সর্বদা ম্যাপ করে রাখতে, আপনিlockMemory
ব্যবহার করতে পারেন, একটি RAII স্টাইলের অবজেক্ট যা লক লাইফ সাইকেল জুড়ে সংশ্লিষ্টhidl_memory
ম্যাপ করে রাখে। উদাহরণ:#include <hidlmemory/mapping.h> sp<RefBase> lockMemory(const sp<IMemoryToken> key);
বর্ধিত ব্যবহার
এই বিভাগটি 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; };
এর পরে, মেমরি ডিলার ব্যবহার করে মেমোরিব্লকের সাথে মেটাডেটা আবদ্ধ করুন। উদাহরণ:
MemoryBlockWithMetaData memory_block; memory_block.block = dealer->allocate(size); if(HidlMemoryDealer::isOk(block)){ memory_block.metaData = new MetaData(...);