HIDL MemoryBlock adalah lapisan abstrak yang dibuat di hidl_memory, HIDL
@1.0::IAllocator, dan HIDL @1.0::IMapper. Layanan ini dirancang untuk HIDL yang memiliki beberapa blok memori untuk berbagi heap memori tunggal.
Peningkatan performa
Menggunakan MemoryBlock di aplikasi dapat mengurangi jumlah mmap/munmap dan kesalahan segmentasi ruang pengguna secara signifikan, sehingga meningkatkan performa.
Contoh:
- Menggunakan per
hidl_memoryuntuk setiap alokasi buffer rata-rata 238 us/1 alokasi. - Menggunakan
MemoryBlockdan berbagihidl_memorytunggal rata-rata 2,82 us/1 alokasi.
Arsitektur
Arsitektur MemoryBlock HIDL mencakup layanan HIDL dengan beberapa blok memori yang berbagi heap memori tunggal:
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",
...
};
Menerapkan HAL
Untuk menerapkan HAL contoh:
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
HidlMemoryDealerdenganhidl_memoryyang 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
MemoryDealeruntuk 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); ...Batalkan alokasi
MemoryBlock:Return<void> Foo::giveBack(const MemoryBlock& block) { memory_dealer->deallocate(block.offset); ...Manipulasi 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,
MemoryBlockmenggunakan jumlah referensi untuk mempertahankanhidl_memorybersama yang merupakanmmap()saat pertama kali salah satu instanceMemoryBlock instances is mapped and isdipetakan dan-ed when nothing refers to it. To keepsaat tidak ada yang merujuknya. Untuk memastikanalways mapped, you can useselalu dipetakan, Anda dapat menggunakan, a RAII style object that keeps the corresponding, objek gaya RAII yang membuat yang sesuai dipetakan di seluruh siklus proses . Contoh:#include <hidlmemory/mapping.h> sp<RefBase> lockMemory(const sp<IMemoryToken> key);
Penggunaan yang diperluas
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/membatalkan alokasi secara eksplisit. Namun, di aplikasi yang rumit, menggunakan jumlah referensi untuk pengumpulan sampah mungkin merupakan ide yang lebih baik. Untuk memiliki jumlah referensi di MemoryBlock, Anda dapat mengikat MemoryBlock dengan objek binder, yang membantu menghitung referensi dan membatalkan alokasi MemoryBlock saat jumlahnya berkurang menjadi 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 menghapus metode
untuk memberikan kembali MemoryBlock. Alokasinya dibatalkan dengan penghitungan referensi dengan MemoryBlockAllocation. Contoh:
interface IFoo {
allocateSome() generates(MemoryBlockAllocation allocation);
};
Menerapkan 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 sisi klien HAL:
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
MemoryBlockmenggunakanMemoryDealer. Contoh:MemoryBlockWithMetaData memory_block; memory_block.block = dealer->allocate(size); if(HidlMemoryDealer::isOk(block)){ memory_block.metaData = new MetaData(...);