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 বরাদ্দ।
স্থাপত্য
এইচআইডিএল MemoryBlock
আর্কিটেকচারে একাধিক মেমরি ব্লকের সাথে একটি একক মেমরি হিপ শেয়ার করে এইচআইডিএল পরিষেবা অন্তর্ভুক্ত রয়েছে:
চিত্র 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
করতে হবে কিনা তা নির্ধারণ করতে প্রবাহটি পর্যালোচনা করুন।সাধারণত,
MemoryBlock
শেয়ার করাhidl_memory
বজায় রাখার জন্য রেফারেন্স গণনা ব্যবহার করে যাmmap()
-ed প্রথমবার এরMemoryBlock instances is mapped and is
munmap()-ed when nothing refers to it. To keep
hidl_memory সবসময় ম্যাপ করা-ed when nothing refers to it. To keep
always mapped, you can use
, a RAII style object that keeps the corresponding
। উদাহরণ:#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; };
এর পরে,
MemoryDealer
ব্যবহার করেMemoryBlock
এর সাথে মেটাডেটা আবদ্ধ করুন। উদাহরণ:MemoryBlockWithMetaData memory_block; memory_block.block = dealer->allocate(size); if(HidlMemoryDealer::isOk(block)){ memory_block.metaData = new MetaData(...);