HIDL MemoryBlock
; hidl_memory
, HIDL
@1.0::IAllocator
ve HIDL @1.0::IMapper
üzerinde oluşturulmuş soyut bir katmandır. HIDL hizmetleri için tasarlanmıştır
tek bir bellek yığınını paylaşacak birden fazla bellek bloğuna sahip olmalıdır.
Performans iyileştirmeleri
Uygulamalarda MemoryBlock
kullanmak,
mmap
/munmap
ve kullanıcı alanı segmentasyonu hataları nedeniyle performans artar.
Örnek:
- Her tampon payı için
hidl_memory
başına kullanım ortalaması 238 ABD/1 tahsis etme anlamına gelir. MemoryBlock
kullanımı ve tek birhidl_memory
paylaşımı ortalama 2,82 ABD doları/1 tahsis etme anlamına gelir.
Mimari
HIDL MemoryBlock
mimarisi, birden çok belleğe sahip HIDL hizmetlerini içerir.
tek bir bellek yığınını paylaşan bloklar:
Şekil 1. HIDL MemoryBlock mimarisi
Normal kullanım
Bu bölümde, önce şunu beyan ederek MemoryBlock
kullanımına bir örnek verilmiştir:
HAL, ardından HAL'yi uygulama.
HAL beyanı
Aşağıdaki IFoo HAL örneği için:
import android.hidl.memory.block@1.0::MemoryBlock;
interface IFoo {
getSome() generates(MemoryBlock block);
giveBack(MemoryBlock block);
};
Android.bp
aşağıdaki gibidir:
hidl_interface {
...
srcs: [
"IFoo.hal",
],
interfaces: [
"android.hidl.memory.block@1.0",
...
};
HAL'yi uygulama
Örnek HAL'yi uygulamak için:
hidl_memory
belgesini edinin (ayrıntılar için HIDL'ye bakın) C++) kullanabilirsiniz.#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 }));
Edinilen
hidl_memory
ile birHidlMemoryDealer
örneği oluşturun:#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);
HIDL ile tanımlanan bir struct olan
MemoryBlock
ayırın.Örnek
MemoryBlock
:struct MemoryBlock { IMemoryToken token; uint64_t size; uint64_t offset; };
MemoryBlock
ayırmak içinMemoryDealer
öğesinin kullanıldığı örnek:#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
bayisi:Return<void> Foo::giveBack(const MemoryBlock& block) { memory_dealer->deallocate(block.offset); ...
Verileri işleme:
#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
Yapılandırması:shared_libs: [ "android.hidl.memory@1.0", "android.hidl.memory.block@1.0" "android.hidl.memory.token@1.0", "libhidlbase", "libhidlmemory",
lockMemory
işlemini yapmanız gerekip gerekmediğini belirlemek için akışı inceleyin.Normalde
MemoryBlock
, paylaşılan veri miktarını korumak için referans sayısını kullanırhidl_memory
, kilit boyuncaMemoryBlock 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" parametresinden ilk kez eşlendiğindemmap()
-edildi yaşam döngüsü boyunca geçerlidir. Örnek:#include <hidlmemory/mapping.h> sp<RefBase> lockMemory(const sp<IMemoryToken> key);
Uzun süreli kullanım
Bu bölümde, MemoryBlock
ürününün genişletilmiş kullanımıyla ilgili ayrıntılar yer almaktadır.
MemoryBlock'u yönetmek için referans sayısını kullanma
Çoğu durumda, MemoryBlock
kullanmanın en etkili yolu
tahsis etme anlamına gelir. Ancak, referans sayısı kullanan karmaşık uygulamalarda
düşünmesi daha iyi bir fikir olabilir. Referans sayısının açık olması için
MemoryBlock
bir bağlayıcı nesneyle MemoryBlock
bağlayabilirsiniz. Bu, şunları yapmanıza yardımcı olur:
referansları say ve sayı azaldığında MemoryBlock
öğesini ayır
sıfıra eşittir.
HAL beyanı
HAL belirtirken, MemoryBlock
içeren bir HIDL yapısı açıklayın
örnek ve bir IBase:
import android.hidl.memory.block@1.0::MemoryBlock;
struct MemoryBlockAllocation {
MemoryBlock block;
IBase refcnt;
};
MemoryBlock
yöntemini değiştirmek ve yöntemi kaldırmak için MemoryBlockAllocation
kullanın
MemoryBlock
olarak bağışta bulunduk. Referans sayımına göre ayrılır
MemoryBlockAllocation
ile birlikte. Örnek:
interface IFoo {
allocateSome() generates(MemoryBlockAllocation allocation);
};
HAL'yi uygulama
HAL'nin hizmet tarafı uygulamasına örnek:
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);
HAL'nin istemci tarafı uygulaması örneği:
ifoo->allocateSome([&](const MemoryBlockAllocation& allocation){
...
);
Meta veri ekleme ve alma
Bazı uygulamalar, ayrılan MemoryBlock
ile bağlantı kurmak için ek verilere ihtiyaç duyar.
Meta verileri iki yöntem kullanarak ekleyebilir ve alabilirsiniz:
Uygulama, meta verilere engellemenin kendisi kadar sık erişiyorsa meta verileri ekleyip tümünü bir struct'ta iletebilirim. Örnek:
import android.hidl.memory.block@1.0::MemoryBlock; struct MemoryBlockWithMetaData{ MemoryBlock block; MetaDataStruct metaData; };
Uygulama, meta verilere meta verileri pasif bir şekilde iletmek yerine bir kullanır. Örnek:
import android.hidl.memory.block@1.0::MemoryBlock; struct MemoryBlockWithMetaData{ MemoryBlock block; IMetaData metaData; };
Daha sonra,
MemoryDealer
kullanarak meta verileriMemoryBlock
ile bağlayın. Örnek:MemoryBlockWithMetaData memory_block; memory_block.block = dealer->allocate(size); if(HidlMemoryDealer::isOk(block)){ memory_block.metaData = new MetaData(...);