blob: c88e66938851e343e626d34d5bac700b01e78eda [file] [log] [blame]
Jarkko Poyry3c827362014-09-02 11:48:52 +03001#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:
Jarkko Pöyry1592f162015-05-29 14:40:11 -070048 typedef void (*Function) (CallReader& data);
Jarkko Poyry3c827362014-09-02 11:48:52 +030049
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
Jarkko Pöyry745d7c62015-05-19 12:24:51 -070058 size_t getDataSize (void) const { return m_data.size(); }
59 void setDataSize (size_t size) { m_data.resize(size); }
Jarkko Poyry3c827362014-09-02 11:48:52 +030060
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
Jarkko Pöyry745d7c62015-05-19 12:24:51 -070075 void read (deUint8* bytes, size_t numBytes);
76 const deUint8* getDataBlock (size_t numBytes); //!< \note Valid only during call.
Jarkko Pöyry1592f162015-05-29 14:40:11 -070077 bool isDataConsumed (void) const; //!< all data has been consumed
Jarkko Poyry3c827362014-09-02 11:48:52 +030078
79private:
Jarkko Pöyry1592f162015-05-29 14:40:11 -070080 CallReader (const CallReader& other); //!< disallowed
81 CallReader& operator= (const CallReader& other); //!< disallowed
82
Jarkko Poyry3c827362014-09-02 11:48:52 +030083 Call* m_call;
Jarkko Pöyry745d7c62015-05-19 12:24:51 -070084 size_t m_curPos;
Jarkko Poyry3c827362014-09-02 11:48:52 +030085};
86
87class CallWriter
88{
89public:
90 CallWriter (CallQueue* queue, Call::Function function);
91 ~CallWriter (void);
92
Jarkko Pöyry745d7c62015-05-19 12:24:51 -070093 void write (const deUint8* bytes, size_t numBytes);
Jarkko Poyry3c827362014-09-02 11:48:52 +030094 void enqueue (void);
95
96private:
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
105class CallQueue
106{
107public:
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);
Mika Isojärvi57177852015-05-19 13:44:08 -0700116 void cancel (void);
Jarkko Poyry3c827362014-09-02 11:48:52 +0300117
118private:
119 CallQueue (const CallQueue& other);
120 CallQueue& operator= (const CallQueue& other);
121
Mika Isojärvi57177852015-05-19 13:44:08 -0700122 bool m_canceled;
Jarkko Poyry3c827362014-09-02 11:48:52 +0300123 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
133CallReader& operator>> (CallReader& reader, std::string& value);
134CallWriter& operator<< (CallWriter& writer, const char* str);
135
136template <typename T>
137CallReader& operator>> (CallReader& reader, T& value)
138{
139 reader.read((deUint8*)&value, sizeof(T));
140 return reader;
141}
142
143template <typename T>
144CallWriter& 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