एचआईडीएल मेमोरीब्लॉक

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 MemoryBlock आर्किटेक्चर में एक से ज़्यादा मेमोरी वाली HIDL सेवाएं शामिल हैं एक मेमोरी हीप को शेयर करने से रोकता है:

एचआईडीएल मेमोरीब्लॉक

पहला डायग्राम. HIDL MemoryBlock आर्किटेक्चर

सामान्य इस्तेमाल

इस सेक्शन में MemoryBlock को इस्तेमाल करने का उदाहरण दिया गया है. HAL फिर 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",
        ...
};

एचएएल को लागू करना

एचएएल के उदाहरण को लागू करने के लिए:

  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()-ed1 है. यह 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 को हटा दें शून्य तक.

एचएएल का एलान करना

एचएएल का एलान करते समय, उस एचआईडीएल के बारे में बताएं जिसमें 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);
};

एचएएल को लागू करना

एचएएल को सेवा के तौर पर लागू करने का उदाहरण:

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);

एचएएल को क्लाइंट साइड पर लागू करने का उदाहरण:

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(...);