Add a parameter to allow EventFlag configuration.

Add a parameter to the default MQDescriptor constructor
to allow for the allocation of memory for an EventFlag word.

Bug: 31223612 33295104
Test: FMQ unit tests.

Change-Id: I1087a10bed4f4f02d1a4da5fcd80121c35d18575
diff --git a/base/include/hidl/MQDescriptor.h b/base/include/hidl/MQDescriptor.h
index ebd0911..0bffa75 100644
--- a/base/include/hidl/MQDescriptor.h
+++ b/base/include/hidl/MQDescriptor.h
@@ -56,7 +56,7 @@
             native_handle_t* nHandle, size_t size);
 
     MQDescriptor(size_t bufferSize, native_handle_t* nHandle,
-                 size_t messageSize);
+                 size_t messageSize, bool configureEventFlag = false);
 
     ~MQDescriptor();
 
@@ -92,12 +92,20 @@
 
     static const size_t kOffsetOfGrantors;
     static const size_t kOffsetOfHandle;
+    enum GrantorType : int { READPTRPOS = 0, WRITEPTRPOS, DATAPTRPOS, EVFLAGWORDPOS };
+
     /*
-     * There should atleast be GrantorDescriptors for the read counter, write
-     * counter and data buffer.
+     * There should at least be GrantorDescriptors for the read counter, write
+     * counter and data buffer. A GrantorDescriptor for an EventFlag word is
+     * not required if there is no need for blocking FMQ operations.
      */
-    static constexpr int32_t kMinGrantorCount = 3;
-    enum GrantorType : int { READPTRPOS = 0, WRITEPTRPOS, DATAPTRPOS };
+    static constexpr int32_t kMinGrantorCount = DATAPTRPOS + 1;
+
+    /*
+     * Minimum number of GrantorDescriptors required if EventFlag support is
+     * needed for blocking FMQ operations.
+     */
+    static constexpr int32_t kMinGrantorCountForEvFlagSupport = EVFLAGWORDPOS + 1;
 private:
     ::android::hardware::hidl_vec<GrantorDescriptor> mGrantors;
     ::android::hardware::details::hidl_pointer<native_handle_t> mHandle;
@@ -139,29 +147,36 @@
 
 template<MQFlavor flavor>
 MQDescriptor<flavor>::MQDescriptor(size_t bufferSize, native_handle_t *nHandle,
-                           size_t messageSize)
+                                   size_t messageSize, bool configureEventFlag)
     : mHandle(nHandle), mQuantum(messageSize), mFlags(flavor) {
-    mGrantors.resize(kMinGrantorCount);
+    /*
+     * If configureEventFlag is true, allocate an additional spot in mGrantor
+     * for containing the fd and offset for mmapping the EventFlag word.
+     */
+    mGrantors.resize(configureEventFlag? kMinGrantorCountForEvFlagSupport : kMinGrantorCount);
+
+    size_t memSize[] = {
+        sizeof(RingBufferPosition),  /* memory to be allocated for read pointer counter */
+        sizeof(RingBufferPosition),  /* memory to be allocated for write pointer counter */
+        bufferSize,                  /* memory to be allocated for data buffer */
+        sizeof(std::atomic<uint32_t>)/* memory to be allocated for EventFlag word */
+    };
+
     /*
      * Create a default grantor descriptor for read, write pointers and
      * the data buffer. fdIndex parameter is set to 0 by default and
      * the offset for each grantor is contiguous.
      */
-    mGrantors[READPTRPOS] = {
-        0 /* grantor flags */, 0 /* fdIndex */, 0 /* offset */,
-        sizeof(RingBufferPosition) /* extent */
-    };
-
-    mGrantors[WRITEPTRPOS] = {
-        0 /* grantor flags */,
-        0 /* fdIndex */,
-        sizeof(RingBufferPosition) /* offset */,
-        sizeof(RingBufferPosition) /* extent */
-    };
-    mGrantors[DATAPTRPOS] = {
-        0 /* grantor flags */, 0 /* fdIndex */,
-        2 * sizeof(RingBufferPosition) /* offset */, bufferSize /* extent */
-    };
+    for (size_t grantorPos = 0, offset = 0;
+         grantorPos < mGrantors.size();
+         offset += memSize[grantorPos++]) {
+        mGrantors[grantorPos] = {
+            0 /* grantor flags */,
+            0 /* fdIndex */,
+            static_cast<uint32_t>(offset),
+            memSize[grantorPos]
+        };
+    }
 }
 
 template<MQFlavor flavor>