HIDL মেমরি ব্লক

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 বরাদ্দ।

স্থাপত্য

এইচআইডিএল মেমরিব্লক আর্কিটেকচারে একাধিক মেমরি ব্লকের সাথে একটি একক মেমরি হিপ শেয়ার করে এইচআইডিএল পরিষেবা অন্তর্ভুক্ত রয়েছে:

HIDL মেমরি ব্লক

চিত্র 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 বাস্তবায়ন করতে:

  1. 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
      }));
    
  2. অর্জিত 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);
    
  3. 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);
        ...
    
  4. MemoryBlock ডিলোকেট করুন:

    Return<void> Foo::giveBack(const MemoryBlock& block) {
        memory_dealer->deallocate(block.offset);
    ...
    
  5. ডেটা ম্যানিপুলেট করুন:

    #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()));
    
  6. Android.bp কনফিগার করুন:

    shared_libs: [
            "android.hidl.memory@1.0",
    
            "android.hidl.memory.block@1.0"
    
            "android.hidl.memory.token@1.0",
            "libhidlbase",
            "libhidlmemory",
    
  7. আপনার 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(...);