1#ifndef _XECALLQUEUE_HPP 2#define _XECALLQUEUE_HPP 3/*------------------------------------------------------------------------- 4 * drawElements Quality Program Test Executor 5 * ------------------------------------------ 6 * 7 * Copyright 2014 The Android Open Source Project 8 * 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 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 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. 20 * 21 *//*! 22 * \file 23 * \brief Cross-thread function call dispatcher. 24 *//*--------------------------------------------------------------------*/ 25 26#include "xeDefs.hpp" 27#include "deMutex.hpp" 28#include "deSemaphore.hpp" 29#include "deRingBuffer.hpp" 30 31#include <vector> 32 33namespace xe 34{ 35 36class Call; 37class CallReader; 38class CallWriter; 39class CallQueue; 40 41// \todo [2012-07-10 pyry] Optimize memory management in Call 42// \todo [2012-07-10 pyry] CallQueue API could be improved to match TestLog API more closely. 43// In order to do that, reference counting system for call object management is needed. 44 45class Call 46{ 47public: 48 typedef void (*Function) (CallReader data); 49 50 Call (void); 51 ~Call (void); 52 53 void clear (void); 54 55 Function getFunction (void) const { return m_func; } 56 void setFunction (Function func) { m_func = func; } 57 58 int getDataSize (void) const { return (int)m_data.size(); } 59 void setDataSize (int size) { m_data.resize(size); } 60 61 const deUint8* getData (void) const { return m_data.empty() ? DE_NULL : &m_data[0]; } 62 deUint8* getData (void) { return m_data.empty() ? DE_NULL : &m_data[0]; } 63 64private: 65 Function m_func; 66 std::vector<deUint8> m_data; 67}; 68 69class CallReader 70{ 71public: 72 CallReader (Call* call); 73 CallReader (void) : m_call(DE_NULL), m_curPos(0) {} 74 75 void read (deUint8* bytes, int numBytes); 76 const deUint8* getDataBlock (int numBytes); //!< \note Valid only during call. 77 78private: 79 Call* m_call; 80 int m_curPos; 81}; 82 83class CallWriter 84{ 85public: 86 CallWriter (CallQueue* queue, Call::Function function); 87 ~CallWriter (void); 88 89 void write (const deUint8* bytes, int numBytes); 90 void enqueue (void); 91 92private: 93 CallWriter (const CallWriter& other); 94 CallWriter& operator= (const CallWriter& other); 95 96 CallQueue* m_queue; 97 Call* m_call; 98 bool m_enqueued; 99}; 100 101class CallQueue 102{ 103public: 104 CallQueue (void); 105 ~CallQueue (void); 106 107 void callNext (void); //!< Executes and removes first call in queue. Will block if queue is empty. 108 109 Call* getEmptyCall (void); 110 void enqueue (Call* call); 111 void freeCall (Call* call); 112 113private: 114 CallQueue (const CallQueue& other); 115 CallQueue& operator= (const CallQueue& other); 116 117 de::Semaphore m_callSem; 118 119 de::Mutex m_lock; 120 std::vector<Call*> m_calls; 121 std::vector<Call*> m_freeCalls; 122 de::RingBuffer<Call*> m_callQueue; 123}; 124 125// Stream operators for call reader / writer. 126 127CallReader& operator>> (CallReader& reader, std::string& value); 128CallWriter& operator<< (CallWriter& writer, const char* str); 129 130template <typename T> 131CallReader& operator>> (CallReader& reader, T& value) 132{ 133 reader.read((deUint8*)&value, sizeof(T)); 134 return reader; 135} 136 137template <typename T> 138CallWriter& operator<< (CallWriter& writer, T& value) 139{ 140 writer.write((const deUint8*)&value, sizeof(T)); 141 return writer; 142} 143 144} // xe 145 146#endif // _XECALLQUEUE_HPP 147