diff options
-rw-r--r-- | Android.bp | 7 | ||||
-rw-r--r-- | base/include/hidl/MQDescriptor.h | 96 | ||||
-rw-r--r-- | transport/ServiceManagement.cpp | 12 | ||||
-rw-r--r-- | transport/include/hidl/HidlLazyUtils.h | 11 |
4 files changed, 38 insertions, 88 deletions
@@ -165,6 +165,13 @@ cc_defaults { "transport/include", ], + header_libs: [ + "libfmq-base", + ], + export_header_lib_headers: [ + "libfmq-base", + ], + generated_sources: [ "android.hidl.manager@1.0_genc++", "android.hidl.manager@1.1_genc++", diff --git a/base/include/hidl/MQDescriptor.h b/base/include/hidl/MQDescriptor.h index eb244e57..786c1bea 100644 --- a/base/include/hidl/MQDescriptor.h +++ b/base/include/hidl/MQDescriptor.h @@ -20,43 +20,13 @@ #include <unistd.h> #include <cutils/native_handle.h> +#include <fmq/MQDescriptorBase.h> #include <hidl/HidlInternal.h> #include <hidl/HidlSupport.h> namespace android { namespace hardware { -typedef uint64_t RingBufferPosition; - -struct GrantorDescriptor { - uint32_t flags __attribute__ ((aligned(4))); - uint32_t fdIndex __attribute__ ((aligned(4))); - uint32_t offset __attribute__ ((aligned(4))); - uint64_t extent __attribute__ ((aligned(8))); -}; - -static_assert(offsetof(GrantorDescriptor, flags) == 0, "wrong offset"); -static_assert(offsetof(GrantorDescriptor, fdIndex) == 4, "wrong offset"); -static_assert(offsetof(GrantorDescriptor, offset) == 8, "wrong offset"); -static_assert(offsetof(GrantorDescriptor, extent) == 16, "wrong offset"); -static_assert(sizeof(GrantorDescriptor) == 24, "wrong size"); -static_assert(__alignof(GrantorDescriptor) == 8, "wrong alignment"); - -enum MQFlavor : uint32_t { - /* - * kSynchronizedReadWrite represents the wait-free synchronized flavor of the - * FMQ. It is intended to be have a single reader and single writer. - * Attempts to overflow/underflow returns a failure. - */ - kSynchronizedReadWrite = 0x01, - /* - * kUnsynchronizedWrite represents the flavor of FMQ where writes always - * succeed. This flavor allows one writer and many readers. A read operation - * can detect an overwrite and reset the read counter. - */ - kUnsynchronizedWrite = 0x02 -}; - template <typename T, MQFlavor flavor> struct MQDescriptor { // Takes ownership of handle @@ -87,6 +57,8 @@ struct MQDescriptor { return mGrantors; } + // This should be removed if no one is using it. We shouldn't be returning + // a mutable reference if it's not necessary. TODO(b/162465295). inline ::android::hardware::hidl_vec<GrantorDescriptor> &grantors() { return mGrantors; } @@ -101,42 +73,7 @@ struct MQDescriptor { static const size_t kOffsetOfGrantors; static const size_t kOffsetOfHandle; - enum GrantorType : int { READPTRPOS = 0, WRITEPTRPOS, DATAPTRPOS, EVFLAGWORDPOS }; - /* - * 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 = DATAPTRPOS + 1; - - /* - * Minimum number of GrantorDescriptors required if EventFlag support is - * needed for blocking FMQ operations. - */ - static constexpr int32_t kMinGrantorCountForEvFlagSupport = EVFLAGWORDPOS + 1; - - //TODO(b/34160777) Identify a better solution that supports remoting. - static inline size_t alignToWordBoundary(size_t length) { - constexpr size_t kAlignmentSize = 64; - if (kAlignmentSize % __WORDSIZE != 0) { - details::logAlwaysFatal("Incompatible word size"); - } - - /* - * Check if alignment to word boundary would cause an overflow. - */ - if (length > SIZE_MAX - kAlignmentSize/8 + 1) { - details::logAlwaysFatal("Queue size too large"); - } - - return (length + kAlignmentSize/8 - 1) & ~(kAlignmentSize/8 - 1U); - } - - static inline size_t isAlignedToWordBoundary(size_t offset) { - constexpr size_t kAlignmentSize = 64; - return (offset & (kAlignmentSize/8 - 1)) == 0; - } private: ::android::hardware::hidl_vec<GrantorDescriptor> mGrantors; ::android::hardware::details::hidl_pointer<native_handle_t> mHandle; @@ -170,9 +107,6 @@ MQDescriptor<T, flavor>::MQDescriptor(const std::vector<GrantorDescriptor>& gran : mHandle(nhandle), mQuantum(static_cast<uint32_t>(size)), mFlags(flavor) { mGrantors.resize(grantors.size()); for (size_t i = 0; i < grantors.size(); ++i) { - if (isAlignedToWordBoundary(grantors[i].offset) == false) { - details::logAlwaysFatal("Grantor offsets need to be aligned"); - } mGrantors[i] = grantors[i]; } } @@ -185,13 +119,16 @@ MQDescriptor<T, flavor>::MQDescriptor(size_t bufferSize, native_handle_t* nHandl * 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); + mGrantors.resize(configureEventFlag ? details::kMinGrantorCountForEvFlagSupport + : details::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 */ + sizeof(details::RingBufferPosition), /* memory to be allocated for read pointer counter + */ + sizeof(details::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 */ }; /* @@ -202,12 +139,9 @@ MQDescriptor<T, flavor>::MQDescriptor(size_t bufferSize, native_handle_t* nHandl for (size_t grantorPos = 0, offset = 0; grantorPos < mGrantors.size(); offset += memSize[grantorPos++]) { - mGrantors[grantorPos] = { - 0 /* grantor flags */, - 0 /* fdIndex */, - static_cast<uint32_t>(alignToWordBoundary(offset)), - memSize[grantorPos] - }; + mGrantors[grantorPos] = {0 /* grantor flags */, 0 /* fdIndex */, + static_cast<uint32_t>(details::alignToWordBoundary(offset)), + memSize[grantorPos]}; } } @@ -253,7 +187,7 @@ MQDescriptor<T, flavor>::~MQDescriptor() { template<typename T, MQFlavor flavor> size_t MQDescriptor<T, flavor>::getSize() const { - return static_cast<size_t>(mGrantors[DATAPTRPOS].extent); + return static_cast<size_t>(mGrantors[details::DATAPTRPOS].extent); } template<typename T, MQFlavor flavor> diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp index aa540c6a..cbe7ac60 100644 --- a/transport/ServiceManagement.cpp +++ b/transport/ServiceManagement.cpp @@ -87,7 +87,7 @@ static void waitForHwServiceManager() { static std::string binaryName() { std::ifstream ifs("/proc/self/cmdline"); std::string cmdline; - if (!ifs.is_open()) { + if (!ifs) { return ""; } ifs >> cmdline; @@ -106,7 +106,7 @@ static std::string packageWithoutVersion(const std::string& packageAndVersion) { return packageAndVersion.substr(0, at); } -static void tryShortenProcessName(const std::string& descriptor) { +__attribute__((noinline)) static void tryShortenProcessName(const std::string& descriptor) { const static std::string kTasks = "/proc/self/task/"; // make sure that this binary name is in the same package @@ -135,17 +135,17 @@ static void tryShortenProcessName(const std::string& descriptor) { if (dp->d_name[0] == '.') continue; std::fstream fs(kTasks + dp->d_name + "/comm"); - if (!fs.is_open()) { + if (!fs) { ALOGI("Could not rename process, failed read comm for %s.", dp->d_name); continue; } std::string oldComm; - fs >> oldComm; + if (!(fs >> oldComm)) continue; // don't rename if it already has an explicit name if (base::StartsWith(descriptor, oldComm)) { - fs.seekg(0, fs.beg); + if (!fs.seekg(0, fs.beg)) continue; fs << newName; } } @@ -187,7 +187,7 @@ static inline bool isTrebleTestingOverride() { * Returns the age of the current process by reading /proc/self/stat and comparing starttime to the * current time. This is useful for measuring how long it took a HAL to register itself. */ -static long getProcessAgeMs() { +__attribute__((noinline)) static long getProcessAgeMs() { constexpr const int PROCFS_STAT_STARTTIME_INDEX = 21; std::string content; android::base::ReadFileToString("/proc/self/stat", &content, false); diff --git a/transport/include/hidl/HidlLazyUtils.h b/transport/include/hidl/HidlLazyUtils.h index 6a62c97f..97fe20ed 100644 --- a/transport/include/hidl/HidlLazyUtils.h +++ b/transport/include/hidl/HidlLazyUtils.h @@ -26,7 +26,16 @@ namespace details { class LazyServiceRegistrarImpl; } // namespace details -/** Exits when all HALs registered through this object have 0 clients */ +/** + * Exits when all HALs registered through this object have 0 clients + * + * In order to use this class, it's expected that your service: + * - registers all services in the process with this API + * - configures services as oneshot + disabled in init .rc files + * - uses 'interface' declarations in init .rc files + * + * For more information on init .rc configuration, see system/core/init/README.md + **/ class LazyServiceRegistrar { public: static LazyServiceRegistrar& getInstance(); |