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

স্থাপত্য

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

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 করতে হবে কিনা তা নির্ধারণ করতে প্রবাহটি পর্যালোচনা করুন।

    সাধারণত, 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(...);