HIDL MemoryBlock hidl_memory
, HIDL @1.0::IAllocator
और HIDL @1.0::IMapper
पर निर्मित एक अमूर्त परत है। इसे HIDL सेवाओं के लिए डिज़ाइन किया गया है जिनमें एकल मेमोरी हीप को साझा करने के लिए कई मेमोरी ब्लॉक होते हैं।
कार्य में सुधार
अनुप्रयोगों में मेमोरीब्लॉक का उपयोग mmap
/ munmap
और उपयोगकर्ता स्थान विभाजन दोषों की संख्या को काफी कम कर सकता है, जिससे प्रदर्शन में सुधार हो सकता है। उदाहरण के लिए:
- प्रत्येक बफ़र आवंटन के लिए प्रति
hidl_memory
उपयोग करने पर औसत 238 यूएस/1 आवंटन होता है। -
MemoryBlock
उपयोग करना और एकलhidl_memory
साझा करना औसत 2.82 यूएस/1 आवंटन है।
वास्तुकला
HIDL मेमोरीब्लॉक आर्किटेक्चर में एकल मेमोरी हीप को साझा करने वाले एकाधिक मेमोरी ब्लॉक वाली HIDL सेवाएं शामिल हैं:
चित्र 1. एचआईडीएल मेमोरीब्लॉक आर्किटेक्चर
सामान्य उपयोग
यह अनुभाग पहले एचएएल घोषित करके और फिर एचएएल लागू करके मेमोरीब्लॉक का उपयोग करने का एक उदाहरण प्रदान करता है।
एचएएल की घोषणा
निम्नलिखित उदाहरण के लिए 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 को लागू करने के लिए:
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
आवंटित करें, जो एचआईडीएल के साथ परिभाषित एक संरचना है।उदाहरण
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
के विस्तारित उपयोग के बारे में विवरण प्रदान करता है।
मेमोरीब्लॉक को प्रबंधित करने के लिए संदर्भ गणना का उपयोग करना
अधिकांश स्थितियों में, मेमोरीब्लॉक का उपयोग करने का सबसे प्रभावी तरीका स्पष्ट रूप से आवंटित/डीललोकेट करना है। हालाँकि, जटिल अनुप्रयोगों में कचरा संग्रहण के लिए संदर्भ गणना का उपयोग करना एक बेहतर विचार हो सकता है। मेमोरीब्लॉक पर संदर्भ गणना करने के लिए, आप मेमोरीब्लॉक को बाइंडर ऑब्जेक्ट से बांध सकते हैं, जो संदर्भों को गिनने और गिनती शून्य होने पर मेमोरीब्लॉक को हटाने में मदद करता है।
एचएएल की घोषणा
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);
};
एचएएल का कार्यान्वयन
एचएएल के सेवा पक्ष कार्यान्वयन का उदाहरण:
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; };
इसके बाद, मेमोरी डीलर का उपयोग करके मेटाडेटा को मेमोरीब्लॉक के साथ बाइंड करें। उदाहरण:
MemoryBlockWithMetaData memory_block; memory_block.block = dealer->allocate(size); if(HidlMemoryDealer::isOk(block)){ memory_block.metaData = new MetaData(...);