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* getDummyData (size_t size); //!< Return data pointer that contains at least size bytes. Valid until next call
179 ThreadStatus getStatus (void) const { return m_status; }
181 MessageBuilder newMessage (void) { return MessageBuilder(*this); }
182 de::Random& getRandom (void) { return m_random; }
184 // Used to by test case to read log messages
185 int getMessageCount (void) const;
186 Message getMessage (int index) const;
188 // Used by message builder
189 void pushMessage (const std::string& str);
192 virtual void run (void);
194 std::vector<Operation*> m_operations;
197 mutable de::Mutex m_messageLock;
198 std::vector<Message> m_messages;
199 ThreadStatus m_status;
200 std::vector<deUint8> m_dummyData;
203 Thread (const Thread&);
204 Thread operator= (const Thread&);
207 class DataBlock : public Object
210 DataBlock (de::SharedPtr<Event> event);
212 void setData (size_t size, const void* data);
213 const deUint8* getData (void) const { return &(m_data[0]); }
214 size_t getSize (void) const { return m_data.size(); }
217 std::vector<deUint8> m_data;
221 class CompareData : public Operation
224 CompareData (de::SharedPtr<DataBlock> a, de::SharedPtr<DataBlock> b);
225 void exec (Thread& thread);
228 de::SharedPtr<DataBlock> m_a;
229 de::SharedPtr<DataBlock> m_b;
235 #endif // _TCUTHREADUTIL_HPP