From 1f496ca60ba4b0a5099ccebb51d17fcdc9ac5a41 Mon Sep 17 00:00:00 2001 From: Rafael Antognolli Date: Wed, 8 Mar 2017 11:13:35 -0800 Subject: [PATCH] Add HWCEvent to handle signalling of HWCThread. This class uses linux eventfd() to handle events and signal when the HWCThread should wake up. Signed-off-by: Rafael Antognolli --- Android.mk | 1 + Makefile.sources | 1 + common/utils/hwcevent.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++++ common/utils/hwcevent.h | 42 +++++++++++++++++++++++ common/utils/hwcthread.cpp | 29 ++++------------ common/utils/hwcthread.h | 4 +-- 6 files changed, 137 insertions(+), 25 deletions(-) create mode 100644 common/utils/hwcevent.cpp create mode 100644 common/utils/hwcevent.h diff --git a/Android.mk b/Android.mk index f7997b5..0ba6145 100644 --- a/Android.mk +++ b/Android.mk @@ -60,6 +60,7 @@ LOCAL_SRC_FILES := \ common/display/pageflipeventhandler.cpp \ common/display/virtualdisplay.cpp \ common/utils/drmscopedtypes.cpp \ + common/utils/hwcevent.cpp \ common/utils/hwcthread.cpp \ common/utils/disjoint_layers.cpp \ os/android/grallocbufferhandler.cpp \ diff --git a/Makefile.sources b/Makefile.sources index 8fb6fac..7c0271d 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -16,6 +16,7 @@ common_SOURCES = \ common/display/pageflipeventhandler.cpp \ common/display/virtualdisplay.cpp \ common/utils/drmscopedtypes.cpp \ + common/utils/hwcevent.cpp \ common/utils/hwcthread.cpp \ common/utils/disjoint_layers.cpp \ os/linux/gbmbufferhandler.cpp \ diff --git a/common/utils/hwcevent.cpp b/common/utils/hwcevent.cpp new file mode 100644 index 0000000..e3a54ae --- /dev/null +++ b/common/utils/hwcevent.cpp @@ -0,0 +1,85 @@ +/* +// Copyright (c) 2017 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +#include "hwcevent.h" + +#include +#include +#include +#include +#include +#include + +#include "hwctrace.h" + +namespace hwcomposer { + +HWCEvent::HWCEvent() { + fd_ = eventfd(0, EFD_SEMAPHORE); + if (fd_ < 0) { + ETRACE("Failed to initialize eventfd: %s", strerror(errno)); + } +} + +HWCEvent::~HWCEvent() { + if (fd_ >= 0) + close(fd_); + + fd_ = -1; +} + +bool HWCEvent::Signal() { + if (fd_ < 0) { + ETRACE("invalid eventfd: %d", fd_); + return false; + } + + uint64_t inc = 1; + ssize_t ret = write(fd_, &inc, sizeof(inc)); + if (ret < 0) { + ETRACE("couldn't write to eventfd: %zd (%s)", ret, strerror(errno)); + return false; + } + + return true; +} + +bool HWCEvent::Wait() { + if (fd_ < 0) { + ETRACE("invalid eventfd: %d", fd_); + return false; + } + + uint64_t result; + ssize_t ret = read(fd_, &result, sizeof(result)); + if (ret < 0) { + ETRACE("couldn't read from eventfd: %zd (%s)", ret, strerror(errno)); + return false; + } + + if (result != 1) { + ETRACE("read from eventfd has wrong value: %lu (should be 1)", result); + return false; + } + + return true; +} + +bool HWCEvent::ShouldWait() { + return true; +} + +} // namespace hwcomposer diff --git a/common/utils/hwcevent.h b/common/utils/hwcevent.h new file mode 100644 index 0000000..a3242fb --- /dev/null +++ b/common/utils/hwcevent.h @@ -0,0 +1,42 @@ +/* +// Copyright (c) 2017 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +*/ + +#ifndef COMMON_UTILS_HWCEVENT_H_ +#define COMMON_UTILS_HWCEVENT_H_ + +namespace hwcomposer { + +class HWCEvent { + public: + HWCEvent(); + virtual ~HWCEvent(); + + bool Signal(); + bool Wait(); + + bool ShouldWait(); + + int get_fd() const { + return fd_; + } + + private: + int fd_; +}; + +} // namespace hwcomposer + +#endif // COMMON_UTILS_HWCEVENT_H_ diff --git a/common/utils/hwcthread.cpp b/common/utils/hwcthread.cpp index 5ef34be..edd4857 100644 --- a/common/utils/hwcthread.cpp +++ b/common/utils/hwcthread.cpp @@ -35,10 +35,10 @@ HWCThread::~HWCThread() { bool HWCThread::InitWorker() { if (initialized_) return true; - mutex_.lock(); + initialized_ = true; exit_ = false; - mutex_.unlock(); + thread_ = std::unique_ptr( new std::thread(&HWCThread::ProcessThread, this)); @@ -46,14 +46,10 @@ bool HWCThread::InitWorker() { } void HWCThread::Resume() { - if (!suspended_ || exit_) + if (exit_) return; - mutex_.lock(); - suspended_ = false; - mutex_.unlock(); - - cond_.notify_one(); + event_.Signal(); } void HWCThread::Exit() { @@ -61,13 +57,9 @@ void HWCThread::Exit() { if (!initialized_) return; - mutex_.lock(); initialized_ = false; - suspended_ = false; - exit_ = true; - mutex_.unlock(); - cond_.notify_one(); + event_.Signal(); thread_->join(); } @@ -78,26 +70,17 @@ void HWCThread::ProcessThread() { setpriority(PRIO_PROCESS, 0, priority_); prctl(PR_SET_NAME, name_.c_str()); - std::unique_lock lk(mutex_, std::defer_lock); - while (true) { - lk.lock(); + while (event_.Wait()) { if (exit_) { HandleExit(); return; } - if (suspended_) { - cond_.wait(lk); - } - lk.unlock(); HandleRoutine(); } } void HWCThread::ConditionalSuspend() { - mutex_.lock(); - suspended_ = true; - mutex_.unlock(); } } // namespace hwcomposer diff --git a/common/utils/hwcthread.h b/common/utils/hwcthread.h index 8ccdd16..19bdbcf 100644 --- a/common/utils/hwcthread.h +++ b/common/utils/hwcthread.h @@ -22,6 +22,7 @@ #include #include +#include "hwcevent.h" #include "spinlock.h" namespace hwcomposer { @@ -47,10 +48,9 @@ class HWCThread { int priority_; std::string name_; + HWCEvent event_; bool exit_ = false; bool suspended_ = false; - std::mutex mutex_; - std::condition_variable cond_; std::unique_ptr thread_; }; -- 2.11.0