gem5-dev@gem5.org

The gem5 Developer List

View all threads

[M] Change in gem5/gem5[develop]: base,cpu,dev: Add a level of indirection for ListenSockets.

GB
Gabe Black (Gerrit)
Tue, Mar 21, 2023 10:53 PM

Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/69162?usp=email )

Change subject: base,cpu,dev: Add a level of indirection for ListenSockets.
......................................................................

base,cpu,dev: Add a level of indirection for ListenSockets.

This makes room for there to be different implementations for different
types of sockets.

Change-Id: I8c959e2c3400caec8242e693e11330e072bc2c5f

M src/base/remote_gdb.cc
M src/base/remote_gdb.hh
M src/base/socket.cc
M src/base/socket.hh
M src/base/vnc/vncserver.cc
M src/base/vnc/vncserver.hh
M src/cpu/nativetrace.cc
M src/cpu/nativetrace.hh
M src/dev/net/ethertap.cc
M src/dev/serial/terminal.cc
M src/dev/serial/terminal.hh
11 files changed, 76 insertions(+), 38 deletions(-)

diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc
index 2e66a92..095b2bd 100644
--- a/src/base/remote_gdb.cc
+++ b/src/base/remote_gdb.cc
@@ -392,10 +392,11 @@

BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) :
incomingConnectionEvent(nullptr), incomingDataEvent(nullptr),

  •    listener(name(), _port), fd(-1), sys(_system),
    
  •    connectEvent(*this), disconnectEvent(*this), trapEvent(this),
    
  •    singleStepEvent(*this)
    

-{}

  •    fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this),
    
  •    trapEvent(this), singleStepEvent(*this)
    

+{

  • listener = listenSocketInetConfig(_port).build(name());
    +}

BaseRemoteGDB::~BaseRemoteGDB()
{
@@ -417,25 +418,22 @@
return;
}

  • listener.listen();
  • listener->listen();

    incomingConnectionEvent =

  •        new IncomingConnectionEvent(this, listener.getfd(), POLLIN);
    
  •        new IncomingConnectionEvent(this, listener->getfd(), POLLIN);
    pollQueue.schedule(incomingConnectionEvent);
    
  • ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n",

  •         curTick(), name(), listener);
    

    }

    void
    BaseRemoteGDB::connect()
    {

  • panic_if(!listener.islistening(),

  • panic_if(!listener->islistening(),
    "Can't accept GDB connections without any threads!");

    pollQueue.remove(incomingConnectionEvent);

  • int sfd = listener.accept();
  • int sfd = listener->accept();

    if (sfd != -1) {
    if (isAttached())
    @@ -448,9 +446,9 @@
    const ListenSocket &
    BaseRemoteGDB::hostSocket() const
    {

  • panic_if(!listener.islistening(),
  • panic_if(!listener->islistening(),
    "Remote GDB socket is unknown until listen() has been
    called.");
  • return listener;
  • return *listener;
    }

void
@@ -513,7 +511,7 @@
assert(selectThreadContext(_tc->contextId()));

  // Now that we have a thread, we can start listening.
  • if (!listener.islistening())
  • if (!listener->islistening())
    listen();
    }

diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh
index 25b7c54..bf10e77 100644
--- a/src/base/remote_gdb.hh
+++ b/src/base/remote_gdb.hh
@@ -231,7 +231,7 @@
IncomingConnectionEvent *incomingConnectionEvent;
IncomingDataEvent *incomingDataEvent;

  • ListenSocket listener;
  • ListenSocketPtr listener;

    // The socket commands come in through.
    int fd;
    diff --git a/src/base/socket.cc b/src/base/socket.cc
    index 1aff73a..5fb8492 100644
    --- a/src/base/socket.cc
    +++ b/src/base/socket.cc
    @@ -269,4 +269,12 @@
    return sfd;
    }

+ListenSocketConfig
+listenSocketInetConfig(int port)
+{

  • return ListenSocketConfig([port](const std::string &name) {
  •    return std::make_unique<ListenSocket>(name, port);
    
  • });
    +}
  • } // namespace gem5
    diff --git a/src/base/socket.hh b/src/base/socket.hh
    index 81f4d62..638ce40 100644
    --- a/src/base/socket.hh
    +++ b/src/base/socket.hh
    @@ -33,6 +33,9 @@
    #include <sys/types.h>
    #include <sys/un.h>

+#include <cassert>
+#include <functional>
+#include <memory>
#include <string>

#include "base/named.hh"
@@ -127,6 +130,33 @@
/** @} */ // end of api_socket
};

+using ListenSocketPtr = std::unique_ptr<ListenSocket>;
+
+class ListenSocketConfig
+{

  • public:
  • using Builder = std::function<ListenSocketPtr(const std::string
    &name)>;
  • ListenSocketConfig() {}
  • ListenSocketConfig(Builder _builder) : builder(_builder) {}
  • ListenSocketPtr
  • build(const std::string &name) const
  • {
  •    assert(builder);
    
  •    return builder(name);
    
  • }
  • operator bool() const { return (bool)builder; }
  • private:
  • Builder builder;
    +};

+static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; }
+
+ListenSocketConfig listenSocketInetConfig(int port);
+
inline static std::ostream &
operator << (std::ostream &os, const ListenSocket &socket)
{
diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc
index 2d32cef..4e5c951 100644
--- a/src/base/vnc/vncserver.cc
+++ b/src/base/vnc/vncserver.cc
@@ -117,8 +117,8 @@
*/
VncServer::VncServer(const Params &p)
: VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number),

  •  listener(p.name, p.port), sendUpdate(false),
    
  •  supportsRawEnc(false), supportsResizeEnc(false)
    
  •  listener(listenSocketInetConfig(p.port).build(p.name)),
    
  •  sendUpdate(false), supportsRawEnc(false), supportsResizeEnc(false)
    
    {
    if (p.port)
    listen();
    @@ -164,9 +164,9 @@
    return;
    }
  • listener.listen();
  • listener->listen();
  • listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
  • listenEvent = new ListenEvent(this, listener->getfd(), POLLIN);
    pollQueue.schedule(listenEvent);
    }

@@ -179,10 +179,10 @@
// thread.
EventQueue::ScopedMigration migrate(eventQueue());

  • if (!listener.islistening())
  • if (!listener->islistening())
    panic("%s: cannot accept a connection if not listening!", name());
  • int fd = listener.accept();
  • int fd = listener->accept();
    if (fd < 0) {
    warn("%s: failed to accept VNC connection!", name());
    return;
    diff --git a/src/base/vnc/vncserver.hh b/src/base/vnc/vncserver.hh
    index 7455799..d493c05 100644
    --- a/src/base/vnc/vncserver.hh
    +++ b/src/base/vnc/vncserver.hh
    @@ -180,7 +180,7 @@
    int number;
    int dataFd; // data stream file describer
  • ListenSocket listener;
  • ListenSocketPtr listener;

    void listen();
    void accept();
    diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc
    index 05fb41b..3070205 100644
    --- a/src/cpu/nativetrace.cc
    +++ b/src/cpu/nativetrace.cc
    @@ -39,14 +39,14 @@
    namespace trace {

NativeTrace::NativeTrace(const Params &p)

  • : ExeTracer(p), native_listener(p.name, 8000)
  • : ExeTracer(p),
    native_listener(listenSocketInetConfig(8000).build(p.name))
    {
    if (ListenSocket::allDisabled())
    fatal("All listeners are disabled!");
  • native_listener.listen();
  • native_listener->listen();
  • fd = native_listener.accept();
  • fd = native_listener->accept();
    }

void
diff --git a/src/cpu/nativetrace.hh b/src/cpu/nativetrace.hh
index a00e97a..a19acac 100644
--- a/src/cpu/nativetrace.hh
+++ b/src/cpu/nativetrace.hh
@@ -71,7 +71,7 @@
protected:
int fd;

  • ListenSocket native_listener;
  • ListenSocketPtr native_listener;
public:

diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc
index 587dba5..7c7a8dc 100644
--- a/src/dev/net/ethertap.cc
+++ b/src/dev/net/ethertap.cc
@@ -245,11 +245,12 @@
void accept();

protected:
  • ListenSocket listener;
  • ListenSocketPtr listener;
    EtherTapStub *tap;
public:
  • TapListener(EtherTapStub *t, int p) : listener(t->name(), p), tap(t) {}
  • TapListener(EtherTapStub *t, int p) :
  •    listener(listenSocketInetConfig(p).build(t->name())), tap(t) {}
    ~TapListener() { delete event; }
    
    void listen();
    

@@ -258,9 +259,9 @@
void
TapListener::listen()
{

  • listener.listen();
  • listener->listen();
  • event = new Event(this, listener.getfd(), POLLIN|POLLERR);
  • event = new Event(this, listener->getfd(), POLLIN|POLLERR);
    pollQueue.schedule(event);
    }

@@ -272,10 +273,10 @@
// thread.
EventQueue::ScopedMigration migrate(tap->eventQueue());

  • if (!listener.islistening())
  • if (!listener->islistening())
    panic("TapListener(accept): cannot accept if we're not
    listening!");
  • int sfd = listener.accept();
  • int sfd = listener->accept();
    if (sfd != -1)
    tap->attach(sfd);
    }
    diff --git a/src/dev/serial/terminal.cc b/src/dev/serial/terminal.cc
    index 02052b5..6e8e435 100644
    --- a/src/dev/serial/terminal.cc
    +++ b/src/dev/serial/terminal.cc
    @@ -121,7 +121,8 @@
    */
    Terminal::Terminal(const Params &p)
    : SerialDevice(p), listenEvent(NULL), dataEvent(NULL),
  •  number(p.number), data_fd(-1), listener(p.name, p.port),
    
  •  number(p.number), data_fd(-1),
    
  •  listener(listenSocketInetConfig(p.port).build(p.name)),
      txbuf(16384), rxbuf(16384), outfile(terminalDump(p))
    
    #if TRACING_ON == 1
    , linebuf(16384)
    @@ -175,19 +176,19 @@
    return;
    }
  • listener.listen();
  • listener->listen();
  • listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
  • listenEvent = new ListenEvent(this, listener->getfd(), POLLIN);
    pollQueue.schedule(listenEvent);
    }

void
Terminal::accept()
{

  • if (!listener.islistening())
  • if (!listener->islistening())
    panic("%s: cannot accept a connection if not listening!", name());
  • int fd = listener.accept();
  • int fd = listener->accept();
    if (data_fd != -1) {
    char message[] = "terminal already attached!\n";
    atomic_write(fd, message, sizeof(message));
    diff --git a/src/dev/serial/terminal.hh b/src/dev/serial/terminal.hh
    index bd6711d..03adc9f 100644
    --- a/src/dev/serial/terminal.hh
    +++ b/src/dev/serial/terminal.hh
    @@ -101,7 +101,7 @@
    OutputStream * terminalDump(const TerminalParams &p);
protected:
  • ListenSocket listener;
  • ListenSocketPtr listener;

    void listen();
    void accept();

--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/69162?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I8c959e2c3400caec8242e693e11330e072bc2c5f
Gerrit-Change-Number: 69162
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black gabe.black@gmail.com
Gerrit-CC: Gabe Black gabeblack@google.com
Gerrit-MessageType: newchange

Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/69162?usp=email ) Change subject: base,cpu,dev: Add a level of indirection for ListenSockets. ...................................................................... base,cpu,dev: Add a level of indirection for ListenSockets. This makes room for there to be different implementations for different types of sockets. Change-Id: I8c959e2c3400caec8242e693e11330e072bc2c5f --- M src/base/remote_gdb.cc M src/base/remote_gdb.hh M src/base/socket.cc M src/base/socket.hh M src/base/vnc/vncserver.cc M src/base/vnc/vncserver.hh M src/cpu/nativetrace.cc M src/cpu/nativetrace.hh M src/dev/net/ethertap.cc M src/dev/serial/terminal.cc M src/dev/serial/terminal.hh 11 files changed, 76 insertions(+), 38 deletions(-) diff --git a/src/base/remote_gdb.cc b/src/base/remote_gdb.cc index 2e66a92..095b2bd 100644 --- a/src/base/remote_gdb.cc +++ b/src/base/remote_gdb.cc @@ -392,10 +392,11 @@ BaseRemoteGDB::BaseRemoteGDB(System *_system, int _port) : incomingConnectionEvent(nullptr), incomingDataEvent(nullptr), - listener(name(), _port), fd(-1), sys(_system), - connectEvent(*this), disconnectEvent(*this), trapEvent(this), - singleStepEvent(*this) -{} + fd(-1), sys(_system), connectEvent(*this), disconnectEvent(*this), + trapEvent(this), singleStepEvent(*this) +{ + listener = listenSocketInetConfig(_port).build(name()); +} BaseRemoteGDB::~BaseRemoteGDB() { @@ -417,25 +418,22 @@ return; } - listener.listen(); + listener->listen(); incomingConnectionEvent = - new IncomingConnectionEvent(this, listener.getfd(), POLLIN); + new IncomingConnectionEvent(this, listener->getfd(), POLLIN); pollQueue.schedule(incomingConnectionEvent); - - ccprintf(std::cerr, "%d: %s: listening for remote gdb on %s\n", - curTick(), name(), listener); } void BaseRemoteGDB::connect() { - panic_if(!listener.islistening(), + panic_if(!listener->islistening(), "Can't accept GDB connections without any threads!"); pollQueue.remove(incomingConnectionEvent); - int sfd = listener.accept(); + int sfd = listener->accept(); if (sfd != -1) { if (isAttached()) @@ -448,9 +446,9 @@ const ListenSocket & BaseRemoteGDB::hostSocket() const { - panic_if(!listener.islistening(), + panic_if(!listener->islistening(), "Remote GDB socket is unknown until listen() has been called."); - return listener; + return *listener; } void @@ -513,7 +511,7 @@ assert(selectThreadContext(_tc->contextId())); // Now that we have a thread, we can start listening. - if (!listener.islistening()) + if (!listener->islistening()) listen(); } diff --git a/src/base/remote_gdb.hh b/src/base/remote_gdb.hh index 25b7c54..bf10e77 100644 --- a/src/base/remote_gdb.hh +++ b/src/base/remote_gdb.hh @@ -231,7 +231,7 @@ IncomingConnectionEvent *incomingConnectionEvent; IncomingDataEvent *incomingDataEvent; - ListenSocket listener; + ListenSocketPtr listener; // The socket commands come in through. int fd; diff --git a/src/base/socket.cc b/src/base/socket.cc index 1aff73a..5fb8492 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -269,4 +269,12 @@ return sfd; } +ListenSocketConfig +listenSocketInetConfig(int port) +{ + return ListenSocketConfig([port](const std::string &name) { + return std::make_unique<ListenSocket>(name, port); + }); +} + } // namespace gem5 diff --git a/src/base/socket.hh b/src/base/socket.hh index 81f4d62..638ce40 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -33,6 +33,9 @@ #include <sys/types.h> #include <sys/un.h> +#include <cassert> +#include <functional> +#include <memory> #include <string> #include "base/named.hh" @@ -127,6 +130,33 @@ /** @} */ // end of api_socket }; +using ListenSocketPtr = std::unique_ptr<ListenSocket>; + +class ListenSocketConfig +{ + public: + using Builder = std::function<ListenSocketPtr(const std::string &name)>; + + ListenSocketConfig() {} + ListenSocketConfig(Builder _builder) : builder(_builder) {} + + ListenSocketPtr + build(const std::string &name) const + { + assert(builder); + return builder(name); + } + + operator bool() const { return (bool)builder; } + + private: + Builder builder; +}; + +static inline ListenSocketConfig listenSocketEmptyConfig() { return {}; } + +ListenSocketConfig listenSocketInetConfig(int port); + inline static std::ostream & operator << (std::ostream &os, const ListenSocket &socket) { diff --git a/src/base/vnc/vncserver.cc b/src/base/vnc/vncserver.cc index 2d32cef..4e5c951 100644 --- a/src/base/vnc/vncserver.cc +++ b/src/base/vnc/vncserver.cc @@ -117,8 +117,8 @@ */ VncServer::VncServer(const Params &p) : VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number), - listener(p.name, p.port), sendUpdate(false), - supportsRawEnc(false), supportsResizeEnc(false) + listener(listenSocketInetConfig(p.port).build(p.name)), + sendUpdate(false), supportsRawEnc(false), supportsResizeEnc(false) { if (p.port) listen(); @@ -164,9 +164,9 @@ return; } - listener.listen(); + listener->listen(); - listenEvent = new ListenEvent(this, listener.getfd(), POLLIN); + listenEvent = new ListenEvent(this, listener->getfd(), POLLIN); pollQueue.schedule(listenEvent); } @@ -179,10 +179,10 @@ // thread. EventQueue::ScopedMigration migrate(eventQueue()); - if (!listener.islistening()) + if (!listener->islistening()) panic("%s: cannot accept a connection if not listening!", name()); - int fd = listener.accept(); + int fd = listener->accept(); if (fd < 0) { warn("%s: failed to accept VNC connection!", name()); return; diff --git a/src/base/vnc/vncserver.hh b/src/base/vnc/vncserver.hh index 7455799..d493c05 100644 --- a/src/base/vnc/vncserver.hh +++ b/src/base/vnc/vncserver.hh @@ -180,7 +180,7 @@ int number; int dataFd; // data stream file describer - ListenSocket listener; + ListenSocketPtr listener; void listen(); void accept(); diff --git a/src/cpu/nativetrace.cc b/src/cpu/nativetrace.cc index 05fb41b..3070205 100644 --- a/src/cpu/nativetrace.cc +++ b/src/cpu/nativetrace.cc @@ -39,14 +39,14 @@ namespace trace { NativeTrace::NativeTrace(const Params &p) - : ExeTracer(p), native_listener(p.name, 8000) + : ExeTracer(p), native_listener(listenSocketInetConfig(8000).build(p.name)) { if (ListenSocket::allDisabled()) fatal("All listeners are disabled!"); - native_listener.listen(); + native_listener->listen(); - fd = native_listener.accept(); + fd = native_listener->accept(); } void diff --git a/src/cpu/nativetrace.hh b/src/cpu/nativetrace.hh index a00e97a..a19acac 100644 --- a/src/cpu/nativetrace.hh +++ b/src/cpu/nativetrace.hh @@ -71,7 +71,7 @@ protected: int fd; - ListenSocket native_listener; + ListenSocketPtr native_listener; public: diff --git a/src/dev/net/ethertap.cc b/src/dev/net/ethertap.cc index 587dba5..7c7a8dc 100644 --- a/src/dev/net/ethertap.cc +++ b/src/dev/net/ethertap.cc @@ -245,11 +245,12 @@ void accept(); protected: - ListenSocket listener; + ListenSocketPtr listener; EtherTapStub *tap; public: - TapListener(EtherTapStub *t, int p) : listener(t->name(), p), tap(t) {} + TapListener(EtherTapStub *t, int p) : + listener(listenSocketInetConfig(p).build(t->name())), tap(t) {} ~TapListener() { delete event; } void listen(); @@ -258,9 +259,9 @@ void TapListener::listen() { - listener.listen(); + listener->listen(); - event = new Event(this, listener.getfd(), POLLIN|POLLERR); + event = new Event(this, listener->getfd(), POLLIN|POLLERR); pollQueue.schedule(event); } @@ -272,10 +273,10 @@ // thread. EventQueue::ScopedMigration migrate(tap->eventQueue()); - if (!listener.islistening()) + if (!listener->islistening()) panic("TapListener(accept): cannot accept if we're not listening!"); - int sfd = listener.accept(); + int sfd = listener->accept(); if (sfd != -1) tap->attach(sfd); } diff --git a/src/dev/serial/terminal.cc b/src/dev/serial/terminal.cc index 02052b5..6e8e435 100644 --- a/src/dev/serial/terminal.cc +++ b/src/dev/serial/terminal.cc @@ -121,7 +121,8 @@ */ Terminal::Terminal(const Params &p) : SerialDevice(p), listenEvent(NULL), dataEvent(NULL), - number(p.number), data_fd(-1), listener(p.name, p.port), + number(p.number), data_fd(-1), + listener(listenSocketInetConfig(p.port).build(p.name)), txbuf(16384), rxbuf(16384), outfile(terminalDump(p)) #if TRACING_ON == 1 , linebuf(16384) @@ -175,19 +176,19 @@ return; } - listener.listen(); + listener->listen(); - listenEvent = new ListenEvent(this, listener.getfd(), POLLIN); + listenEvent = new ListenEvent(this, listener->getfd(), POLLIN); pollQueue.schedule(listenEvent); } void Terminal::accept() { - if (!listener.islistening()) + if (!listener->islistening()) panic("%s: cannot accept a connection if not listening!", name()); - int fd = listener.accept(); + int fd = listener->accept(); if (data_fd != -1) { char message[] = "terminal already attached!\n"; atomic_write(fd, message, sizeof(message)); diff --git a/src/dev/serial/terminal.hh b/src/dev/serial/terminal.hh index bd6711d..03adc9f 100644 --- a/src/dev/serial/terminal.hh +++ b/src/dev/serial/terminal.hh @@ -101,7 +101,7 @@ OutputStream * terminalDump(const TerminalParams &p); protected: - ListenSocket listener; + ListenSocketPtr listener; void listen(); void accept(); -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69162?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: I8c959e2c3400caec8242e693e11330e072bc2c5f Gerrit-Change-Number: 69162 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black <gabe.black@gmail.com> Gerrit-CC: Gabe Black <gabeblack@google.com> Gerrit-MessageType: newchange