MemoryBlock
HIDL adalah lapisan abstrak yang dibuat di hidl_memory
, HIDL
@1.0::IAllocator
, dan HIDL @1.0::IMapper
. Ini dirancang untuk layanan HIDL
yang memiliki beberapa blok memori untuk berbagi satu heap memori.
Peningkatan performa
Penggunaan MemoryBlock
di aplikasi dapat secara signifikan mengurangi jumlah
mmap
/munmap
dan error segmentasi ruang pengguna, sehingga meningkatkan performa.
Contoh:
- Menggunakan per
hidl_memory
untuk setiap alokasi buffer rata-rata 238 us/1 alokasi. - Menggunakan
MemoryBlock
dan berbagi satuhidl_memory
rata-rata 2,82 us/1 alokasi.
Arsitektur
Arsitektur MemoryBlock
HIDL mencakup layanan HIDL dengan beberapa blok memori
yang berbagi satu heap memori:
Gambar 1. Arsitektur MemoryBlock HIDL
Penggunaan normal
Bagian ini memberikan contoh penggunaan MemoryBlock
dengan mendeklarasikan
HAL terlebih dahulu, lalu menerapkan HAL.
Mendeklarasikan HAL
Untuk contoh IFoo HAL berikut:
import android.hidl.memory.block@1.0::MemoryBlock;
interface IFoo {
getSome() generates(MemoryBlock block);
giveBack(MemoryBlock block);
};
Android.bp
adalah sebagai berikut:
hidl_interface {
...
srcs: [
"IFoo.hal",
],
interfaces: [
"android.hidl.memory.block@1.0",
...
};
Mengimplementasikan HAL
Untuk menerapkan contoh HAL:
Dapatkan
hidl_memory
(untuk mengetahui detailnya, lihat 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 }));
Buat instance
HidlMemoryDealer
denganhidl_memory
yang diperoleh:#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);
Alokasikan
MemoryBlock
, yang merupakan struct yang ditentukan dengan HIDL.Contoh
MemoryBlock
:struct MemoryBlock { IMemoryToken token; uint64_t size; uint64_t offset; };
Contoh penggunaan
MemoryDealer
untuk mengalokasikanMemoryBlock
:#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); ...
Menghapus alokasi
MemoryBlock
:Return<void> Foo::giveBack(const MemoryBlock& block) { memory_dealer->deallocate(block.offset); ...
Memanipulasi data:
#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()));
Konfigurasi
Android.bp
:shared_libs: [ "android.hidl.memory@1.0", "android.hidl.memory.block@1.0" "android.hidl.memory.token@1.0", "libhidlbase", "libhidlmemory",
Tinjau alur untuk menentukan apakah Anda perlu
lockMemory
.Biasanya,
MemoryBlock
menggunakan jumlah referensi untuk mempertahankanhidl_memory
bersama yangmmap()
-ed saat pertama kali salah satuMemoryBlock 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`-nya dipetakan di seluruh siklus proses kunci. Contoh:#include <hidlmemory/mapping.h> sp<RefBase> lockMemory(const sp<IMemoryToken> key);
Penggunaan yang diperpanjang
Bagian ini memberikan detail tentang penggunaan MemoryBlock
yang diperluas.
Menggunakan jumlah referensi untuk mengelola MemoryBlock
Dalam sebagian besar situasi, cara paling efisien untuk menggunakan MemoryBlock
adalah dengan mengalokasikan/mendealokasikan secara eksplisit. Namun, dalam aplikasi yang rumit, menggunakan jumlah referensi
untuk pengumpulan sampah mungkin merupakan ide yang lebih baik. Agar jumlah referensi pada
MemoryBlock
, Anda dapat mengikat MemoryBlock
dengan objek binder, yang membantu
menghitung referensi dan membatalkan alokasi MemoryBlock
saat hitungan berkurang
ke nol.
Mendeklarasikan HAL
Saat mendeklarasikan HAL, jelaskan struct HIDL yang berisi instance
MemoryBlock
dan IBase:
import android.hidl.memory.block@1.0::MemoryBlock;
struct MemoryBlockAllocation {
MemoryBlock block;
IBase refcnt;
};
Gunakan MemoryBlockAllocation
untuk mengganti MemoryBlock
dan hapus metode
untuk menampilkan kembali MemoryBlock
. Ini dide-alokasikan dengan penghitungan referensi
dengan MemoryBlockAllocation
. Contoh:
interface IFoo {
allocateSome() generates(MemoryBlockAllocation allocation);
};
Mengimplementasikan HAL
Contoh penerapan sisi layanan 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);
Contoh penerapan HAL sisi klien:
ifoo->allocateSome([&](const MemoryBlockAllocation& allocation){
...
);
Melampirkan dan mengambil metadata
Beberapa aplikasi memerlukan data tambahan untuk diikat dengan MemoryBlock
yang dialokasikan.
Anda dapat menambahkan dan mengambil metadata menggunakan dua metode:
Jika aplikasi mengakses metadata sesering blok itu sendiri, tambahkan metadata dan teruskan semuanya dalam struct. Contoh:
import android.hidl.memory.block@1.0::MemoryBlock; struct MemoryBlockWithMetaData{ MemoryBlock block; MetaDataStruct metaData; };
Jika aplikasi mengakses metadata jauh lebih jarang daripada blok, akan lebih efisien untuk meneruskan metadata secara pasif dengan antarmuka. Contoh:
import android.hidl.memory.block@1.0::MemoryBlock; struct MemoryBlockWithMetaData{ MemoryBlock block; IMetaData metaData; };
Selanjutnya, ikat metadata dengan
MemoryBlock
menggunakanMemoryDealer
. Contoh:MemoryBlockWithMetaData memory_block; memory_block.block = dealer->allocate(size); if(HidlMemoryDealer::isOk(block)){ memory_block.metaData = new MetaData(...);