13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements C++ Base Library 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Thread-safe ring buffer template. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deThreadSafeRingBuffer.hpp" 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp" 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deThread.hpp" 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector> 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace de 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Message 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 data; 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Message (deUint16 threadId, deUint16 payload) 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : data((threadId << 16) | payload) 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Message (void) 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : data(0) 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint16 getThreadId (void) const { return data >> 16; } 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint16 getPayload (void) const { return data & 0xffff; } 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Consumer : public Thread 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Consumer (ThreadSafeRingBuffer<Message>& buffer, int numProducers) 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_buffer (buffer) 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_lastPayload.resize(numProducers, 0); 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_payloadSum.resize(numProducers, 0); 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void run (void) 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (;;) 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Message msg = m_buffer.popBack(); 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint16 threadId = msg.getThreadId(); 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (threadId == 0xffff) 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_TEST_ASSERT(de::inBounds<int>(threadId, 0, (int)m_lastPayload.size())); 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_TEST_ASSERT((m_lastPayload[threadId] == 0 && msg.getPayload() == 0) || m_lastPayload[threadId] < msg.getPayload()); 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_lastPayload[threadId] = msg.getPayload(); 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_payloadSum[threadId] += (deUint32)msg.getPayload(); 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 getPayloadSum (deUint16 threadId) const 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return m_payloadSum[threadId]; 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ThreadSafeRingBuffer<Message>& m_buffer; 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint16> m_lastPayload; 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint32> m_payloadSum; 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Producer : public Thread 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Producer (ThreadSafeRingBuffer<Message>& buffer, deUint16 threadId, int dataSize) 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : m_buffer (buffer) 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_threadId (threadId) 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_dataSize (dataSize) 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void run (void) 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Yield to give main thread chance to start other producers. 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deSleep(1); 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < m_dataSize; ndx++) 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_buffer.pushFront(Message(m_threadId, (deUint16)ndx)); 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ThreadSafeRingBuffer<Message>& m_buffer; 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint16 m_threadId; 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_dataSize; 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ThreadSafeRingBuffer_selfTest (void) 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numIterations = 16; 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int iterNdx = 0; iterNdx < numIterations; iterNdx++) 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry Random rnd (iterNdx); 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int bufSize = rnd.getInt(1, 2048); 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numProducers = rnd.getInt(1, 16); 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int numConsumers = rnd.getInt(1, 16); 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int dataSize = rnd.getInt(1000, 10000); 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ThreadSafeRingBuffer<Message> buffer (bufSize); 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Producer*> producers; 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<Consumer*> consumers; 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numProducers; i++) 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry producers.push_back(new Producer(buffer, (deUint16)i, dataSize)); 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numConsumers; i++) 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry consumers.push_back(new Consumer(buffer, numProducers)); 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Start consumers. 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<Consumer*>::iterator i = consumers.begin(); i != consumers.end(); i++) 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (*i)->start(); 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Start producers. 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<Producer*>::iterator i = producers.begin(); i != producers.end(); i++) 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (*i)->start(); 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Wait for producers. 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<Producer*>::iterator i = producers.begin(); i != producers.end(); i++) 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (*i)->join(); 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Write end messages for consumers. 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numConsumers; i++) 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry buffer.pushFront(Message(0xffff, 0)); 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Wait for consumers. 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<Consumer*>::iterator i = consumers.begin(); i != consumers.end(); i++) 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (*i)->join(); 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify payload sums. 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 refSum = 0; 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < dataSize; i++) 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry refSum += (deUint32)(deUint16)i; 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int i = 0; i < numProducers; i++) 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 cmpSum = 0; 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int j = 0; j < numConsumers; j++) 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry cmpSum += consumers[j]->getPayloadSum(i); 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_TEST_ASSERT(refSum == cmpSum); 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Free resources. 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<Producer*>::iterator i = producers.begin(); i != producers.end(); i++) 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete *i; 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (vector<Consumer*>::iterator i = consumers.begin(); i != consumers.end(); i++) 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete *i; 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // de 185