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 	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 
     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, int numBytes);
     76 	const deUint8*	getDataBlock		(int numBytes);					//!< \note Valid only during call.
     77 
     78 private:
     79 	Call*			m_call;
     80 	int				m_curPos;
     81 };
     82 
     83 class CallWriter
     84 {
     85 public:
     86 					CallWriter			(CallQueue* queue, Call::Function function);
     87 					~CallWriter			(void);
     88 
     89 	void			write				(const deUint8* bytes, int numBytes);
     90 	void			enqueue				(void);
     91 
     92 private:
     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 
    101 class CallQueue
    102 {
    103 public:
    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 
    113 private:
    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 
    127 CallReader&		operator>>	(CallReader& reader, std::string& value);
    128 CallWriter&		operator<<	(CallWriter& writer, const char* str);
    129 
    130 template <typename T>
    131 CallReader& operator>> (CallReader& reader, T& value)
    132 {
    133 	reader.read((deUint8*)&value, sizeof(T));
    134 	return reader;
    135 }
    136 
    137 template <typename T>
    138 CallWriter& 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