1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program Tester Core
3 * ----------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Thread test utilities
22 *//*--------------------------------------------------------------------*/
24 #include "tcuThreadUtil.hpp"
38 : m_result (RESULT_NOT_READY)
48 void Event::setResult (Result result)
51 DE_ASSERT(m_result == RESULT_NOT_READY);
55 for (int i = 0; i < m_waiterCount; i++)
56 m_waiters.increment();
59 Event::Result Event::waitReady (void)
63 if (m_result == RESULT_NOT_READY)
73 m_waiters.decrement();
78 Object::Object (const char* type, SharedPtr<Event> e)
84 Object::~Object (void)
88 void Object::read (SharedPtr<Event> event, std::vector<SharedPtr<Event> >& deps)
90 // Make call depend on last modifying call
91 deps.push_back(m_modify);
93 // Add read dependency
94 m_reads.push_back(event);
97 void Object::modify (SharedPtr<Event> event, std::vector<SharedPtr<Event> >& deps)
99 // Make call depend on all reads
100 for (int readNdx = 0; readNdx < (int)m_reads.size(); readNdx++)
102 deps.push_back(m_reads[readNdx]);
104 deps.push_back(m_modify);
106 // Update last modifying call
109 // Clear read dependencies of last "version" of this object
113 Operation::Operation (const char* name)
115 , m_event (new Event)
119 Operation::~Operation (void)
123 void Operation::execute (Thread& thread)
127 // Wait for dependencies and check that they succeeded
128 for (int depNdx = 0; depNdx < (int)m_deps.size(); depNdx++)
130 if (m_deps[depNdx]->waitReady() != Event::RESULT_OK)
134 // Try execute operation
143 // Got exception event failed
144 m_event->setResult(Event::RESULT_FAILED);
148 m_event->setResult(Event::RESULT_OK);
151 // Some dependencies failed
152 m_event->setResult(Event::RESULT_FAILED);
156 m_event = SharedPtr<Event>();
159 const MessageBuilder::EndToken Message::End = MessageBuilder::EndToken();
161 void MessageBuilder::operator<< (const EndToken&)
163 m_thread.pushMessage(m_stream.str());
166 Thread::Thread (deUint32 seed)
168 , m_status (THREADSTATUS_NOT_STARTED)
172 Thread::~Thread (void)
174 for (int operationNdx = 0; operationNdx < (int)m_operations.size(); operationNdx++)
175 delete m_operations[operationNdx];
177 m_operations.clear();
180 deUint8* Thread::getDummyData (size_t size)
182 if (m_dummyData.size() < size)
184 m_dummyData.resize(size);
187 return &(m_dummyData[0]);
190 void Thread::addOperation (Operation* operation)
192 m_operations.push_back(operation);
195 void Thread::run (void)
197 m_status = THREADSTATUS_RUNNING;
200 // Reserve at least two messages for each operation
201 m_messages.reserve(m_operations.size()*2);
206 for (int operationNdx = 0; operationNdx < (int)m_operations.size(); operationNdx++)
207 m_operations[operationNdx]->execute(*this);
210 m_status = THREADSTATUS_READY;
212 catch (const tcu::NotSupportedError& e)
214 newMessage() << "tcu::NotSupportedError '" << e.what() << "'" << Message::End;
216 m_status = (initOk ? THREADSTATUS_NOT_SUPPORTED : THREADSTATUS_INIT_FAILED);
218 catch (const tcu::Exception& e)
220 newMessage() << "tcu::Exception '" << e.what() << "'" << Message::End;
222 m_status = (initOk ? THREADSTATUS_FAILED : THREADSTATUS_INIT_FAILED);
224 catch (const std::exception& error)
226 newMessage() << "std::exception '" << error.what() << "'" << Message::End;
228 m_status = (initOk ? THREADSTATUS_FAILED : THREADSTATUS_INIT_FAILED);
232 newMessage() << "Unkown exception" << Message::End;
234 m_status = (initOk ? THREADSTATUS_FAILED : THREADSTATUS_INIT_FAILED);
238 void Thread::exec (void)
243 void Thread::pushMessage (const std::string& str)
245 de::ScopedLock lock(m_messageLock);
246 m_messages.push_back(Message(deGetMicroseconds(), str.c_str()));
249 int Thread::getMessageCount (void) const
251 de::ScopedLock lock(m_messageLock);
252 return (int)(m_messages.size());
255 Message Thread::getMessage (int index) const
257 de::ScopedLock lock(m_messageLock);
258 return m_messages[index];
262 DataBlock::DataBlock (SharedPtr<Event> event)
263 : Object("DataBlock", event)
267 void DataBlock::setData (size_t size, const void* data)
269 m_data = std::vector<deUint8>(size);
270 deMemcpy(&(m_data[0]), data, size);
273 CompareData::CompareData (SharedPtr<DataBlock> a, SharedPtr<DataBlock> b)
274 : Operation ("CompareData")
278 readObject(SharedPtr<Object>(a));
279 readObject(SharedPtr<Object>(b));
282 void CompareData::exec (Thread& thread)
285 DE_ASSERT(m_a->getSize() == m_b->getSize());
287 thread.newMessage() << "Begin -- CompareData" << Message::End;
289 for (int byteNdx = 0; byteNdx < (int)m_a->getSize(); byteNdx++)
291 if (m_a->getData()[byteNdx] != m_b->getData()[byteNdx])
294 thread.newMessage() << "CompareData failed at offset :" << byteNdx << Message::End;
300 thread.newMessage() << "CompareData passed" << Message::End;
302 TCU_FAIL("Data comparision failed");
304 thread.newMessage() << "End -- CompareData" << Message::End;