Line data Source code
1 : //===- llvm/ExecutionEngine/Orc/RawByteChannel.h ----------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
11 : #define LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
12 :
13 : #include "llvm/ADT/StringRef.h"
14 : #include "llvm/ExecutionEngine/Orc/RPCSerialization.h"
15 : #include "llvm/Support/Endian.h"
16 : #include "llvm/Support/Error.h"
17 : #include <cstdint>
18 : #include <mutex>
19 : #include <string>
20 : #include <type_traits>
21 :
22 : namespace llvm {
23 : namespace orc {
24 : namespace rpc {
25 :
26 : /// Interface for byte-streams to be used with RPC.
27 : class RawByteChannel {
28 : public:
29 0 : virtual ~RawByteChannel() = default;
30 :
31 : /// Read Size bytes from the stream into *Dst.
32 : virtual Error readBytes(char *Dst, unsigned Size) = 0;
33 :
34 : /// Read size bytes from *Src and append them to the stream.
35 : virtual Error appendBytes(const char *Src, unsigned Size) = 0;
36 :
37 : /// Flush the stream if possible.
38 : virtual Error send() = 0;
39 :
40 : /// Notify the channel that we're starting a message send.
41 : /// Locks the channel for writing.
42 : template <typename FunctionIdT, typename SequenceIdT>
43 1226 : Error startSendMessage(const FunctionIdT &FnId, const SequenceIdT &SeqNo) {
44 1226 : writeLock.lock();
45 1226 : if (auto Err = serializeSeq(*this, FnId, SeqNo)) {
46 : writeLock.unlock();
47 : return Err;
48 : }
49 : return Error::success();
50 : }
51 :
52 : /// Notify the channel that we're ending a message send.
53 : /// Unlocks the channel for writing.
54 : Error endSendMessage() {
55 : writeLock.unlock();
56 : return Error::success();
57 : }
58 :
59 : /// Notify the channel that we're starting a message receive.
60 : /// Locks the channel for reading.
61 : template <typename FunctionIdT, typename SequenceNumberT>
62 1226 : Error startReceiveMessage(FunctionIdT &FnId, SequenceNumberT &SeqNo) {
63 1226 : readLock.lock();
64 1226 : if (auto Err = deserializeSeq(*this, FnId, SeqNo)) {
65 : readLock.unlock();
66 : return Err;
67 : }
68 : return Error::success();
69 : }
70 :
71 : /// Notify the channel that we're ending a message receive.
72 : /// Unlocks the channel for reading.
73 : Error endReceiveMessage() {
74 : readLock.unlock();
75 : return Error::success();
76 : }
77 :
78 : /// Get the lock for stream reading.
79 : std::mutex &getReadLock() { return readLock; }
80 :
81 : /// Get the lock for stream writing.
82 : std::mutex &getWriteLock() { return writeLock; }
83 :
84 : private:
85 : std::mutex readLock, writeLock;
86 : };
87 :
88 : template <typename ChannelT, typename T>
89 : class SerializationTraits<
90 : ChannelT, T, T,
91 : typename std::enable_if<
92 : std::is_base_of<RawByteChannel, ChannelT>::value &&
93 : (std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value ||
94 : std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
95 : std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
96 : std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
97 : std::is_same<T, char>::value)>::type> {
98 : public:
99 : static Error serialize(ChannelT &C, T V) {
100 : support::endian::byte_swap<T, support::big>(V);
101 3504 : return C.appendBytes(reinterpret_cast<const char *>(&V), sizeof(T));
102 : };
103 :
104 3828 : static Error deserialize(ChannelT &C, T &V) {
105 7656 : if (auto Err = C.readBytes(reinterpret_cast<char *>(&V), sizeof(T)))
106 : return Err;
107 : support::endian::byte_swap<T, support::big>(V);
108 : return Error::success();
109 : };
110 665 : };
111 1330 :
112 : template <typename ChannelT>
113 : class SerializationTraits<ChannelT, bool, bool,
114 : typename std::enable_if<std::is_base_of<
115 : RawByteChannel, ChannelT>::value>::type> {
116 1270 : public:
117 2540 : static Error serialize(ChannelT &C, bool V) {
118 : uint8_t Tmp = V ? 1 : 0;
119 : if (auto Err =
120 : C.appendBytes(reinterpret_cast<const char *>(&Tmp), 1))
121 : return Err;
122 331 : return Error::success();
123 662 : }
124 :
125 : static Error deserialize(ChannelT &C, bool &V) {
126 : uint8_t Tmp = 0;
127 : if (auto Err = C.readBytes(reinterpret_cast<char *>(&Tmp), 1))
128 1374 : return Err;
129 2748 : V = Tmp != 0;
130 : return Error::success();
131 : }
132 : };
133 :
134 1 : template <typename ChannelT>
135 22 : class SerializationTraits<ChannelT, std::string, StringRef,
136 20 : typename std::enable_if<std::is_base_of<
137 40 : RawByteChannel, ChannelT>::value>::type> {
138 : public:
139 : /// RPC channel serialization for std::strings.
140 1 : static Error serialize(RawByteChannel &C, StringRef S) {
141 2 : if (auto Err = serializeSeq(C, static_cast<uint64_t>(S.size())))
142 : return Err;
143 20 : return C.appendBytes((const char *)S.data(), S.size());
144 20 : }
145 40 : };
146 1 :
147 22 : template <typename ChannelT, typename T>
148 : class SerializationTraits<ChannelT, std::string, T,
149 : typename std::enable_if<
150 : std::is_base_of<RawByteChannel, ChannelT>::value &&
151 : (std::is_same<T, const char*>::value ||
152 43 : std::is_same<T, char*>::value)>::type> {
153 62 : public:
154 : static Error serialize(RawByteChannel &C, const char *S) {
155 48 : return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
156 : S);
157 : }
158 193 : };
159 337 :
160 : template <typename ChannelT>
161 98 : class SerializationTraits<ChannelT, std::string, std::string,
162 : typename std::enable_if<std::is_base_of<
163 : RawByteChannel, ChannelT>::value>::type> {
164 243 : public:
165 265 : /// RPC channel serialization for std::strings.
166 0 : static Error serialize(RawByteChannel &C, const std::string &S) {
167 442 : return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
168 0 : S);
169 : }
170 :
171 : /// RPC channel deserialization for std::strings.
172 24 : static Error deserialize(RawByteChannel &C, std::string &S) {
173 : uint64_t Count = 0;
174 24 : if (auto Err = deserializeSeq(C, Count))
175 : return Err;
176 : S.resize(Count);
177 7 : return C.readBytes(&S[0], Count);
178 208 : }
179 14 : };
180 225 :
181 : } // end namespace rpc
182 : } // end namespace orc
183 : } // end namespace llvm
184 221 :
185 228 : #endif // LLVM_EXECUTIONENGINE_ORC_RAWBYTECHANNEL_H
|