Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===---- SimpleRemoteEPCServer.h - EPC over abstract channel ---*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// EPC over simple abstract channel.
10
//
11
//===----------------------------------------------------------------------===//
12
 
13
#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
14
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H
15
 
16
#include "llvm/ADT/DenseMap.h"
17
#include "llvm/ADT/FunctionExtras.h"
18
#include "llvm/Config/llvm-config.h"
19
#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
20
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
21
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
22
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
23
#include "llvm/ExecutionEngine/Orc/TargetProcess/SimpleExecutorDylibManager.h"
24
#include "llvm/Support/DynamicLibrary.h"
25
#include "llvm/Support/Error.h"
26
 
27
#include <condition_variable>
28
#include <future>
29
#include <memory>
30
#include <mutex>
31
 
32
namespace llvm {
33
namespace orc {
34
 
35
/// A simple EPC server implementation.
36
class SimpleRemoteEPCServer : public SimpleRemoteEPCTransportClient {
37
public:
38
  using ReportErrorFunction = unique_function<void(Error)>;
39
 
40
  /// Dispatches calls to runWrapper.
41
  class Dispatcher {
42
  public:
43
    virtual ~Dispatcher();
44
    virtual void dispatch(unique_function<void()> Work) = 0;
45
    virtual void shutdown() = 0;
46
  };
47
 
48
#if LLVM_ENABLE_THREADS
49
  class ThreadDispatcher : public Dispatcher {
50
  public:
51
    void dispatch(unique_function<void()> Work) override;
52
    void shutdown() override;
53
 
54
  private:
55
    std::mutex DispatchMutex;
56
    bool Running = true;
57
    size_t Outstanding = 0;
58
    std::condition_variable OutstandingCV;
59
  };
60
#endif
61
 
62
  class Setup {
63
    friend class SimpleRemoteEPCServer;
64
 
65
  public:
66
    SimpleRemoteEPCServer &server() { return S; }
67
    StringMap<ExecutorAddr> &bootstrapSymbols() { return BootstrapSymbols; }
68
    std::vector<std::unique_ptr<ExecutorBootstrapService>> &services() {
69
      return Services;
70
    }
71
    void setDispatcher(std::unique_ptr<Dispatcher> D) { S.D = std::move(D); }
72
    void setErrorReporter(unique_function<void(Error)> ReportError) {
73
      S.ReportError = std::move(ReportError);
74
    }
75
 
76
  private:
77
    Setup(SimpleRemoteEPCServer &S) : S(S) {}
78
    SimpleRemoteEPCServer &S;
79
    StringMap<ExecutorAddr> BootstrapSymbols;
80
    std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
81
  };
82
 
83
  static StringMap<ExecutorAddr> defaultBootstrapSymbols();
84
 
85
  template <typename TransportT, typename... TransportTCtorArgTs>
86
  static Expected<std::unique_ptr<SimpleRemoteEPCServer>>
87
  Create(unique_function<Error(Setup &S)> SetupFunction,
88
         TransportTCtorArgTs &&...TransportTCtorArgs) {
89
    auto Server = std::make_unique<SimpleRemoteEPCServer>();
90
    Setup S(*Server);
91
    if (auto Err = SetupFunction(S))
92
      return std::move(Err);
93
 
94
    // Set ReportError up-front so that it can be used if construction
95
    // process fails.
96
    if (!Server->ReportError)
97
      Server->ReportError = [](Error Err) {
98
        logAllUnhandledErrors(std::move(Err), errs(), "SimpleRemoteEPCServer ");
99
      };
100
 
101
    // Attempt to create transport.
102
    auto T = TransportT::Create(
103
        *Server, std::forward<TransportTCtorArgTs>(TransportTCtorArgs)...);
104
    if (!T)
105
      return T.takeError();
106
    Server->T = std::move(*T);
107
    if (auto Err = Server->T->start())
108
      return std::move(Err);
109
 
110
    // If transport creation succeeds then start up services.
111
    Server->Services = std::move(S.services());
112
    Server->Services.push_back(
113
        std::make_unique<rt_bootstrap::SimpleExecutorDylibManager>());
114
    for (auto &Service : Server->Services)
115
      Service->addBootstrapSymbols(S.bootstrapSymbols());
116
 
117
    if (auto Err = Server->sendSetupMessage(std::move(S.BootstrapSymbols)))
118
      return std::move(Err);
119
    return std::move(Server);
120
  }
121
 
122
  /// Set an error reporter for this server.
123
  void setErrorReporter(ReportErrorFunction ReportError) {
124
    this->ReportError = std::move(ReportError);
125
  }
126
 
127
  /// Call to handle an incoming message.
128
  ///
129
  /// Returns 'Disconnect' if the message is a 'detach' message from the remote
130
  /// otherwise returns 'Continue'. If the server has moved to an error state,
131
  /// returns an error, which should be reported and treated as a 'Disconnect'.
132
  Expected<HandleMessageAction>
133
  handleMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo, ExecutorAddr TagAddr,
134
                SimpleRemoteEPCArgBytesVector ArgBytes) override;
135
 
136
  Error waitForDisconnect();
137
 
138
  void handleDisconnect(Error Err) override;
139
 
140
private:
141
  Error sendMessage(SimpleRemoteEPCOpcode OpC, uint64_t SeqNo,
142
                    ExecutorAddr TagAddr, ArrayRef<char> ArgBytes);
143
 
144
  Error sendSetupMessage(StringMap<ExecutorAddr> BootstrapSymbols);
145
 
146
  Error handleResult(uint64_t SeqNo, ExecutorAddr TagAddr,
147
                     SimpleRemoteEPCArgBytesVector ArgBytes);
148
  void handleCallWrapper(uint64_t RemoteSeqNo, ExecutorAddr TagAddr,
149
                         SimpleRemoteEPCArgBytesVector ArgBytes);
150
 
151
  shared::WrapperFunctionResult
152
  doJITDispatch(const void *FnTag, const char *ArgData, size_t ArgSize);
153
 
154
  static shared::CWrapperFunctionResult jitDispatchEntry(void *DispatchCtx,
155
                                                         const void *FnTag,
156
                                                         const char *ArgData,
157
                                                         size_t ArgSize);
158
 
159
  uint64_t getNextSeqNo() { return NextSeqNo++; }
160
  void releaseSeqNo(uint64_t) {}
161
 
162
  using PendingJITDispatchResultsMap =
163
      DenseMap<uint64_t, std::promise<shared::WrapperFunctionResult> *>;
164
 
165
  std::mutex ServerStateMutex;
166
  std::condition_variable ShutdownCV;
167
  enum { ServerRunning, ServerShuttingDown, ServerShutDown } RunState;
168
  Error ShutdownErr = Error::success();
169
  std::unique_ptr<SimpleRemoteEPCTransport> T;
170
  std::unique_ptr<Dispatcher> D;
171
  std::vector<std::unique_ptr<ExecutorBootstrapService>> Services;
172
  ReportErrorFunction ReportError;
173
 
174
  uint64_t NextSeqNo = 0;
175
  PendingJITDispatchResultsMap PendingJITDispatchResults;
176
  std::vector<sys::DynamicLibrary> Dylibs;
177
};
178
 
179
} // end namespace orc
180
} // end namespace llvm
181
 
182
#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_SIMPLEREMOTEEPCSERVER_H