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
getFunction(void) const55 Function getFunction (void) const { return m_func; }
setFunction(Function func)56 void setFunction (Function func) { m_func = func; }
57
getDataSize(void) const58 int getDataSize (void) const { return (int)m_data.size(); }
setDataSize(int size)59 void setDataSize (int size) { m_data.resize(size); }
60
getData(void) const61 const deUint8* getData (void) const { return m_data.empty() ? DE_NULL : &m_data[0]; }
getData(void)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);
CallReader(void)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>
operator >>(CallReader & reader,T & value)131 CallReader& operator>> (CallReader& reader, T& value)
132 {
133 reader.read((deUint8*)&value, sizeof(T));
134 return reader;
135 }
136
137 template <typename T>
operator <<(CallWriter & writer,T & value)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