1d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* 2d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* Copyright (c) 2014 - 2015, The Linux Foundation. All rights reserved. 3d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* 4d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* Redistribution and use in source and binary forms, with or without modification, are permitted 5d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* provided that the following conditions are met: 6d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* * Redistributions of source code must retain the above copyright notice, this list of 7d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* conditions and the following disclaimer. 8d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* * Redistributions in binary form must reproduce the above copyright notice, this list of 9d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* conditions and the following disclaimer in the documentation and/or other materials provided 10d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* with the distribution. 11d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* * Neither the name of The Linux Foundation nor the names of its contributors may be used to 12d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* endorse or promote products derived from this software without specific prior written 13d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* permission. 14d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* 15d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 18d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 21d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*/ 24d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 25d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#ifndef __LOCKER_H__ 26d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define __LOCKER_H__ 27d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 28d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <stdint.h> 29d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <pthread.h> 30d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/time.h> 31d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 32d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define SCOPE_LOCK(locker) Locker::ScopeLock lock(locker) 33d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define SEQUENCE_ENTRY_SCOPE_LOCK(locker) Locker::SequenceEntryScopeLock lock(locker) 34d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define SEQUENCE_EXIT_SCOPE_LOCK(locker) Locker::SequenceExitScopeLock lock(locker) 35d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define SEQUENCE_WAIT_SCOPE_LOCK(locker) Locker::SequenceWaitScopeLock lock(locker) 36d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define SEQUENCE_CANCEL_SCOPE_LOCK(locker) Locker::SequenceCancelScopeLock lock(locker) 37d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 38d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinnamespace sdm { 39d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 40d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinclass Locker { 41d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin public: 42d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin class ScopeLock { 43d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin public: 44d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin explicit ScopeLock(Locker& locker) : locker_(locker) { 45d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Lock(); 46d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 47d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 48d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ~ScopeLock() { 49d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Unlock(); 50d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 51d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 52d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin private: 53d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Locker &locker_; 54d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin }; 55d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 56d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin class SequenceEntryScopeLock { 57d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin public: 58d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin explicit SequenceEntryScopeLock(Locker& locker) : locker_(locker) { 59d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Lock(); 60d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.sequence_wait_ = 1; 61d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 62d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 63d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ~SequenceEntryScopeLock() { 64d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Unlock(); 65d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 66d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 67d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin private: 68d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Locker &locker_; 69d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin }; 70d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 71d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin class SequenceExitScopeLock { 72d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin public: 73d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin explicit SequenceExitScopeLock(Locker& locker) : locker_(locker) { 74d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Lock(); 75d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.sequence_wait_ = 0; 76d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 77d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 78d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ~SequenceExitScopeLock() { 79d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Broadcast(); 80d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Unlock(); 81d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 82d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 83d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin private: 84d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Locker &locker_; 85d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin }; 86d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 87d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin class SequenceWaitScopeLock { 88d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin public: 89d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin explicit SequenceWaitScopeLock(Locker& locker) : locker_(locker), error_(false) { 90d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Lock(); 91d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 92d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (locker_.sequence_wait_ == 1) { 93d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Wait(); 94d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin error_ = (locker_.sequence_wait_ == -1); 95d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 96d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 97d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 98d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ~SequenceWaitScopeLock() { 99d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Unlock(); 100d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 101d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 102d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin bool IsError() { 103d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return error_; 104d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 105d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 106d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin private: 107d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Locker &locker_; 108d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin bool error_; 109d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin }; 110d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 111d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin class SequenceCancelScopeLock { 112d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin public: 113d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin explicit SequenceCancelScopeLock(Locker& locker) : locker_(locker) { 114d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Lock(); 115d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.sequence_wait_ = -1; 116d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 117d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 118d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ~SequenceCancelScopeLock() { 119d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Broadcast(); 120d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin locker_.Unlock(); 121d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 122d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 123d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin private: 124d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Locker &locker_; 125d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin }; 126d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 127d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Locker() : sequence_wait_(0) { 128d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_mutex_init(&mutex_, 0); 129d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_cond_init(&condition_, 0); 130d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 131d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 132d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ~Locker() { 133d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_mutex_destroy(&mutex_); 134d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_cond_destroy(&condition_); 135d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 136d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 137d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin void Lock() { pthread_mutex_lock(&mutex_); } 138d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin void Unlock() { pthread_mutex_unlock(&mutex_); } 139d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin void Signal() { pthread_cond_signal(&condition_); } 140d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin void Broadcast() { pthread_cond_broadcast(&condition_); } 141d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin void Wait() { pthread_cond_wait(&condition_, &mutex_); } 142d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int WaitFinite(int ms) { 143d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin struct timespec ts; 144d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin struct timeval tv; 145d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin gettimeofday(&tv, NULL); 146d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ts.tv_sec = tv.tv_sec + ms/1000; 147d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ts.tv_nsec = tv.tv_usec*1000 + (ms%1000)*1000000; 148d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ts.tv_sec += ts.tv_nsec/1000000000L; 149d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ts.tv_nsec += ts.tv_nsec%1000000000L; 150d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return pthread_cond_timedwait(&condition_, &mutex_, &ts); 151d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 152d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 153d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin private: 154d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_mutex_t mutex_; 155d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_cond_t condition_; 156d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int sequence_wait_; // This flag is set to 1 on sequence entry, 0 on exit, and -1 on cancel. 157d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Some routines will wait for sequence of function calls to finish 158d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // so that capturing a transitionary snapshot of context is prevented. 159d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // If flag is set to -1, these routines will exit without doing any 160d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // further processing. 161d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}; 162d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 163d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} // namespace sdm 164d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 165d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#endif // __LOCKER_H__ 166d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 167