| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2016 The Android Open Source Project | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
|  | 16 |  | 
|  | 17 | #ifndef _FMSGQ_DESCRIPTOR_H | 
|  | 18 | #define _FMSGQ_DESCRIPTOR_H | 
|  | 19 |  | 
|  | 20 | #include <android-base/macros.h> | 
|  | 21 | #include <cutils/native_handle.h> | 
|  | 22 | #include <hidl/HidlSupport.h> | 
| Hridya Valsaraju | 4fe70f0 | 2016-09-20 21:02:51 -0700 | [diff] [blame] | 23 | #include <utils/NativeHandle.h> | 
| Hridya Valsaraju | 5d148b3 | 2017-01-10 14:38:42 -0800 | [diff] [blame] | 24 | #include <utils/Log.h> | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 25 |  | 
|  | 26 | namespace android { | 
|  | 27 | namespace hardware { | 
|  | 28 |  | 
| Hridya Valsaraju | 62bb7a0 | 2016-09-23 10:44:04 -0700 | [diff] [blame] | 29 | typedef uint64_t RingBufferPosition; | 
|  | 30 |  | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 31 | struct GrantorDescriptor { | 
| Hridya Valsaraju | 45eb91d | 2017-01-12 13:20:35 -0800 | [diff] [blame^] | 32 | uint32_t flags __attribute__ ((aligned(4))); | 
|  | 33 | uint32_t fdIndex __attribute__ ((aligned(4))); | 
|  | 34 | uint32_t offset __attribute__ ((aligned(4))); | 
|  | 35 | uint64_t extent __attribute__ ((aligned(8))); | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 36 | }; | 
|  | 37 |  | 
| Hridya Valsaraju | 45eb91d | 2017-01-12 13:20:35 -0800 | [diff] [blame^] | 38 | static_assert(offsetof(GrantorDescriptor, flags) == 0, "wrong offset"); | 
|  | 39 | static_assert(offsetof(GrantorDescriptor, fdIndex) == 4, "wrong offset"); | 
|  | 40 | static_assert(offsetof(GrantorDescriptor, offset) == 8, "wrong offset"); | 
|  | 41 | static_assert(offsetof(GrantorDescriptor, extent) == 16, "wrong offset"); | 
|  | 42 | static_assert(sizeof(GrantorDescriptor) == 24, "wrong size"); | 
|  | 43 | static_assert(__alignof(GrantorDescriptor) == 8, "wrong alignment"); | 
|  | 44 |  | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 45 | enum MQFlavor : uint32_t { | 
|  | 46 | /* | 
|  | 47 | * kSynchronizedReadWrite represents the wait-free synchronized flavor of the | 
|  | 48 | * FMQ. It is intended to be have a single reader and single writer. | 
|  | 49 | * Attempts to overflow/underflow returns a failure. | 
|  | 50 | */ | 
| Hridya Valsaraju | 5657578 | 2016-10-13 21:44:55 -0700 | [diff] [blame] | 51 | kSynchronizedReadWrite = 0x01, | 
|  | 52 | /* | 
|  | 53 | * kUnsynchronizedWrite represents the flavor of FMQ where writes always | 
|  | 54 | * succeed. This flavor allows one writer and many readers. A read operation | 
|  | 55 | * can detect an overwrite and reset the read counter. | 
|  | 56 | */ | 
|  | 57 | kUnsynchronizedWrite = 0x02 | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 58 | }; | 
|  | 59 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 60 | template <typename T, MQFlavor flavor> | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 61 | struct MQDescriptor { | 
|  | 62 | MQDescriptor( | 
|  | 63 | const std::vector<GrantorDescriptor>& grantors, | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 64 | native_handle_t* nHandle, size_t size); | 
| Hridya Valsaraju | 62bb7a0 | 2016-09-23 10:44:04 -0700 | [diff] [blame] | 65 |  | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 66 | MQDescriptor(size_t bufferSize, native_handle_t* nHandle, | 
| Hridya Valsaraju | 9ec5730 | 2016-12-14 09:00:31 -0800 | [diff] [blame] | 67 | size_t messageSize, bool configureEventFlag = false); | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 68 |  | 
| Hridya Valsaraju | 0e326a0 | 2016-12-21 10:52:29 -0800 | [diff] [blame] | 69 | MQDescriptor(); | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 70 | ~MQDescriptor(); | 
|  | 71 |  | 
|  | 72 | explicit MQDescriptor(const MQDescriptor &other); | 
|  | 73 | MQDescriptor &operator=(const MQDescriptor &other) = delete; | 
|  | 74 |  | 
|  | 75 | size_t getSize() const; | 
|  | 76 |  | 
|  | 77 | size_t getQuantum() const; | 
|  | 78 |  | 
|  | 79 | int32_t getFlags() const; | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 80 |  | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 81 | bool isHandleValid() const { return mHandle != nullptr; } | 
|  | 82 | size_t countGrantors() const { return mGrantors.size(); } | 
| Hridya Valsaraju | 4fe70f0 | 2016-09-20 21:02:51 -0700 | [diff] [blame] | 83 | std::vector<GrantorDescriptor> getGrantors() const; | 
|  | 84 | const sp<NativeHandle> getNativeHandle() const; | 
| Yifan Hong | 089ae13 | 2016-11-11 11:32:52 -0800 | [diff] [blame] | 85 |  | 
|  | 86 | inline const ::android::hardware::hidl_vec<GrantorDescriptor> &grantors() const { | 
|  | 87 | return mGrantors; | 
|  | 88 | } | 
|  | 89 |  | 
|  | 90 | inline ::android::hardware::hidl_vec<GrantorDescriptor> &grantors() { | 
|  | 91 | return mGrantors; | 
|  | 92 | } | 
|  | 93 |  | 
|  | 94 | inline const ::native_handle_t *handle() const { | 
|  | 95 | return mHandle; | 
|  | 96 | } | 
|  | 97 |  | 
|  | 98 | inline ::native_handle_t *handle() { | 
|  | 99 | return mHandle; | 
|  | 100 | } | 
|  | 101 |  | 
|  | 102 | static const size_t kOffsetOfGrantors; | 
|  | 103 | static const size_t kOffsetOfHandle; | 
| Hridya Valsaraju | 9ec5730 | 2016-12-14 09:00:31 -0800 | [diff] [blame] | 104 | enum GrantorType : int { READPTRPOS = 0, WRITEPTRPOS, DATAPTRPOS, EVFLAGWORDPOS }; | 
|  | 105 |  | 
| Hridya Valsaraju | 62bb7a0 | 2016-09-23 10:44:04 -0700 | [diff] [blame] | 106 | /* | 
| Hridya Valsaraju | 9ec5730 | 2016-12-14 09:00:31 -0800 | [diff] [blame] | 107 | * There should at least be GrantorDescriptors for the read counter, write | 
|  | 108 | * counter and data buffer. A GrantorDescriptor for an EventFlag word is | 
|  | 109 | * not required if there is no need for blocking FMQ operations. | 
| Hridya Valsaraju | 62bb7a0 | 2016-09-23 10:44:04 -0700 | [diff] [blame] | 110 | */ | 
| Hridya Valsaraju | 9ec5730 | 2016-12-14 09:00:31 -0800 | [diff] [blame] | 111 | static constexpr int32_t kMinGrantorCount = DATAPTRPOS + 1; | 
|  | 112 |  | 
|  | 113 | /* | 
|  | 114 | * Minimum number of GrantorDescriptors required if EventFlag support is | 
|  | 115 | * needed for blocking FMQ operations. | 
|  | 116 | */ | 
|  | 117 | static constexpr int32_t kMinGrantorCountForEvFlagSupport = EVFLAGWORDPOS + 1; | 
| Hridya Valsaraju | 5d148b3 | 2017-01-10 14:38:42 -0800 | [diff] [blame] | 118 |  | 
|  | 119 | //TODO(b/34160777) Identify a better solution that supports remoting. | 
|  | 120 | static inline size_t alignToWordBoundary(size_t length) { | 
|  | 121 | constexpr size_t kAlignmentSize = 64; | 
|  | 122 | LOG_ALWAYS_FATAL_IF(kAlignmentSize % __WORDSIZE != 0, "Incompatible word size"); | 
|  | 123 | return (length + kAlignmentSize/8 - 1) & ~(kAlignmentSize/8 - 1U); | 
|  | 124 | } | 
|  | 125 |  | 
|  | 126 | static inline size_t isAlignedToWordBoundary(size_t offset) { | 
|  | 127 | constexpr size_t kAlignmentSize = 64; | 
|  | 128 | return (offset & (kAlignmentSize/8 - 1)) == 0; | 
|  | 129 | } | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 130 | private: | 
|  | 131 | ::android::hardware::hidl_vec<GrantorDescriptor> mGrantors; | 
| Hridya Valsaraju | 4484344 | 2016-12-09 13:38:55 -0800 | [diff] [blame] | 132 | ::android::hardware::details::hidl_pointer<native_handle_t> mHandle; | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 133 | uint32_t mQuantum; | 
|  | 134 | uint32_t mFlags; | 
|  | 135 | }; | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 136 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 137 | template<typename T, MQFlavor flavor> | 
|  | 138 | const size_t MQDescriptor<T, flavor>::kOffsetOfGrantors = offsetof(MQDescriptor, mGrantors); | 
| Yifan Hong | 089ae13 | 2016-11-11 11:32:52 -0800 | [diff] [blame] | 139 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 140 | template<typename T, MQFlavor flavor> | 
|  | 141 | const size_t MQDescriptor<T, flavor>::kOffsetOfHandle = offsetof(MQDescriptor, mHandle); | 
| Yifan Hong | 089ae13 | 2016-11-11 11:32:52 -0800 | [diff] [blame] | 142 |  | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 143 | /* | 
|  | 144 | * MQDescriptorSync will describe the wait-free synchronized | 
|  | 145 | * flavor of FMQ. | 
|  | 146 | */ | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 147 | template<typename T> | 
|  | 148 | using MQDescriptorSync = MQDescriptor<T, kSynchronizedReadWrite>; | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 149 |  | 
| Hridya Valsaraju | 5657578 | 2016-10-13 21:44:55 -0700 | [diff] [blame] | 150 | /* | 
|  | 151 | * MQDescriptorUnsync will describe the unsynchronized write | 
|  | 152 | * flavor of FMQ. | 
|  | 153 | */ | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 154 | template<typename T> | 
|  | 155 | using MQDescriptorUnsync = MQDescriptor<T, kUnsynchronizedWrite>; | 
| Hridya Valsaraju | 5657578 | 2016-10-13 21:44:55 -0700 | [diff] [blame] | 156 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 157 | template<typename T, MQFlavor flavor> | 
|  | 158 | MQDescriptor<T, flavor>::MQDescriptor( | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 159 | const std::vector<GrantorDescriptor>& grantors, | 
|  | 160 | native_handle_t* nhandle, | 
|  | 161 | size_t size) | 
|  | 162 | : mHandle(nhandle), | 
|  | 163 | mQuantum(size), | 
|  | 164 | mFlags(flavor) { | 
|  | 165 | mGrantors.resize(grantors.size()); | 
|  | 166 | for (size_t i = 0; i < grantors.size(); ++i) { | 
| Hridya Valsaraju | 5d148b3 | 2017-01-10 14:38:42 -0800 | [diff] [blame] | 167 | LOG_ALWAYS_FATAL_IF(isAlignedToWordBoundary(grantors[i].offset) == false, | 
|  | 168 | "Grantor offsets need to be aligned"); | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 169 | mGrantors[i] = grantors[i]; | 
|  | 170 | } | 
|  | 171 | } | 
|  | 172 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 173 | template<typename T, MQFlavor flavor> | 
|  | 174 | MQDescriptor<T, flavor>::MQDescriptor(size_t bufferSize, native_handle_t *nHandle, | 
| Hridya Valsaraju | 9ec5730 | 2016-12-14 09:00:31 -0800 | [diff] [blame] | 175 | size_t messageSize, bool configureEventFlag) | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 176 | : mHandle(nHandle), mQuantum(messageSize), mFlags(flavor) { | 
| Hridya Valsaraju | 9ec5730 | 2016-12-14 09:00:31 -0800 | [diff] [blame] | 177 | /* | 
|  | 178 | * If configureEventFlag is true, allocate an additional spot in mGrantor | 
|  | 179 | * for containing the fd and offset for mmapping the EventFlag word. | 
|  | 180 | */ | 
|  | 181 | mGrantors.resize(configureEventFlag? kMinGrantorCountForEvFlagSupport : kMinGrantorCount); | 
|  | 182 |  | 
|  | 183 | size_t memSize[] = { | 
|  | 184 | sizeof(RingBufferPosition),  /* memory to be allocated for read pointer counter */ | 
|  | 185 | sizeof(RingBufferPosition),  /* memory to be allocated for write pointer counter */ | 
|  | 186 | bufferSize,                  /* memory to be allocated for data buffer */ | 
|  | 187 | sizeof(std::atomic<uint32_t>)/* memory to be allocated for EventFlag word */ | 
|  | 188 | }; | 
|  | 189 |  | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 190 | /* | 
|  | 191 | * Create a default grantor descriptor for read, write pointers and | 
|  | 192 | * the data buffer. fdIndex parameter is set to 0 by default and | 
|  | 193 | * the offset for each grantor is contiguous. | 
|  | 194 | */ | 
| Hridya Valsaraju | 9ec5730 | 2016-12-14 09:00:31 -0800 | [diff] [blame] | 195 | for (size_t grantorPos = 0, offset = 0; | 
|  | 196 | grantorPos < mGrantors.size(); | 
|  | 197 | offset += memSize[grantorPos++]) { | 
|  | 198 | mGrantors[grantorPos] = { | 
|  | 199 | 0 /* grantor flags */, | 
|  | 200 | 0 /* fdIndex */, | 
| Hridya Valsaraju | 5d148b3 | 2017-01-10 14:38:42 -0800 | [diff] [blame] | 201 | static_cast<uint32_t>(alignToWordBoundary(offset)), | 
| Hridya Valsaraju | 9ec5730 | 2016-12-14 09:00:31 -0800 | [diff] [blame] | 202 | memSize[grantorPos] | 
|  | 203 | }; | 
|  | 204 | } | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 205 | } | 
|  | 206 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 207 | template<typename T, MQFlavor flavor> | 
|  | 208 | MQDescriptor<T, flavor>::MQDescriptor(const MQDescriptor<T, flavor> &other) | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 209 | : mGrantors(other.mGrantors), | 
|  | 210 | mHandle(nullptr), | 
|  | 211 | mQuantum(other.mQuantum), | 
|  | 212 | mFlags(other.mFlags) { | 
|  | 213 | if (other.mHandle != nullptr) { | 
|  | 214 | mHandle = native_handle_create( | 
|  | 215 | other.mHandle->numFds, other.mHandle->numInts); | 
|  | 216 |  | 
|  | 217 | for (int i = 0; i < other.mHandle->numFds; ++i) { | 
| Hridya Valsaraju | 4484344 | 2016-12-09 13:38:55 -0800 | [diff] [blame] | 218 | mHandle->data[i] = dup(other.mHandle->data[i]); | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 219 | } | 
|  | 220 |  | 
| Hridya Valsaraju | 4484344 | 2016-12-09 13:38:55 -0800 | [diff] [blame] | 221 | memcpy(&mHandle->data[other.mHandle->numFds], | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 222 | &other.mHandle->data[other.mHandle->numFds], | 
|  | 223 | other.mHandle->numInts * sizeof(int)); | 
|  | 224 | } | 
|  | 225 | } | 
|  | 226 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 227 | template<typename T, MQFlavor flavor> | 
|  | 228 | MQDescriptor<T, flavor>::MQDescriptor() : MQDescriptor( | 
| Hridya Valsaraju | 0e326a0 | 2016-12-21 10:52:29 -0800 | [diff] [blame] | 229 | std::vector<android::hardware::GrantorDescriptor>(), | 
|  | 230 | nullptr /* nHandle */, | 
|  | 231 | 0 /* size */) {} | 
|  | 232 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 233 | template<typename T, MQFlavor flavor> | 
|  | 234 | MQDescriptor<T, flavor>::~MQDescriptor() { | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 235 | if (mHandle != nullptr) { | 
| Hridya Valsaraju | 4484344 | 2016-12-09 13:38:55 -0800 | [diff] [blame] | 236 | native_handle_close(mHandle); | 
|  | 237 | native_handle_delete(mHandle); | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 238 | } | 
|  | 239 | } | 
|  | 240 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 241 | template<typename T, MQFlavor flavor> | 
|  | 242 | size_t MQDescriptor<T, flavor>::getSize() const { | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 243 | return mGrantors[DATAPTRPOS].extent; | 
|  | 244 | } | 
|  | 245 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 246 | template<typename T, MQFlavor flavor> | 
|  | 247 | size_t MQDescriptor<T, flavor>::getQuantum() const { return mQuantum; } | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 248 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 249 | template<typename T, MQFlavor flavor> | 
|  | 250 | int32_t MQDescriptor<T, flavor>::getFlags() const { return mFlags; } | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 251 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 252 | template<typename T, MQFlavor flavor> | 
|  | 253 | std::vector<GrantorDescriptor> MQDescriptor<T, flavor>::getGrantors() const { | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 254 | size_t grantor_count = mGrantors.size(); | 
|  | 255 | std::vector<GrantorDescriptor> grantors(grantor_count); | 
|  | 256 | for (size_t i = 0; i < grantor_count; i++) { | 
|  | 257 | grantors[i] = mGrantors[i]; | 
|  | 258 | } | 
|  | 259 | return grantors; | 
|  | 260 | } | 
|  | 261 |  | 
| Hridya Valsaraju | 7e6404d | 2016-12-27 09:13:34 -0800 | [diff] [blame] | 262 | template<typename T, MQFlavor flavor> | 
|  | 263 | const sp<NativeHandle> MQDescriptor<T, flavor>::getNativeHandle() const { | 
| Hridya Valsaraju | 24fb4e2 | 2016-09-26 10:37:01 -0700 | [diff] [blame] | 264 | /* | 
|  | 265 | * Create an sp<NativeHandle> from mHandle. | 
|  | 266 | */ | 
|  | 267 | return NativeHandle::create(mHandle, false /* ownsHandle */); | 
|  | 268 | } | 
| Yifan Hong | be7a688 | 2017-01-05 17:30:17 -0800 | [diff] [blame] | 269 |  | 
|  | 270 | namespace details { | 
|  | 271 | template<typename T, MQFlavor flavor> | 
|  | 272 | std::string toString(const MQDescriptor<T, flavor> &q) { | 
|  | 273 | std::string os; | 
|  | 274 | if (flavor & kSynchronizedReadWrite) { | 
|  | 275 | os += "fmq_sync"; | 
|  | 276 | } | 
|  | 277 | if (flavor & kUnsynchronizedWrite) { | 
|  | 278 | os += "fmq_unsync"; | 
|  | 279 | } | 
|  | 280 | os += " {" | 
|  | 281 | + toString(q.getGrantors().size()) + " grantor(s), " | 
|  | 282 | + "size = " + toString(q.getSize()) | 
|  | 283 | + ", .handle = " + toString(q.getNativeHandle().get()) | 
|  | 284 | + ", .quantum = " + toString(q.getQuantum()) + "}"; | 
|  | 285 | return os; | 
|  | 286 | } | 
|  | 287 | }  // namespace details | 
|  | 288 |  | 
| Hridya Valsaraju | 4fe70f0 | 2016-09-20 21:02:51 -0700 | [diff] [blame] | 289 | }  // namespace hardware | 
|  | 290 | }  // namespace android | 
| Andreas Huber | 0a45128 | 2016-08-30 11:27:24 -0700 | [diff] [blame] | 291 |  | 
|  | 292 | #endif  // FMSGQ_DESCRIPTOR_H |