1 #ifndef _TCUTHREADUTIL_HPP
2 #define _TCUTHREADUTIL_HPP
3 /*-------------------------------------------------------------------------
4 * drawElements Quality Program Tester Core
5 * ----------------------------------------
7 * Copyright 2014 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Thread test utilities
24 *//*--------------------------------------------------------------------*/
26 #include "tcuDefs.hpp"
27 #include "deSharedPtr.hpp"
28 #include "deMutex.hpp"
29 #include "deSemaphore.hpp"
30 #include "deThread.hpp"
31 #include "deRandom.hpp"
40 // Event object for synchronizing threads
53 void setResult (Result result);
54 Result waitReady (void);
55 Result getResult (void) const { return m_result; }
58 volatile Result m_result;
59 volatile int m_waiterCount;
60 de::Semaphore m_waiters;
65 Event& operator= (const Event&);
68 // Base class for objects which modifications should be tracked between threads
72 Object (const char* type, de::SharedPtr<Event> createEvent);
73 virtual ~Object (void);
74 const char* getType (void) const { return m_type; }
76 // Used by class Operation only
77 void read (de::SharedPtr<Event> event, std::vector<de::SharedPtr<Event> >& deps);
78 void modify (de::SharedPtr<Event> event, std::vector<de::SharedPtr<Event> >& deps);
82 de::SharedPtr<Event> m_modify;
83 std::vector<de::SharedPtr<Event> > m_reads;
86 Object (const Object&);
87 Object& operator= (const Object&);
95 MessageBuilder (Thread& thread) : m_thread(thread) {}
96 MessageBuilder (const MessageBuilder& other) : m_thread(other.m_thread), m_stream(other.m_stream.str()) {}
98 MessageBuilder& operator<< (const T& t) { m_stream << t; return *this; }
106 void operator<< (const EndToken&);
110 std::stringstream m_stream;
116 Message (deUint64 time, const char* message) : m_time(time), m_message(message) {}
118 deUint64 getTime (void) const { return m_time; }
119 const std::string& getMessage (void) const { return m_message; }
121 static const MessageBuilder::EndToken End;
125 std::string m_message;
128 // Base class for operations executed by threads
132 Operation (const char* name);
133 virtual ~Operation (void);
135 const char* getName (void) const { return m_name; }
136 de::SharedPtr<Event> getEvent (void) { return m_event; }
138 void readObject (de::SharedPtr<Object> object) { object->read(m_event, m_deps); }
139 void modifyObject (de::SharedPtr<Object> object) { object->modify(m_event, m_deps); }
141 virtual void exec (Thread& thread) = 0; //!< Overwritten by inherited class to perform actual operation
142 virtual void execute (Thread& thread); //!< May Be overwritten by inherited class to change how syncronization is done
146 std::vector<de::SharedPtr<Event> > m_deps;
147 de::SharedPtr<Event> m_event;
149 Operation (const Operation&);
150 Operation& operator= (const Operation&);
153 class Thread : public de::Thread
158 THREADSTATUS_NOT_STARTED = 0,
159 THREADSTATUS_INIT_FAILED,
160 THREADSTATUS_RUNNING,
163 THREADSTATUS_NOT_SUPPORTED
165 Thread (deUint32 seed);
168 virtual void init (void) {} //!< Called first before any Operation
170 // \todo [mika] Should the result of execution be passed to deinit?
171 virtual void deinit (void) {} //!< Called after after operation
173 void addOperation (Operation* operation);
177 deUint8* getUnusedData (size_t size); //!< Return data pointer that contains at least size bytes. Valid until next call
179 ThreadStatus getStatus (void) const { de::ScopedLock lock(m_statusLock); return m_status; }
180 void setStatus (ThreadStatus status) { de::ScopedLock lock(m_statusLock); m_status = status; }
182 MessageBuilder newMessage (void) { return MessageBuilder(*this); }
183 de::Random& getRandom (void) { return m_random; }
185 // Used to by test case to read log messages
186 int getMessageCount (void) const;
187 Message getMessage (int index) const;
189 // Used by message builder
190 void pushMessage (const std::string& str);
193 virtual void run (void);
195 std::vector<Operation*> m_operations;
198 mutable de::Mutex m_messageLock;
199 std::vector<Message> m_messages;
200 mutable de::Mutex m_statusLock;
201 ThreadStatus m_status;
202 std::vector<deUint8> m_unusedData;
205 Thread (const Thread&);
206 Thread operator= (const Thread&);
209 class DataBlock : public Object
212 DataBlock (de::SharedPtr<Event> event);
214 void setData (size_t size, const void* data);
215 const deUint8* getData (void) const { return &(m_data[0]); }
216 size_t getSize (void) const { return m_data.size(); }
219 std::vector<deUint8> m_data;
223 class CompareData : public Operation
226 CompareData (de::SharedPtr<DataBlock> a, de::SharedPtr<DataBlock> b);
227 void exec (Thread& thread);
230 de::SharedPtr<DataBlock> m_a;
231 de::SharedPtr<DataBlock> m_b;
237 #endif // _TCUTHREADUTIL_HPP