xref: /aosp_15_r20/external/deqp/executor/xeCallQueue.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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
56     {
57         return m_func;
58     }
setFunction(Function func)59     void setFunction(Function func)
60     {
61         m_func = func;
62     }
63 
getDataSize(void) const64     size_t getDataSize(void) const
65     {
66         return m_data.size();
67     }
setDataSize(size_t size)68     void setDataSize(size_t size)
69     {
70         m_data.resize(size);
71     }
72 
getData(void) const73     const uint8_t *getData(void) const
74     {
75         return m_data.empty() ? DE_NULL : &m_data[0];
76     }
getData(void)77     uint8_t *getData(void)
78     {
79         return m_data.empty() ? DE_NULL : &m_data[0];
80     }
81 
82 private:
83     Function m_func;
84     std::vector<uint8_t> m_data;
85 };
86 
87 class CallReader
88 {
89 public:
90     CallReader(Call *call);
CallReader(void)91     CallReader(void) : m_call(DE_NULL), m_curPos(0)
92     {
93     }
94 
95     void read(uint8_t *bytes, size_t numBytes);
96     const uint8_t *getDataBlock(size_t numBytes); //!< \note Valid only during call.
97     bool isDataConsumed(void) const;              //!< all data has been consumed
98 
99 private:
100     CallReader(const CallReader &other);            //!< disallowed
101     CallReader &operator=(const CallReader &other); //!< disallowed
102 
103     Call *m_call;
104     size_t m_curPos;
105 };
106 
107 class CallWriter
108 {
109 public:
110     CallWriter(CallQueue *queue, Call::Function function);
111     ~CallWriter(void);
112 
113     void write(const uint8_t *bytes, size_t numBytes);
114     void enqueue(void);
115 
116 private:
117     CallWriter(const CallWriter &other);
118     CallWriter &operator=(const CallWriter &other);
119 
120     CallQueue *m_queue;
121     Call *m_call;
122     bool m_enqueued;
123 };
124 
125 class CallQueue
126 {
127 public:
128     CallQueue(void);
129     ~CallQueue(void);
130 
131     void callNext(void); //!< Executes and removes first call in queue. Will block if queue is empty.
132 
133     Call *getEmptyCall(void);
134     void enqueue(Call *call);
135     void freeCall(Call *call);
136     void cancel(void);
137 
138 private:
139     CallQueue(const CallQueue &other);
140     CallQueue &operator=(const CallQueue &other);
141 
142     bool m_canceled;
143     de::Semaphore m_callSem;
144 
145     de::Mutex m_lock;
146     std::vector<Call *> m_calls;
147     std::vector<Call *> m_freeCalls;
148     de::RingBuffer<Call *> m_callQueue;
149 };
150 
151 // Stream operators for call reader / writer.
152 
153 CallReader &operator>>(CallReader &reader, std::string &value);
154 CallWriter &operator<<(CallWriter &writer, const char *str);
155 
156 template <typename T>
operator >>(CallReader & reader,T & value)157 CallReader &operator>>(CallReader &reader, T &value)
158 {
159     reader.read((uint8_t *)&value, sizeof(T));
160     return reader;
161 }
162 
163 template <typename T>
operator <<(CallWriter & writer,T & value)164 CallWriter &operator<<(CallWriter &writer, T &value)
165 {
166     writer.write((const uint8_t *)&value, sizeof(T));
167     return writer;
168 }
169 
170 } // namespace xe
171 
172 #endif // _XECALLQUEUE_HPP
173