1*35238bceSAndroid Build Coastguard Worker #ifndef _TCUTHREADUTIL_HPP 2*35238bceSAndroid Build Coastguard Worker #define _TCUTHREADUTIL_HPP 3*35238bceSAndroid Build Coastguard Worker /*------------------------------------------------------------------------- 4*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program Tester Core 5*35238bceSAndroid Build Coastguard Worker * ---------------------------------------- 6*35238bceSAndroid Build Coastguard Worker * 7*35238bceSAndroid Build Coastguard Worker * Copyright 2014 The Android Open Source Project 8*35238bceSAndroid Build Coastguard Worker * 9*35238bceSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 10*35238bceSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 11*35238bceSAndroid Build Coastguard Worker * You may obtain a copy of the License at 12*35238bceSAndroid Build Coastguard Worker * 13*35238bceSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 14*35238bceSAndroid Build Coastguard Worker * 15*35238bceSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 16*35238bceSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 17*35238bceSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18*35238bceSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 19*35238bceSAndroid Build Coastguard Worker * limitations under the License. 20*35238bceSAndroid Build Coastguard Worker * 21*35238bceSAndroid Build Coastguard Worker *//*! 22*35238bceSAndroid Build Coastguard Worker * \file 23*35238bceSAndroid Build Coastguard Worker * \brief Thread test utilities 24*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/ 25*35238bceSAndroid Build Coastguard Worker 26*35238bceSAndroid Build Coastguard Worker #include "tcuDefs.hpp" 27*35238bceSAndroid Build Coastguard Worker #include "deSharedPtr.hpp" 28*35238bceSAndroid Build Coastguard Worker #include "deMutex.hpp" 29*35238bceSAndroid Build Coastguard Worker #include "deSemaphore.hpp" 30*35238bceSAndroid Build Coastguard Worker #include "deThread.hpp" 31*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp" 32*35238bceSAndroid Build Coastguard Worker 33*35238bceSAndroid Build Coastguard Worker #include <vector> 34*35238bceSAndroid Build Coastguard Worker #include <sstream> 35*35238bceSAndroid Build Coastguard Worker 36*35238bceSAndroid Build Coastguard Worker namespace tcu 37*35238bceSAndroid Build Coastguard Worker { 38*35238bceSAndroid Build Coastguard Worker namespace ThreadUtil 39*35238bceSAndroid Build Coastguard Worker { 40*35238bceSAndroid Build Coastguard Worker // Event object for synchronizing threads 41*35238bceSAndroid Build Coastguard Worker class Event 42*35238bceSAndroid Build Coastguard Worker { 43*35238bceSAndroid Build Coastguard Worker public: 44*35238bceSAndroid Build Coastguard Worker enum Result 45*35238bceSAndroid Build Coastguard Worker { 46*35238bceSAndroid Build Coastguard Worker RESULT_NOT_READY = 0, 47*35238bceSAndroid Build Coastguard Worker RESULT_OK, 48*35238bceSAndroid Build Coastguard Worker RESULT_FAILED 49*35238bceSAndroid Build Coastguard Worker }; 50*35238bceSAndroid Build Coastguard Worker 51*35238bceSAndroid Build Coastguard Worker Event(void); 52*35238bceSAndroid Build Coastguard Worker ~Event(void); 53*35238bceSAndroid Build Coastguard Worker void setResult(Result result); 54*35238bceSAndroid Build Coastguard Worker Result waitReady(void); getResult(void) const55*35238bceSAndroid Build Coastguard Worker Result getResult(void) const 56*35238bceSAndroid Build Coastguard Worker { 57*35238bceSAndroid Build Coastguard Worker return m_result; 58*35238bceSAndroid Build Coastguard Worker } 59*35238bceSAndroid Build Coastguard Worker 60*35238bceSAndroid Build Coastguard Worker private: 61*35238bceSAndroid Build Coastguard Worker volatile Result m_result; 62*35238bceSAndroid Build Coastguard Worker volatile int m_waiterCount; 63*35238bceSAndroid Build Coastguard Worker de::Semaphore m_waiters; 64*35238bceSAndroid Build Coastguard Worker de::Mutex m_lock; 65*35238bceSAndroid Build Coastguard Worker 66*35238bceSAndroid Build Coastguard Worker // Disabled 67*35238bceSAndroid Build Coastguard Worker Event(const Event &); 68*35238bceSAndroid Build Coastguard Worker Event &operator=(const Event &); 69*35238bceSAndroid Build Coastguard Worker }; 70*35238bceSAndroid Build Coastguard Worker 71*35238bceSAndroid Build Coastguard Worker // Base class for objects which modifications should be tracked between threads 72*35238bceSAndroid Build Coastguard Worker class Object 73*35238bceSAndroid Build Coastguard Worker { 74*35238bceSAndroid Build Coastguard Worker public: 75*35238bceSAndroid Build Coastguard Worker Object(const char *type, de::SharedPtr<Event> createEvent); 76*35238bceSAndroid Build Coastguard Worker virtual ~Object(void); getType(void) const77*35238bceSAndroid Build Coastguard Worker const char *getType(void) const 78*35238bceSAndroid Build Coastguard Worker { 79*35238bceSAndroid Build Coastguard Worker return m_type; 80*35238bceSAndroid Build Coastguard Worker } 81*35238bceSAndroid Build Coastguard Worker 82*35238bceSAndroid Build Coastguard Worker // Used by class Operation only 83*35238bceSAndroid Build Coastguard Worker void read(de::SharedPtr<Event> event, std::vector<de::SharedPtr<Event>> &deps); 84*35238bceSAndroid Build Coastguard Worker void modify(de::SharedPtr<Event> event, std::vector<de::SharedPtr<Event>> &deps); 85*35238bceSAndroid Build Coastguard Worker 86*35238bceSAndroid Build Coastguard Worker private: 87*35238bceSAndroid Build Coastguard Worker const char *m_type; 88*35238bceSAndroid Build Coastguard Worker de::SharedPtr<Event> m_modify; 89*35238bceSAndroid Build Coastguard Worker std::vector<de::SharedPtr<Event>> m_reads; 90*35238bceSAndroid Build Coastguard Worker 91*35238bceSAndroid Build Coastguard Worker // Disabled 92*35238bceSAndroid Build Coastguard Worker Object(const Object &); 93*35238bceSAndroid Build Coastguard Worker Object &operator=(const Object &); 94*35238bceSAndroid Build Coastguard Worker }; 95*35238bceSAndroid Build Coastguard Worker 96*35238bceSAndroid Build Coastguard Worker class Thread; 97*35238bceSAndroid Build Coastguard Worker 98*35238bceSAndroid Build Coastguard Worker class MessageBuilder 99*35238bceSAndroid Build Coastguard Worker { 100*35238bceSAndroid Build Coastguard Worker public: MessageBuilder(Thread & thread)101*35238bceSAndroid Build Coastguard Worker MessageBuilder(Thread &thread) : m_thread(thread) 102*35238bceSAndroid Build Coastguard Worker { 103*35238bceSAndroid Build Coastguard Worker } MessageBuilder(const MessageBuilder & other)104*35238bceSAndroid Build Coastguard Worker MessageBuilder(const MessageBuilder &other) : m_thread(other.m_thread), m_stream(other.m_stream.str()) 105*35238bceSAndroid Build Coastguard Worker { 106*35238bceSAndroid Build Coastguard Worker } 107*35238bceSAndroid Build Coastguard Worker template <class T> operator <<(const T & t)108*35238bceSAndroid Build Coastguard Worker MessageBuilder &operator<<(const T &t) 109*35238bceSAndroid Build Coastguard Worker { 110*35238bceSAndroid Build Coastguard Worker m_stream << t; 111*35238bceSAndroid Build Coastguard Worker return *this; 112*35238bceSAndroid Build Coastguard Worker } 113*35238bceSAndroid Build Coastguard Worker 114*35238bceSAndroid Build Coastguard Worker class EndToken 115*35238bceSAndroid Build Coastguard Worker { 116*35238bceSAndroid Build Coastguard Worker public: EndToken(void)117*35238bceSAndroid Build Coastguard Worker EndToken(void) 118*35238bceSAndroid Build Coastguard Worker { 119*35238bceSAndroid Build Coastguard Worker } 120*35238bceSAndroid Build Coastguard Worker }; 121*35238bceSAndroid Build Coastguard Worker 122*35238bceSAndroid Build Coastguard Worker void operator<<(const EndToken &); 123*35238bceSAndroid Build Coastguard Worker 124*35238bceSAndroid Build Coastguard Worker private: 125*35238bceSAndroid Build Coastguard Worker Thread &m_thread; 126*35238bceSAndroid Build Coastguard Worker std::stringstream m_stream; 127*35238bceSAndroid Build Coastguard Worker }; 128*35238bceSAndroid Build Coastguard Worker 129*35238bceSAndroid Build Coastguard Worker class Message 130*35238bceSAndroid Build Coastguard Worker { 131*35238bceSAndroid Build Coastguard Worker public: Message(uint64_t time,const char * message)132*35238bceSAndroid Build Coastguard Worker Message(uint64_t time, const char *message) : m_time(time), m_message(message) 133*35238bceSAndroid Build Coastguard Worker { 134*35238bceSAndroid Build Coastguard Worker } 135*35238bceSAndroid Build Coastguard Worker getTime(void) const136*35238bceSAndroid Build Coastguard Worker uint64_t getTime(void) const 137*35238bceSAndroid Build Coastguard Worker { 138*35238bceSAndroid Build Coastguard Worker return m_time; 139*35238bceSAndroid Build Coastguard Worker } getMessage(void) const140*35238bceSAndroid Build Coastguard Worker const std::string &getMessage(void) const 141*35238bceSAndroid Build Coastguard Worker { 142*35238bceSAndroid Build Coastguard Worker return m_message; 143*35238bceSAndroid Build Coastguard Worker } 144*35238bceSAndroid Build Coastguard Worker 145*35238bceSAndroid Build Coastguard Worker static const MessageBuilder::EndToken End; 146*35238bceSAndroid Build Coastguard Worker 147*35238bceSAndroid Build Coastguard Worker private: 148*35238bceSAndroid Build Coastguard Worker uint64_t m_time; 149*35238bceSAndroid Build Coastguard Worker std::string m_message; 150*35238bceSAndroid Build Coastguard Worker }; 151*35238bceSAndroid Build Coastguard Worker 152*35238bceSAndroid Build Coastguard Worker // Base class for operations executed by threads 153*35238bceSAndroid Build Coastguard Worker class Operation 154*35238bceSAndroid Build Coastguard Worker { 155*35238bceSAndroid Build Coastguard Worker public: 156*35238bceSAndroid Build Coastguard Worker Operation(const char *name); 157*35238bceSAndroid Build Coastguard Worker virtual ~Operation(void); 158*35238bceSAndroid Build Coastguard Worker getName(void) const159*35238bceSAndroid Build Coastguard Worker const char *getName(void) const 160*35238bceSAndroid Build Coastguard Worker { 161*35238bceSAndroid Build Coastguard Worker return m_name; 162*35238bceSAndroid Build Coastguard Worker } getEvent(void)163*35238bceSAndroid Build Coastguard Worker de::SharedPtr<Event> getEvent(void) 164*35238bceSAndroid Build Coastguard Worker { 165*35238bceSAndroid Build Coastguard Worker return m_event; 166*35238bceSAndroid Build Coastguard Worker } 167*35238bceSAndroid Build Coastguard Worker readObject(de::SharedPtr<Object> object)168*35238bceSAndroid Build Coastguard Worker void readObject(de::SharedPtr<Object> object) 169*35238bceSAndroid Build Coastguard Worker { 170*35238bceSAndroid Build Coastguard Worker object->read(m_event, m_deps); 171*35238bceSAndroid Build Coastguard Worker } modifyObject(de::SharedPtr<Object> object)172*35238bceSAndroid Build Coastguard Worker void modifyObject(de::SharedPtr<Object> object) 173*35238bceSAndroid Build Coastguard Worker { 174*35238bceSAndroid Build Coastguard Worker object->modify(m_event, m_deps); 175*35238bceSAndroid Build Coastguard Worker } 176*35238bceSAndroid Build Coastguard Worker 177*35238bceSAndroid Build Coastguard Worker virtual void exec(Thread &thread) = 0; //!< Overwritten by inherited class to perform actual operation 178*35238bceSAndroid Build Coastguard Worker virtual void execute( 179*35238bceSAndroid Build Coastguard Worker Thread &thread); //!< May Be overwritten by inherited class to change how syncronization is done 180*35238bceSAndroid Build Coastguard Worker 181*35238bceSAndroid Build Coastguard Worker protected: 182*35238bceSAndroid Build Coastguard Worker const char *m_name; 183*35238bceSAndroid Build Coastguard Worker std::vector<de::SharedPtr<Event>> m_deps; 184*35238bceSAndroid Build Coastguard Worker de::SharedPtr<Event> m_event; 185*35238bceSAndroid Build Coastguard Worker 186*35238bceSAndroid Build Coastguard Worker Operation(const Operation &); 187*35238bceSAndroid Build Coastguard Worker Operation &operator=(const Operation &); 188*35238bceSAndroid Build Coastguard Worker }; 189*35238bceSAndroid Build Coastguard Worker 190*35238bceSAndroid Build Coastguard Worker class Thread : public de::Thread 191*35238bceSAndroid Build Coastguard Worker { 192*35238bceSAndroid Build Coastguard Worker public: 193*35238bceSAndroid Build Coastguard Worker enum ThreadStatus 194*35238bceSAndroid Build Coastguard Worker { 195*35238bceSAndroid Build Coastguard Worker THREADSTATUS_NOT_STARTED = 0, 196*35238bceSAndroid Build Coastguard Worker THREADSTATUS_INIT_FAILED, 197*35238bceSAndroid Build Coastguard Worker THREADSTATUS_RUNNING, 198*35238bceSAndroid Build Coastguard Worker THREADSTATUS_READY, 199*35238bceSAndroid Build Coastguard Worker THREADSTATUS_FAILED, 200*35238bceSAndroid Build Coastguard Worker THREADSTATUS_NOT_SUPPORTED 201*35238bceSAndroid Build Coastguard Worker }; 202*35238bceSAndroid Build Coastguard Worker Thread(uint32_t seed); 203*35238bceSAndroid Build Coastguard Worker ~Thread(void); 204*35238bceSAndroid Build Coastguard Worker init(void)205*35238bceSAndroid Build Coastguard Worker virtual void init(void) 206*35238bceSAndroid Build Coastguard Worker { 207*35238bceSAndroid Build Coastguard Worker } //!< Called first before any Operation 208*35238bceSAndroid Build Coastguard Worker 209*35238bceSAndroid Build Coastguard Worker // \todo [mika] Should the result of execution be passed to deinit? deinit(void)210*35238bceSAndroid Build Coastguard Worker virtual void deinit(void) 211*35238bceSAndroid Build Coastguard Worker { 212*35238bceSAndroid Build Coastguard Worker } //!< Called after after operation 213*35238bceSAndroid Build Coastguard Worker 214*35238bceSAndroid Build Coastguard Worker void addOperation(Operation *operation); 215*35238bceSAndroid Build Coastguard Worker 216*35238bceSAndroid Build Coastguard Worker void exec(void); 217*35238bceSAndroid Build Coastguard Worker 218*35238bceSAndroid Build Coastguard Worker uint8_t *getUnusedData( 219*35238bceSAndroid Build Coastguard Worker size_t size); //!< Return data pointer that contains at least size bytes. Valid until next call 220*35238bceSAndroid Build Coastguard Worker getStatus(void) const221*35238bceSAndroid Build Coastguard Worker ThreadStatus getStatus(void) const 222*35238bceSAndroid Build Coastguard Worker { 223*35238bceSAndroid Build Coastguard Worker de::ScopedLock lock(m_statusLock); 224*35238bceSAndroid Build Coastguard Worker return m_status; 225*35238bceSAndroid Build Coastguard Worker } setStatus(ThreadStatus status)226*35238bceSAndroid Build Coastguard Worker void setStatus(ThreadStatus status) 227*35238bceSAndroid Build Coastguard Worker { 228*35238bceSAndroid Build Coastguard Worker de::ScopedLock lock(m_statusLock); 229*35238bceSAndroid Build Coastguard Worker m_status = status; 230*35238bceSAndroid Build Coastguard Worker } 231*35238bceSAndroid Build Coastguard Worker newMessage(void)232*35238bceSAndroid Build Coastguard Worker MessageBuilder newMessage(void) 233*35238bceSAndroid Build Coastguard Worker { 234*35238bceSAndroid Build Coastguard Worker return MessageBuilder(*this); 235*35238bceSAndroid Build Coastguard Worker } getRandom(void)236*35238bceSAndroid Build Coastguard Worker de::Random &getRandom(void) 237*35238bceSAndroid Build Coastguard Worker { 238*35238bceSAndroid Build Coastguard Worker return m_random; 239*35238bceSAndroid Build Coastguard Worker } 240*35238bceSAndroid Build Coastguard Worker 241*35238bceSAndroid Build Coastguard Worker // Used to by test case to read log messages 242*35238bceSAndroid Build Coastguard Worker int getMessageCount(void) const; 243*35238bceSAndroid Build Coastguard Worker Message getMessage(int index) const; 244*35238bceSAndroid Build Coastguard Worker 245*35238bceSAndroid Build Coastguard Worker // Used by message builder 246*35238bceSAndroid Build Coastguard Worker void pushMessage(const std::string &str); 247*35238bceSAndroid Build Coastguard Worker 248*35238bceSAndroid Build Coastguard Worker private: 249*35238bceSAndroid Build Coastguard Worker virtual void run(void); 250*35238bceSAndroid Build Coastguard Worker 251*35238bceSAndroid Build Coastguard Worker std::vector<Operation *> m_operations; 252*35238bceSAndroid Build Coastguard Worker de::Random m_random; 253*35238bceSAndroid Build Coastguard Worker 254*35238bceSAndroid Build Coastguard Worker mutable de::Mutex m_messageLock; 255*35238bceSAndroid Build Coastguard Worker std::vector<Message> m_messages; 256*35238bceSAndroid Build Coastguard Worker mutable de::Mutex m_statusLock; 257*35238bceSAndroid Build Coastguard Worker ThreadStatus m_status; 258*35238bceSAndroid Build Coastguard Worker std::vector<uint8_t> m_unusedData; 259*35238bceSAndroid Build Coastguard Worker 260*35238bceSAndroid Build Coastguard Worker // Disabled 261*35238bceSAndroid Build Coastguard Worker Thread(const Thread &); 262*35238bceSAndroid Build Coastguard Worker Thread operator=(const Thread &); 263*35238bceSAndroid Build Coastguard Worker }; 264*35238bceSAndroid Build Coastguard Worker 265*35238bceSAndroid Build Coastguard Worker class DataBlock : public Object 266*35238bceSAndroid Build Coastguard Worker { 267*35238bceSAndroid Build Coastguard Worker public: 268*35238bceSAndroid Build Coastguard Worker DataBlock(de::SharedPtr<Event> event); 269*35238bceSAndroid Build Coastguard Worker 270*35238bceSAndroid Build Coastguard Worker void setData(size_t size, const void *data); getData(void) const271*35238bceSAndroid Build Coastguard Worker const uint8_t *getData(void) const 272*35238bceSAndroid Build Coastguard Worker { 273*35238bceSAndroid Build Coastguard Worker return &(m_data[0]); 274*35238bceSAndroid Build Coastguard Worker } getSize(void) const275*35238bceSAndroid Build Coastguard Worker size_t getSize(void) const 276*35238bceSAndroid Build Coastguard Worker { 277*35238bceSAndroid Build Coastguard Worker return m_data.size(); 278*35238bceSAndroid Build Coastguard Worker } 279*35238bceSAndroid Build Coastguard Worker 280*35238bceSAndroid Build Coastguard Worker private: 281*35238bceSAndroid Build Coastguard Worker std::vector<uint8_t> m_data; 282*35238bceSAndroid Build Coastguard Worker }; 283*35238bceSAndroid Build Coastguard Worker 284*35238bceSAndroid Build Coastguard Worker class CompareData : public Operation 285*35238bceSAndroid Build Coastguard Worker { 286*35238bceSAndroid Build Coastguard Worker public: 287*35238bceSAndroid Build Coastguard Worker CompareData(de::SharedPtr<DataBlock> a, de::SharedPtr<DataBlock> b); 288*35238bceSAndroid Build Coastguard Worker void exec(Thread &thread); 289*35238bceSAndroid Build Coastguard Worker 290*35238bceSAndroid Build Coastguard Worker private: 291*35238bceSAndroid Build Coastguard Worker de::SharedPtr<DataBlock> m_a; 292*35238bceSAndroid Build Coastguard Worker de::SharedPtr<DataBlock> m_b; 293*35238bceSAndroid Build Coastguard Worker }; 294*35238bceSAndroid Build Coastguard Worker 295*35238bceSAndroid Build Coastguard Worker } // namespace ThreadUtil 296*35238bceSAndroid Build Coastguard Worker } // namespace tcu 297*35238bceSAndroid Build Coastguard Worker 298*35238bceSAndroid Build Coastguard Worker #endif // _TCUTHREADUTIL_HPP 299