अगर आपको एआईडीएल से जुड़ी सहायता चाहिए, तो यह भी देखें AIDL के साथ FMQ.
HIDL का रिमोट प्रोसेस कॉल (RPC) इन्फ़्रास्ट्रक्चर, बाइंडर मैकेनिज़्म का इस्तेमाल करता है. इसका मतलब है कि कॉल में ओवरहेड शामिल है, उसके लिए कर्नेल ऑपरेशन की ज़रूरत होती है, और ये ट्रिगर हो सकते हैं शेड्यूलर कार्रवाई. हालांकि, ऐसे मामलों में जहां डेटा के बीच डेटा ट्रांसफ़र किया जाना चाहिए कम ओवरहेड वाली और कर्नेल भागीदारी के बिना प्रोसेस, फ़ास्ट मैसेज क्यू (FMQ) सिस्टम का इस्तेमाल किया गया.
FMQ, पसंदीदा प्रॉपर्टी के साथ मैसेज की सूची बनाता है. अगर आप
MQDescriptorSync
या MQDescriptorUnsync
ऑब्जेक्ट यह हो सकता है
HIDL RPC कॉल पर भेजा गया और इसका इस्तेमाल रिसीव करने की प्रोसेस में
संदेश सूची.
तेज़ मैसेज की सूची सिर्फ़ C++ और डिवाइसों पर काम करती है Android 8.0 और इसके बाद वाला वर्शन होना चाहिए.
Message चेतावनी के टाइप
Android पर दो तरह की क़ीमतें काम करती हैं (जिसे फ़्लेवर कहा जाता है):
- सिंक नहीं की गई सूचियों को ओवरफ़्लो होने की अनुमति होती है. साथ ही, इसमें कई सूचियां हो सकती हैं पाठक; हर पाठक को समय पर डेटा पढ़ना होगा या उसे खोना होगा.
- सिंक की गई सूचियों को ओवरफ़्लो नहीं किया जा सकता है, और सिर्फ़ इन्हें ओवरफ़्लो हो सकता है एक रीडर.
दोनों तरह की सूचियों को अंडरफ़्लो (किसी खाली सूची की मदद से पढ़ने के लिए) की अनुमति नहीं है विफल होता है) और उसका केवल एक लेखक हो सकता है.
सिंक में नहीं है
सिंक नहीं की गई सूची में सिर्फ़ एक राइटर होता है, लेकिन उसकी संख्या एक भी हो सकती है पाठक. सूची में लिखने के लिए एक पोज़िशन है; हालांकि, हर पाठक पहले से ही ट्रैक करने में मदद मिलती है.
सूची में शामिल सभी टेक्स्ट हमेशा तब तक काम करते हैं (ओवरफ़्लो के लिए इसकी जांच नहीं की जाती) जब तक कि वे कॉन्फ़िगर की गई क्यू की क्षमता से ज़्यादा नहीं हैं (लिखकर क्यू की क्षमता तुरंत बंद हो जाती है). हर व्यक्ति के लिए पढ़ने का तरीका अलग हो सकता है हर व्यक्ति के लिए डेटा के हर हिस्से को पढ़ने का इंतज़ार नहीं करती. जब भी नए लेखों को लिखने के लिए जगह की ज़रूरत हो, तो उन्हें सूची से बाहर किया जा सकता है.
पाठक, डेटा के आखिर तक पहुंचने से पहले उसे वापस पाने की ज़िम्मेदारी लेते हैं सूची में है. ऐसा रीड जो उपलब्ध डेटा से ज़्यादा डेटा पढ़ने की कोशिश करता है तुरंत काम नहीं कर पाता (अगर ब्लॉक नहीं किया जाता) या ज़रूरत के मुताबिक डेटा उपलब्ध होने का इंतज़ार करता है (अगर ब्लॉक करना). ऐसा रीड जो हमेशा सूची में क्षमता से ज़्यादा डेटा पढ़ने की कोशिश करता है विफल हो जाता है.
अगर कोई पाठक लेखक से संपर्क नहीं कर पाता है, तो जितना उस पाठक ने लिखा है और अभी तक नहीं पढ़ा है, तो वह सूची की क्षमता से ज़्यादा है. अगली बार पढ़ने पर डेटा नहीं मिलता; इसके बजाय, यह रीडर के पढ़े गए टेक्स्ट को रीसेट कर देता है पोज़िशन को हाल ही में लिखे गए पेज की पोज़िशन के बराबर सेट करता है, तो नतीजे के तौर पर फ़ेल हो जाता है. अगर पढ़ने के लिए उपलब्ध डेटा की जांच ओवरफ़्लो के बाद की जाती है, लेकिन अगली बार पढ़ने से पहले, इसकी जांच की जाती है पढ़ने के लिए उपलब्ध डेटा, सूची में मौजूद क्षमता से ज़्यादा दिखाता है. इससे पता चलता है कि ओवरफ़्लो हुआ. (अगर उपलब्ध डेटा की जांच करने के दौरान सूची ज़्यादा हो जाती है और उस डेटा को पढ़ने का प्रयास करते समय, ओवरफ़्लो का एकमात्र संकेत यह होता है कि पढ़ना विफल रहा.)
सिंक नहीं की गई सूची में मौजूद पाठक, शायद रीसेट न करना चाहें सूची के 'पढ़ें और लिखें' पॉइंटर. इसलिए, डिस्क्रिप्टर रीडर को `resetPointers` के लिए `गलत` आर्ग्युमेंट का इस्तेमाल करना चाहिए पैरामीटर.
सिंक किया गया
सिंक की गई सूची में एक राइटर और एक रीडर है. इसमें एक ही लिखा है स्थिति और एक रीड पोज़िशन. इससे ज़्यादा डेटा लिखना संभव नहीं है सूची में मौजूदा डेटा से ज़्यादा डेटा पढ़ने या इसके लिए जगह है. यह इस बात पर निर्भर करता है कि टेक्स्ट को ब्लॉक करने या ब्लॉक करने वाला फ़ंक्शन, राइट या रीड फ़ंक्शन है या नहीं कॉल किया गया, तो उपलब्ध जगह को पार करने की कोशिश की जाती है या डेटा वापस मिलने में विफल हो जाता है तुरंत या ब्लॉक करें, जब तक कि मनचाहा ऑपरेशन पूरा न हो जाए. ये कोशिशें की गई हैं क्यू में क्षमता से ज़्यादा डेटा पढ़ने या लिखने में हमेशा समस्या आती है.
एफ़एमक्यू सेट अप करें
मैसेज सूची में कई MessageQueue
ऑब्जेक्ट होने चाहिए: एक
को लिखा हो और पढ़ने के लिए एक या ज़्यादा. इसमें कोई अश्लील कॉन्टेंट नहीं है
ऐसा कॉन्फ़िगरेशन जिससे लिखने या पढ़ने के लिए इस्तेमाल किया जाता हो; यह तय करना होता है कि
उपयोगकर्ता को यह पक्का करने के लिए कहा जाएगा कि पढ़ने और लिखने, दोनों के लिए किसी भी ऑब्जेक्ट का इस्तेमाल न किया जाए,
ज़्यादा से ज़्यादा एक लेखक और सिंक की गई सूची के लिए,
रीडर.
पहला MessageQ ऑब्जेक्ट बनाएं
मैसेज सूची को एक ही कॉल से बनाया और कॉन्फ़िगर किया जाता है:
#include <fmq/MessageQueue.h> using android::hardware::kSynchronizedReadWrite; using android::hardware::kUnsynchronizedWrite; using android::hardware::MQDescriptorSync; using android::hardware::MQDescriptorUnsync; using android::hardware::MessageQueue; .... // For a synchronized non-blocking FMQ mFmqSynchronized = new (std::nothrow) MessageQueue<uint16_t, kSynchronizedReadWrite> (kNumElementsInQueue); // For an unsynchronized FMQ that supports blocking mFmqUnsynchronizedBlocking = new (std::nothrow) MessageQueue<uint16_t, kUnsynchronizedWrite> (kNumElementsInQueue, true /* enable blocking operations */);
MessageQueue<T, flavor>(numElements)
शुरू करने वाला एक ऐसा ऑब्जेक्ट बनाता और शुरू करता है जो मैसेज सूची की सुविधा के साथ काम करता है.MessageQueue<T, flavor>(numElements, configureEventFlagWord)
शुरू करने वाला टूल कोई ऑब्जेक्ट बनाता और शुरू करता है जो ब्लॉक करने के साथ मैसेज सूची की सुविधा के साथ काम करती है.flavor
या तोkSynchronizedReadWrite
सिंक नहीं की गई सूची याkUnsynchronizedWrite
सूची.uint16_t
(इस उदाहरण में) कोई भी HIDL से तय किया गया टाइप जो इसमें नेस्ट किए गए बफ़र शामिल नहीं होते हैं (string
याvec
नहीं होते हैं) टाइप), हैंडल या इंटरफ़ेस में दिख सकते हैं.kNumElementsInQueue
, संख्या में सूची का साइज़ दिखाता है एंट्री; यह, शेयर किए गए उस मेमोरी बफ़र का साइज़ तय करता है जिसे बांटा गया है आपका पसंदीदा विकल्प है.
दूसरा Message चेतावनी ऑब्जेक्ट बनाएं
संदेश सूची के दूसरे हिस्से को
पहली तरफ़ से MQDescriptor
ऑब्जेक्ट मिला है. कॉन्टेंट बनाने
प्रोसेस के लिए MQDescriptor
ऑब्जेक्ट, HIDL या AIDL RPC कॉल पर भेजा गया
जो मैसेज सूची का दूसरा सिरा होता है. कॉन्टेंट बनाने
MQDescriptor
में सूची के बारे में जानकारी होती है, जैसे:
- बफ़र को मैप करने और पॉइंटर लिखने के लिए जानकारी.
- रीड पॉइंटर को मैप करने की जानकारी (अगर सूची सिंक की गई है).
- इवेंट फ़्लैग शब्द को मैप करने के लिए जानकारी (अगर सूची ब्लॉक कर रही है).
- ऑब्जेक्ट टाइप (
<T, flavor>
), जिसमें यह शामिल है इसका HIDL-तय टाइप क्यू एलिमेंट और क्यू फ़्लेवर (सिंक किए गए या सिंक नहीं किए गए).
MQDescriptor
ऑब्जेक्ट का इस्तेमाल करके,
MessageQueue
ऑब्जेक्ट:
MessageQueue<T, flavor>::MessageQueue(const MQDescriptor<T, flavor>& Desc, bool resetPointers)
resetPointers
पैरामीटर से पता चलता है कि रीड को रीसेट करना है या नहीं
और इस MessageQueue
ऑब्जेक्ट को बनाते समय 0 पर पोज़िशन लिखें.
सिंक नहीं की गई सूची में, पढ़ने की स्थिति (जो हर एक के लिए स्थानीय होती है)
सिंक नहीं की गई सूची में मौजूद MessageQueue
ऑब्जेक्ट) हमेशा 0 पर सेट रहता है
बनाने के दौरान किया जा सकता है. आम तौर पर, MQDescriptor
इस दौरान शुरू होता है
मैसेज सूची में मौजूद पहला ऑब्जेक्ट बनाने के लिए. शेयर की गई चीज़ों पर ज़्यादा कंट्रोल के लिए
मेमोरी, मैन्युअल रूप से MQDescriptor
को सेट अप किया जा सकता है
(MQDescriptor
की परिभाषा यहां दी गई है
system/libhidl/base/include/hidl/MQDescriptor.h
)
फिर इस सेक्शन में बताए गए तरीके से हर MessageQueue
ऑब्जेक्ट बनाएं.
सूची और इवेंट फ़्लैग ब्लॉक करें
डिफ़ॉल्ट रूप से, सूची में पढ़ने/लिखने को रोकने की सुविधा काम नहीं करती. इसके दो तरह के होते हैं रीड/राइट कॉल को ब्लॉक करने की सुविधा:
- छोटा रूप, जिसमें तीन पैरामीटर (डेटा पॉइंटर, आइटम की संख्या,
टाइम आउट). किसी एक पर व्यक्तिगत पढ़ने/लिखने की कार्रवाइयों पर ब्लॉक करने का समर्थन करता है
सूची. इस फ़ॉर्म का इस्तेमाल करते समय सूची, इवेंट फ़्लैग और बिटमास्क को हैंडल करती है
और मैसेज सूची के पहले ऑब्जेक्ट को
true
के दूसरे पैरामीटर से शुरू किया जाना चाहिए. उदाहरण के लिए:// For an unsynchronized FMQ that supports blocking mFmqUnsynchronizedBlocking = new (std::nothrow) MessageQueue<uint16_t, kUnsynchronizedWrite> (kNumElementsInQueue, true /* enable blocking operations */);
- बड़ा फ़ॉर्म, जिसमें छह पैरामीटर (इवेंट फ़्लैग और बिटमास्क शामिल हैं).
कई क्यू के बीच, शेयर किए गए
EventFlag
ऑब्जेक्ट का इस्तेमाल किया जा सकता है और सूचना बिट मास्क को इस्तेमाल करने की अनुमति देता है. इस मामले में, 'रीड ऐंड राइट' कॉल के लिए, इवेंट फ़्लैग और बिटमास्क दिए जाने चाहिए.
लंबी अवधि के वीडियो के लिए, EventFlag
की वैल्यू
हर readBlocking()
और writeBlocking()
कॉल के लिए. इनमें से एक
सूचियों को किसी इंटरनल इवेंट फ़्लैग के साथ शुरू किया जा सकता है. इसके लिए, यह ज़रूरी है कि
इसका इस्तेमाल करके उस सूची के MessageQueue
ऑब्जेक्ट से एक्सट्रैक्ट किया गया
getEventFlagWord()
और इसका इस्तेमाल, EventFlag
बनाने में किया गया
हर प्रोसेस में मौजूद एक ऑब्जेक्ट की जानकारी देती हैं जिसका इस्तेमाल दूसरे एफ़एमक्यू के साथ किया जा सकता है. इसके अलावा,
EventFlag
ऑब्जेक्ट को किसी भी सही शेयर के साथ शुरू किया जा सकता है
मेमोरी.
आम तौर पर, हर सूची में, ब्लॉक न करने वाले और कम अवधि के सिर्फ़ एक फ़ॉर्मैट का इस्तेमाल किया जाना चाहिए या लंबी अवधि के वीडियो ब्लॉक करना. उन्हें मिक्स करना कोई गड़बड़ी नहीं है, लेकिन सावधान रहें मनचाहा नतीजा पाने के लिए प्रोग्रामिंग ज़रूरी है.
इस 'यादें' को 'सिर्फ़ पढ़ने के लिए' के तौर पर मार्क करें
शेयर की गई 'यादें' में, कॉन्टेंट पढ़ने और उसमें बदलाव करने की अनुमतियां डिफ़ॉल्ट रूप से मौजूद होती हैं. सिंक में नहीं है के लिए
सूची (kUnsynchronizedWrite
), तो हो सकता है कि लेखक सभी के लिए, लिखने की अनुमतियां हटाना चाहे
MQDescriptorUnsync
ऑब्जेक्ट को सौंपे जाने से पहले पाठकों की संख्या में कितनी कमी आती है. इससे पक्का होता है कि
एक सूची में अलग-अलग प्रोसेस नहीं लिख सकतीं. ऐसा इसलिए, क्योंकि हमारा सुझाव है कि बग या ऐप्लिकेशन की खराब परफ़ॉर्मेंस से बचा जा सके
पाठक की प्रोसेस को कैसे पूरा करता है.
अगर लेखक चाहता है कि पाठक सूची को रीसेट करने के लिए,
सूची का रीड साइड बनाने के लिए MQDescriptorUnsync
. इसके बाद, मेमोरी को मार्क नहीं किया जा सकेगा
सिर्फ़ पढ़ने के लिए है. यह `Message चेतावनी` कंस्ट्रक्टर का डिफ़ॉल्ट व्यवहार है. इसलिए, अगर पहले से
इस सूची के मौजूदा उपयोगकर्ता हैं, तो क्यू के साथ सूची बनाने के लिए उनका कोड बदलना होगा
resetPointer=false
.
- लेखक:
MQDescriptor
फ़ाइल डिस्क्रिप्टर के साथashmem_set_prot_region
को कॉल करें और क्षेत्र को केवल पढ़ने के लिए (PROT_READ
) पर सेट किया गया है:int res = ashmem_set_prot_region(mqDesc->handle->data[0], PROT_READ)
- रीडर:
resetPointer=false
( डिफ़ॉल्ट रूप सेtrue
है):mFmq = new (std::nothrow) MessageQueue(mqDesc, false);
Messageक्यू का इस्तेमाल करना
MessageQueue
ऑब्जेक्ट का सार्वजनिक एपीआई यह है:
size_t availableToWrite() // Space available (number of elements). size_t availableToRead() // Number of elements available. size_t getQuantumSize() // Size of type T in bytes. size_t getQuantumCount() // Number of items of type T that fit in the FMQ. bool isValid() // Whether the FMQ is configured correctly. const MQDescriptor<T, flavor>* getDesc() // Return info to send to other process. bool write(const T* data) // Write one T to FMQ; true if successful. bool write(const T* data, size_t count) // Write count T's; no partial writes. bool read(T* data); // read one T from FMQ; true if successful. bool read(T* data, size_t count); // Read count T's; no partial reads. bool writeBlocking(const T* data, size_t count, int64_t timeOutNanos = 0); bool readBlocking(T* data, size_t count, int64_t timeOutNanos = 0); // Allows multiple queues to share a single event flag word std::atomic<uint32_t>* getEventFlagWord(); bool writeBlocking(const T* data, size_t count, uint32_t readNotification, uint32_t writeNotification, int64_t timeOutNanos = 0, android::hardware::EventFlag* evFlag = nullptr); // Blocking write operation for count Ts. bool readBlocking(T* data, size_t count, uint32_t readNotification, uint32_t writeNotification, int64_t timeOutNanos = 0, android::hardware::EventFlag* evFlag = nullptr) // Blocking read operation for count Ts; //APIs to allow zero copy read/write operations bool beginWrite(size_t nMessages, MemTransaction* memTx) const; bool commitWrite(size_t nMessages); bool beginRead(size_t nMessages, MemTransaction* memTx) const; bool commitRead(size_t nMessages);
availableToWrite()
और availableToRead()
का इस्तेमाल किया जा सकता है
का इस्तेमाल करें. इससे तय किया जा सकता है कि एक कार्रवाई से कितना डेटा ट्रांसफ़र हो सकता है. इस
सिंक में नहीं की गई सूची:
availableToWrite()
हमेशा सूची की क्षमता दिखाता है.- हर रीडर की पढ़ने की अपनी पोज़िशन होती है. साथ ही, वह
availableToRead()
. - धीमे पढ़ने वाले के हिसाब से, सूची को ओवरफ़्लो होने की अनुमति होती है;
तो
availableToRead()
का मान इससे बड़ा हो सकता है . ओवरफ़्लो के बाद पहली बार पढ़ी गई और फिर पढ़ने वाले व्यक्ति की पढ़ने की पोज़िशन, मौजूदा लिखने के पॉइंटर के बराबर सेट की जा रही है, ओवरफ़्लो की रिपोर्ट इसके ज़रिए की गई थी या नहींavailableToRead()
.
read()
और write()
तरीके रिटर्न करते हैं
true
अगर अनुरोध किया गया सारा डेटा, यहां से ट्रांसफ़र किया जा सकता था (और किया जा सकता था)
सूची में है. ये तरीके ब्लॉक नहीं किए जाते; वे सफल होते हैं (और वापस लौटते हैं)
true
) या गड़बड़ी का मैसेज (false
) तुरंत वापस नहीं लिया जा सकता.
readBlocking()
और writeBlocking()
तरीके इंतज़ार कर रहे हैं
जब तक कि अनुरोध की गई कार्रवाई पूरी नहीं की जा सकती या जब तक कि वे टाइम आउट नहीं हो जाते (a
timeOutNanos
की वैल्यू 0 होने का मतलब है कि कभी टाइम आउट नहीं होगा).
ब्लॉक करने की कार्रवाइयां, इवेंट फ़्लैग शब्द का इस्तेमाल करके लागू की जाती हैं. डिफ़ॉल्ट रूप से,
हर सूची अपने झंडे का शब्द बनाती है और उसका इस्तेमाल करके,
readBlocking()
और writeBlocking()
. यह उनके लिए संभव है
किसी एक शब्द को शेयर करने के लिए कई सूची बनाई जा सकती हैं, ताकि लिखने पर इंतज़ार किया जा सके या
सूची में मौजूद विकल्पों में से किसी को भी पढ़ सकता है. सूची में इवेंट फ़्लैग शब्द के लिए पॉइंटर
getEventFlagWord()
को कॉल करके मिले और उस पॉइंटर (या किसी भी
का इस्तेमाल एक सही शेयर की गई मेमोरी लोकेशन के लिए किया जा सकता है.
EventFlag
ऑब्जेक्ट को इसके लंबे फ़ॉर्मैट में पास करना है
readBlocking()
और writeBlocking()
किसी अन्य
सूची. readNotification
और writeNotification
पैरामीटर से यह पता चलता है कि रीड सिग्नल के लिए इवेंट फ़्लैग में किन बिट का इस्तेमाल किया जाना चाहिए और
उस सूची पर लिखता है. readNotification
और
writeNotification
32-बिट बिटमास्क हैं.
readBlocking()
, writeNotification
बिट तक इंतज़ार करता है;
अगर वह पैरामीटर 0 है, तो कॉल हमेशा फ़ेल हो जाता है. अगर
readNotification
का मान 0 है, कॉल फ़ेल नहीं होगा, लेकिन
सही तरीके से पढ़ने की सुविधा से, सूचना के बारे में कोई बिट सेट नहीं होगी. सिंक की गई सूची में,
इसका मतलब यह होगा कि संबंधित writeBlocking()
कॉल
स्क्रीन तब तक नहीं खुलती है, जब तक कि इस बिट को कहीं और सेट न किया गया हो. सिंक नहीं की गई सूची में,
writeBlocking()
इंतज़ार नहीं करता (इसे सेट करने के लिए अब भी इसका इस्तेमाल किया जाना चाहिए
सूचना बिट लिखें) और रीड के लिए कोई सेट न करें
सूचना बिट. इसी तरह, writeblocking()
काम नहीं करता अगर
readNotification
0 है और सही तरीके से लिखने पर,
writeNotification
बिट.
एक बार में कई सूची पर इंतज़ार करने के लिए, EventFlag
ऑब्जेक्ट का इस्तेमाल करें
सूचनाओं के बिटमास्क पर इंतज़ार करने के लिए wait()
तरीका. कॉन्टेंट बनाने
wait()
तरीका, उन बिट के साथ स्टेटस शब्द दिखाता है जिनकी वजह से
जागना सेट. इसके बाद इस जानकारी का इस्तेमाल यह पुष्टि करने के लिए किया जाता है कि संबंधित सूची में
मनमुताबिक लेखन/पढ़ें कार्रवाई के लिए काफ़ी जगह या डेटा होना चाहिए और
ब्लॉक नहीं करने वाला write()
/read()
. पोस्ट से जुड़ी कार्रवाई करवाने के लिए
नोटिफ़िकेशन, EventFlag
की
wake()
तरीका. EventFlag
की परिभाषा के लिए
अमूर्त,
system/libfmq/include/fmq/EventFlag.h
.
शून्य कॉपी ऑपरेशन
कॉन्टेंट बनाने
read
/write
/readBlocking
/writeBlocking()
एपीआई, इनपुट/आउटपुट बफ़र में पॉइंटर को आर्ग्युमेंट के तौर पर ले जाते हैं और
memcpy()
, उपयोगकर्ताओं को एक ही
एफ़एमक्यू रिंग बफ़र. परफ़ॉर्मेंस को बेहतर बनाने के लिए, Android 8.0 और उसके बाद के वर्शन में
ऐसे एपीआई जो रिंग बफ़र में पॉइंटर का सीधा ऐक्सेस देते हैं. इन एपीआई की मदद से,
memcpy
कॉल करने की ज़रूरत है.
एफ़एमक्यू से जुड़ी शून्य कॉपी वाली कार्रवाइयों के लिए, नीचे दिए गए सार्वजनिक एपीआई का इस्तेमाल करें:
bool beginWrite(size_t nMessages, MemTransaction* memTx) const; bool commitWrite(size_t nMessages); bool beginRead(size_t nMessages, MemTransaction* memTx) const; bool commitRead(size_t nMessages);
beginWrite
तरीका, एफ़एमक्यू रिंग में बेस पॉइंटर देता है बफ़र. डेटा लिखे जाने के बाद,commitWrite()
का इस्तेमाल करके उसे सेव करें.beginRead
/commitRead
तरीके इसी तरह से काम करते हैं.- इनपुट के तौर पर
beginRead
/Write
तरीके पढ़े/लिखे जाने वाले संदेशों की संख्या और एक बूलियन प्राप्त होता है जो यह बताता है कि पढ़ना/लिखना संभव है. अगर पढ़ा या लिखा जा सकता है, तोmemTx
स्ट्रक्चर, बेस पॉइंटर से अपने-आप भर जाता है, जिसका इस्तेमाल डायरेक्ट पॉइंटर के लिए किया जा सकता है रिंग बफ़र की शेयर की गई मेमोरी का ऐक्सेस. MemRegion
स्ट्रक्चर में मेमोरी के ब्लॉक के बारे में जानकारी होती है, इसमें बेस पॉइंटर (मेमोरी ब्लॉक का बेस पता) और इसकी लंबाई शामिल हैT
के पद (HIDL-तय के हिसाब से मेमोरी ब्लॉक की लंबाई संदेश सूची का प्रकार).MemTransaction
स्ट्रक्चर में दोMemRegion
हैं स्ट्रक्ट,first
औरsecond
रीड या राइट के रूप में रिंग बफ़र को सूची की शुरुआत तक रैप करना पड़ सकता है. यह इसका मतलब यह होगा कि FMQ में डेटा पढ़ने/लिखने के लिए दो बेस पॉइंटर की ज़रूरत होगी रिंग बफ़र.
MemRegion
स्ट्रक्चर से बेस का पता और उसकी लंबाई का पता लगाने के लिए:
T* getAddress(); // gets the base address size_t getLength(); // gets the length of the memory region in terms of T size_t getLengthInBytes(); // gets the length of the memory region in bytes
इसमें पहले और दूसरे MemRegion
के रेफ़रंस पाने के लिए
MemTransaction
ऑब्जेक्ट:
const MemRegion& getFirstRegion(); // get a reference to the first MemRegion const MemRegion& getSecondRegion(); // get a reference to the second MemRegion
शून्य कॉपी एपीआई का इस्तेमाल करके एफ़एमक्यू पर लिखने का उदाहरण:
MessageQueueSync::MemTransaction tx; if (mQueue->beginRead(dataLen, &tx)) { auto first = tx.getFirstRegion(); auto second = tx.getSecondRegion(); foo(first.getAddress(), first.getLength()); // method that performs the data write foo(second.getAddress(), second.getLength()); // method that performs the data write if(commitWrite(dataLen) == false) { // report error } } else { // report error }
नीचे दिए गए हेल्पर तरीके भी MemTransaction
का हिस्सा हैं:
T* getSlot(size_t idx);
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
इसके अंदर स्लॉटidx
पर पॉइंटर लौटाता हैMemRegions
जो इसMemTransaction
का हिस्सा हैं ऑब्जेक्ट है. अगरMemTransaction
ऑब्जेक्ट, मेमोरी को दिखा रहा है T प्रकार के N आइटम पढ़ने/लिखने के लिए क्षेत्र, फिर इसकी मान्य श्रेणीidx
, 0 और N-1 के बीच है.bool copyTo(const T* data, size_t startIdx, size_t nMessages = 1);
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
मेमोरी की जगहों में T टाइप केnMessages
आइटम लिखेंstartIdx
इंडेक्स से शुरू करते हुए, ऑब्जेक्ट के ज़रिए बताया गया. यह तरीकाmemcpy()
का इस्तेमाल करता है. हालांकि, इसे शून्य कॉपी के लिए इस्तेमाल नहीं किया जाना चाहिए कार्रवाई. अगरMemTransaction
ऑब्जेक्ट, T प्रकार के N आइटम पढ़ें/लिखें, फिरidx
की मान्य श्रेणी यह होगी वैल्यू 0 और N-1 के बीच होनी चाहिए.bool copyFrom(T* data, size_t startIdx, size_t nMessages = 1);
अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
T प्रकार केnMessages
आइटम पढ़ने के लिए सहायक विधि ऑब्जेक्ट के हिसाब से,startIdx
से शुरू होने वाले मेमोरी के क्षेत्र. यह यह तरीकाmemcpy()
का इस्तेमाल करता है. इसे शून्य कॉपी के लिए इस्तेमाल नहीं किया जाना चाहिए कार्रवाई.
HIDL पर सूची भेजें
कॉन्टेंट बनाने का तरीका:
- ऊपर बताए गए तरीके से, मैसेज सूची के लिए ऑब्जेक्ट बनाएं.
- पुष्टि करें कि ऑब्जेक्ट
isValid()
के साथ मान्य है. - यदि आप
EventFlag
की लंबी अवधिreadBlocking()
/writeBlocking()
है, तो आप इवेंट फ़्लैग पॉइंटर (getEventFlagWord()
का इस्तेमाल करके)MessageQueue
ऑब्जेक्ट जिसे फ़्लैग बनाने के लिए शुरू किया गया था और ज़रूरीEventFlag
ऑब्जेक्ट बनाने के लिए, उस फ़्लैग का इस्तेमाल करें. - पाने के लिए
MessageQueue
getDesc()
तरीके का इस्तेमाल करें डिस्क्रिप्टर ऑब्जेक्ट. .hal
फ़ाइल में, तरीके कोfmq_sync
याfmq_unsync
जहांT
, सही HIDL-परिभाषित प्रकार होना चाहिए. इसका इस्तेमाल करके ऑब्जेक्ट को वापस भेजें पाने की प्रोसेस मेंgetDesc()
.
दाईं ओर:
MessageQueue
ऑब्जेक्ट बनाने के लिए, डिस्क्रिप्टर ऑब्जेक्ट का इस्तेमाल करें. होना एक ही क्यू फ़्लेवर और डेटा टाइप का इस्तेमाल करें. ऐसा न करने पर टेंप्लेट कंपाइल करें.- अगर आपने कोई इवेंट फ़्लैग निकाला है, तो उससे जुड़े इवेंट फ़्लैग से फ़्लैग निकालें
MessageQueue
ऑब्जेक्ट, पाने की प्रोसेस में है. - डेटा ट्रांसफ़र करने के लिए,
MessageQueue
ऑब्जेक्ट का इस्तेमाल करें.