diff options
| author | Vijay Venkatraman <vijaykv@google.com> | 2017-01-05 10:39:38 -0800 |
|---|---|---|
| committer | Vijay Venkatraman <vijaykv@google.com> | 2017-01-24 22:51:36 +0000 |
| commit | 75acc7bf81d43850694d39d2c45a20ca81d99379 (patch) | |
| tree | 39f8b964c90102fbc6a8b954110342724cf6f394 /libutils/include/utils/Condition.h | |
| parent | 897bc9b2b38ead33aa883359593eb4356b68bda2 (diff) | |
| download | system_core-75acc7bf81d43850694d39d2c45a20ca81d99379.tar.gz system_core-75acc7bf81d43850694d39d2c45a20ca81d99379.tar.bz2 system_core-75acc7bf81d43850694d39d2c45a20ca81d99379.zip | |
Exporting C++ headers from system/core
Moved headers from include/libutils and include/libsysutils to
libutils/include and libsysutils/include respectively, so they can be
exported via these libs. They needed to be moved since Soong does
not allow export from external folder.
Added symlink from old locations. They are needed since Soong
includes system/core/include by default. Once all modules are
cleaned up to explicitly add the required libs, the symlinks will be
removed.
Moved headers of libutils to libutils_headers. They should be used
by modules for header-only inlines. Added libutils_headers as
dependency of libutils.
Split of C++ headers into those that have no dependency and those that
have dependency on libutils.so will be handled in a later CL.
Test: Add above libs to shared lib of local module
Change-Id: I122db72056b26b1f39bad1d9a0c2a1c5efda3550
Diffstat (limited to 'libutils/include/utils/Condition.h')
| -rw-r--r-- | libutils/include/utils/Condition.h | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/libutils/include/utils/Condition.h b/libutils/include/utils/Condition.h new file mode 100644 index 000000000..25a53aa23 --- /dev/null +++ b/libutils/include/utils/Condition.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * 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 _LIBS_UTILS_CONDITION_H +#define _LIBS_UTILS_CONDITION_H + +#include <limits.h> +#include <stdint.h> +#include <sys/types.h> +#include <time.h> + +#if !defined(_WIN32) +# include <pthread.h> +#endif + +#include <utils/Errors.h> +#include <utils/Mutex.h> +#include <utils/Timers.h> + +// --------------------------------------------------------------------------- +namespace android { +// --------------------------------------------------------------------------- + +/* + * Condition variable class. The implementation is system-dependent. + * + * Condition variables are paired up with mutexes. Lock the mutex, + * call wait(), then either re-wait() if things aren't quite what you want, + * or unlock the mutex and continue. All threads calling wait() must + * use the same mutex for a given Condition. + */ +class Condition { +public: + enum { + PRIVATE = 0, + SHARED = 1 + }; + + enum WakeUpType { + WAKE_UP_ONE = 0, + WAKE_UP_ALL = 1 + }; + + Condition(); + explicit Condition(int type); + ~Condition(); + // Wait on the condition variable. Lock the mutex before calling. + status_t wait(Mutex& mutex); + // same with relative timeout + status_t waitRelative(Mutex& mutex, nsecs_t reltime); + // Signal the condition variable, allowing exactly one thread to continue. + void signal(); + // Signal the condition variable, allowing one or all threads to continue. + void signal(WakeUpType type) { + if (type == WAKE_UP_ONE) { + signal(); + } else { + broadcast(); + } + } + // Signal the condition variable, allowing all threads to continue. + void broadcast(); + +private: +#if !defined(_WIN32) + pthread_cond_t mCond; +#else + void* mState; +#endif +}; + +// --------------------------------------------------------------------------- + +#if !defined(_WIN32) + +inline Condition::Condition() { + pthread_cond_init(&mCond, NULL); +} +inline Condition::Condition(int type) { + if (type == SHARED) { + pthread_condattr_t attr; + pthread_condattr_init(&attr); + pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + pthread_cond_init(&mCond, &attr); + pthread_condattr_destroy(&attr); + } else { + pthread_cond_init(&mCond, NULL); + } +} +inline Condition::~Condition() { + pthread_cond_destroy(&mCond); +} +inline status_t Condition::wait(Mutex& mutex) { + return -pthread_cond_wait(&mCond, &mutex.mMutex); +} +inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { + struct timespec ts; +#if defined(__linux__) + clock_gettime(CLOCK_REALTIME, &ts); +#else // __APPLE__ + // Apple doesn't support POSIX clocks. + struct timeval t; + gettimeofday(&t, NULL); + ts.tv_sec = t.tv_sec; + ts.tv_nsec = t.tv_usec*1000; +#endif + + // On 32-bit devices, tv_sec is 32-bit, but `reltime` is 64-bit. + int64_t reltime_sec = reltime/1000000000; + + ts.tv_nsec += static_cast<long>(reltime%1000000000); + if (reltime_sec < INT64_MAX && ts.tv_nsec >= 1000000000) { + ts.tv_nsec -= 1000000000; + ++reltime_sec; + } + + int64_t time_sec = ts.tv_sec; + if (time_sec > INT64_MAX - reltime_sec) { + time_sec = INT64_MAX; + } else { + time_sec += reltime_sec; + } + + ts.tv_sec = (time_sec > LONG_MAX) ? LONG_MAX : static_cast<long>(time_sec); + + return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); +} +inline void Condition::signal() { + /* + * POSIX says pthread_cond_signal wakes up "one or more" waiting threads. + * However bionic follows the glibc guarantee which wakes up "exactly one" + * waiting thread. + * + * man 3 pthread_cond_signal + * pthread_cond_signal restarts one of the threads that are waiting on + * the condition variable cond. If no threads are waiting on cond, + * nothing happens. If several threads are waiting on cond, exactly one + * is restarted, but it is not specified which. + */ + pthread_cond_signal(&mCond); +} +inline void Condition::broadcast() { + pthread_cond_broadcast(&mCond); +} + +#endif // !defined(_WIN32) + +// --------------------------------------------------------------------------- +}; // namespace android +// --------------------------------------------------------------------------- + +#endif // _LIBS_UTILS_CONDITON_H |
