Home | History | Annotate | Download | only in executor
      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 
     33 namespace xe
     34 {
     35 
     36 class Call;
     37 class CallReader;
     38 class CallWriter;
     39 class 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 
     45 class Call
     46 {
     47 public:
     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 	size_t						getDataSize			(void) const	{ return m_data.size();			}
     59 	void						setDataSize			(size_t 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 
     64 private:
     65 	Function					m_func;
     66 	std::vector<deUint8>		m_data;
     67 };
     68 
     69 class CallReader
     70 {
     71 public:
     72 					CallReader			(Call* call);
     73 					CallReader			(void) : m_call(DE_NULL), m_curPos(0) {}
     74 
     75 	void			read				(deUint8* bytes, size_t numBytes);
     76 	const deUint8*	getDataBlock		(size_t numBytes);					//!< \note Valid only during call.
     77 	bool			isDataConsumed		(void) const;						//!< all data has been consumed
     78 
     79 private:
     80 					CallReader			(const CallReader& other);	//!< disallowed
     81 	CallReader&		operator=			(const CallReader& other);	//!< disallowed
     82 
     83 	Call*			m_call;
     84 	size_t			m_curPos;
     85 };
     86 
     87 class CallWriter
     88 {
     89 public:
     90 					CallWriter			(CallQueue* queue, Call::Function function);
     91 					~CallWriter			(void);
     92 
     93 	void			write				(const deUint8* bytes, size_t numBytes);
     94 	void			enqueue				(void);
     95 
     96 private:
     97 					CallWriter			(const CallWriter& other);
     98 	CallWriter&		operator=			(const CallWriter& other);
     99 
    100 	CallQueue*		m_queue;
    101 	Call*			m_call;
    102 	bool			m_enqueued;
    103 };
    104 
    105 class CallQueue
    106 {
    107 public:
    108 							CallQueue			(void);
    109 							~CallQueue			(void);
    110 
    111 	void					callNext			(void); //!< Executes and removes first call in queue. Will block if queue is empty.
    112 
    113 	Call*					getEmptyCall		(void);
    114 	void					enqueue				(Call* call);
    115 	void					freeCall			(Call* call);
    116 	void					cancel				(void);
    117 
    118 private:
    119 							CallQueue			(const CallQueue& other);
    120 	CallQueue&				operator=			(const CallQueue& other);
    121 
    122 	bool					m_canceled;
    123 	de::Semaphore			m_callSem;
    124 
    125 	de::Mutex				m_lock;
    126 	std::vector<Call*>		m_calls;
    127 	std::vector<Call*>		m_freeCalls;
    128 	de::RingBuffer<Call*>	m_callQueue;
    129 };
    130 
    131 // Stream operators for call reader / writer.
    132 
    133 CallReader&		operator>>	(CallReader& reader, std::string& value);
    134 CallWriter&		operator<<	(CallWriter& writer, const char* str);
    135 
    136 template <typename T>
    137 CallReader& operator>> (CallReader& reader, T& value)
    138 {
    139 	reader.read((deUint8*)&value, sizeof(T));
    140 	return reader;
    141 }
    142 
    143 template <typename T>
    144 CallWriter& operator<< (CallWriter& writer, T& value)
    145 {
    146 	writer.write((const deUint8*)&value, sizeof(T));
    147 	return writer;
    148 }
    149 
    150 } // xe
    151 
    152 #endif // _XECALLQUEUE_HPP
    153