Das HIDL MemoryBlock
ist eine abstrakte Ebene, die auf hidl_memory
, HIDL
@1.0::IAllocator
und HIDL @1.0::IMapper
basiert. Es wurde für HIDL-Dienste entwickelt.
die mehrere Speicherblöcke haben,
um sich einen einzelnen Speicher-Heap zu teilen.
Leistungsverbesserungen
Durch die Verwendung von MemoryBlock
in Apps kann die Anzahl der
mmap
/munmap
und Nutzerbereich-Segmentierungsfehler, wodurch die Leistung verbessert wird.
Beispiel:
- Die Verwendung pro
hidl_memory
für jede Pufferzuweisung beträgt durchschnittlich 238 us/1. Zuordnung. - Die Nutzung von
MemoryBlock
und die gemeinsame Nutzung eines einzelnenhidl_memory
führt zu durchschnittlich 2,82 uns/1 Zuordnung.
Architektur
Die HIDL-MemoryBlock
-Architektur umfasst HIDL-Dienste mit mehreren Arbeitsspeichern
die Freigabe eines einzelnen Speicher-Heaps blockieren:
Abbildung 1: HIDL MemoryBlock-Architektur
Normale Nutzung
Dieser Abschnitt enthält ein Beispiel für die Verwendung von MemoryBlock
, indem zuerst die Methode
HAL und implementiert dann den HAL.
HAL deklarieren
Für das folgende IFoo HAL-Beispiel:
import android.hidl.memory.block@1.0::MemoryBlock;
interface IFoo {
getSome() generates(MemoryBlock block);
giveBack(MemoryBlock block);
};
Android.bp
sieht so aus:
hidl_interface {
...
srcs: [
"IFoo.hal",
],
interfaces: [
"android.hidl.memory.block@1.0",
...
};
HAL implementieren
So implementieren Sie das Beispiel-HAL:
Hol dir das
hidl_memory
(weitere Informationen findest du unter 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 }));
Erstellen Sie eine
HidlMemoryDealer
-Instanz mit der übernommenenhidl_memory
:#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);
Weisen Sie
MemoryBlock
zu. Dies ist eine mit HIDL definierte Struktur.Beispiel für
MemoryBlock
:struct MemoryBlock { IMemoryToken token; uint64_t size; uint64_t offset; };
Beispiel für die Verwendung von
MemoryDealer
zum Zuweisen einerMemoryBlock
:#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); ...
Zuweisung von
MemoryBlock
aufheben:Return<void> Foo::giveBack(const MemoryBlock& block) { memory_dealer->deallocate(block.offset); ...
So bearbeiten Sie die Daten:
#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()));
Konfiguration
Android.bp
:shared_libs: [ "android.hidl.memory@1.0", "android.hidl.memory.block@1.0" "android.hidl.memory.token@1.0", "libhidlbase", "libhidlmemory",
Prüfen Sie den Ablauf, um festzustellen, ob Sie
lockMemory
.Normalerweise verwendet
MemoryBlock
die Referenzanzahl, um die geteilten Inhalte aufrechtzuerhalten.hidl_memory
, dasmmap()
-ed-Objekt wird, wenn zum ersten Mal eine seinerMemoryBlock instances is mapped and is
munmap()-ed when nothing refers to it. To keep
hidl_memoryalways mapped, you can use
lockMemory, a RAII style object that keeps the corresponding
hidl_memory`-Funktion innerhalb der Sperre zugeordnet wird Lebenszyklus. Beispiel:#include <hidlmemory/mapping.h> sp<RefBase> lockMemory(const sp<IMemoryToken> key);
Verlängerte Nutzung
Dieser Abschnitt enthält Details zur erweiterten Nutzung von MemoryBlock
.
Referenzanzahl zum Verwalten von MemoryBlock verwenden
In den meisten Situationen ist es am effizientesten, MemoryBlock
zu verwenden,
Zuweisen/Auflösen. In komplizierten Apps mit der Anzahl der Referenzen
für die automatische Speicherbereinigung. Damit die Anzahl der Referenzen
MemoryBlock
können Sie MemoryBlock
mit einem Binderobjekt binden.
Verweise zählen und die Zuweisung von MemoryBlock
aufheben, wenn die Anzahl sinkt
auf null setzen.
HAL deklarieren
Beschreiben Sie beim Deklarieren des HAL eine HIDL-Struktur, die ein MemoryBlock
enthält.
und eine IBase-Instanz:
import android.hidl.memory.block@1.0::MemoryBlock;
struct MemoryBlockAllocation {
MemoryBlock block;
IBase refcnt;
};
Verwenden Sie MemoryBlockAllocation
, um MemoryBlock
zu ersetzen und die Methode zu entfernen
um MemoryBlock
zurückzugeben. Die Freigabe erfolgt durch Referenzzählung.
mit MemoryBlockAllocation
. Beispiel:
interface IFoo {
allocateSome() generates(MemoryBlockAllocation allocation);
};
HAL implementieren
Beispiel für die dienstseitige Implementierung des 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);
Beispiel für die clientseitige Implementierung des HAL:
ifoo->allocateSome([&](const MemoryBlockAllocation& allocation){
...
);
Metadaten anhängen und abrufen
Einige Apps benötigen zusätzliche Daten, um sie an die zugewiesene MemoryBlock
zu binden.
Sie können Metadaten mit zwei Methoden anfügen und abrufen:
Greift die App genauso oft auf die Metadaten zu wie der Block selbst, die Metadaten anhängen und sie alle in einer Struktur übergeben. Beispiel:
import android.hidl.memory.block@1.0::MemoryBlock; struct MemoryBlockWithMetaData{ MemoryBlock block; MetaDataStruct metaData; };
Wenn die App viel seltener auf die Metadaten zugreift als ist es effizienter, die Metadaten passiv mit einem . Beispiel:
import android.hidl.memory.block@1.0::MemoryBlock; struct MemoryBlockWithMetaData{ MemoryBlock block; IMetaData metaData; };
Binden Sie als Nächstes die Metadaten mithilfe von
MemoryDealer
anMemoryBlock
. Beispiel:MemoryBlockWithMetaData memory_block; memory_block.block = dealer->allocate(size); if(HidlMemoryDealer::isOk(block)){ memory_block.metaData = new MetaData(...);