gem5-dev@gem5.org

The gem5 Developer List

View all threads

[M] Change in gem5/gem5[develop]: base,python: Add a param type for host sockets.

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/+/69165?usp=email )

Change subject: base,python: Add a param type for host sockets.
......................................................................

base,python: Add a param type for host sockets.

These can either be set to an integer, in which case it's interpreted
as a TCP port, or a string, in which case it's treated as a unix domain
socket. If the unix domain socket is prefixed with a "@", it will be
treated as an abstract socket.

When stored in the ini file, there is always a prefix added to make
parsing the string more systematic and less ambiguous. A port number is
prefixed with "#", an abstract socket with "@", and a socket file with
the prefix "P" for "path".

Change-Id: I1fc7a579074e849b3becd936238c62fb0d9a2087

M src/base/socket.cc
M src/base/socket.hh
M src/python/m5/params.py
M src/python/pybind11/core.cc
4 files changed, 99 insertions(+), 0 deletions(-)

diff --git a/src/base/socket.cc b/src/base/socket.cc
index c401a08..0ef0062 100644
--- a/src/base/socket.cc
+++ b/src/base/socket.cc
@@ -196,6 +196,32 @@
return sfd;
}

+bool
+ListenSocketConfig::parseIni(const std::string &value,

  •    ListenSocketConfig &retval)
    

+{

  • if (value.size() == 0) {

  •    retval = listenSocketEmptyConfig();
    
  •    return true;
    
  • } else if (value[0] == '@') {

  •    retval = listenSocketUnixAbstractConfig(value.substr(1));
    
  •    return true;
    
  • } else if (value[0] == 'P') {

  •    std::filesystem::path p(value.substr(1));
    
  •    retval = listenSocketUnixFileConfig(p.parent_path(), p.filename());
    
  •    return true;
    
  • } else if (value[0] == '#') {

  •    uint64_t port;
    
  •    bool ret = to_number(value.substr(1), port);
    
  •    if (!ret)
    
  •        return false;
    
  •    retval = listenSocketInetConfig(port);
    
  •    return true;
    
  • } else {

  •    panic("Can't interpret %s as a host socket.", value);
    
  • }
    +}

  • ListenSocketInet::ListenSocketInet(const std::string &_name, int port)
    : ListenSocket(_name), _port(port)
    {}
    diff --git a/src/base/socket.hh b/src/base/socket.hh
    index 82e8375..5974348 100644
    --- a/src/base/socket.hh
    +++ b/src/base/socket.hh
    @@ -152,6 +152,8 @@

    operator bool() const { return (bool)builder; }
    
  • static bool parseIni(const std::string &value, ListenSocketConfig
    &retval);

  • private:
    Builder builder;
    };
    diff --git a/src/python/m5/params.py b/src/python/m5/params.py
    index e9047a8..c2c1321 100644
    --- a/src/python/m5/params.py
    +++ b/src/python/m5/params.py
    @@ -1085,6 +1085,62 @@
    code(f"{ret} to_bool({src}, {dest});")

+class HostSocket(ParamValue):

  • cxx_type = "ListenSocketConfig"
  • @classmethod
  • def cxx_predecls(cls, code):
  •    code('#include "base/socket.hh"')
    
  • def init(self, value):
  •    if isinstance(value, HostSocket):
    
  •        self.value = value.value
    
  •    else:
    
  •        self.value = value
    
  • def getValue(self):
  •    from _m5.socket import listenSocketEmptyConfig
    
  •    from _m5.socket import listenSocketInetConfig
    
  •    from _m5.socket import listenSocketUnixFileConfig
    
  •    from _m5.socket import listenSocketUnixAbstractConfig
    
  •    if isinstance(self.value, str):
    
  •        if self.value[0] == '@':
    
  •            return listenSocketUnixAbstractConfig(self.value[1:])
    
  •        else:
    
  •            d, f = os.path.split(self.value)
    
  •            return listenSocketUnixFileConfig(d, f)
    
  •    else:
    
  •        if self.value == 0:
    
  •            return listenSocketEmptyConfig()
    
  •        else:
    
  •            return listenSocketInetConfig(self.value)
    
  • def call(self, value):
  •    self.__init__(value)
    
  •    return value
    
  • def str(self):
  •    if isinstance(self.value, str):
    
  •        return self.value
    
  •    else:
    
  •        return "#" + str(self.value)
    
  • def ini_str(self):
  •    if isinstance(self.value, str):
    
  •        if self.value[0] == '@':
    
  •            return self.value
    
  •        else:
    
  •            return 'P' + self.value
    
  •    else:
    
  •        return "#" + str(self.value)
    
  • @classmethod
  • def cxx_ini_predecls(cls, code):
  •    code('#include "base/socket.hh"')
    
  • @classmethod
  • def cxx_ini_parse(cls, code, src, dest, ret):
  •    code(f"{ret} ListenSocketConfig::parseIni({src}, {dest});")
    
  • def IncEthernetAddr(addr, val=1):
    bytes = [int(x, 16) for x in addr.split(":")]
    bytes[5] += val
    diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc
    index bd83a74..0b03d5a 100644
    --- a/src/python/pybind11/core.cc
    +++ b/src/python/pybind11/core.cc
    @@ -223,6 +223,20 @@
    m.def("setInterpDir", &loader::setInterpDir);
    }

+static void
+init_socket(py::module_ &m_native)
+{

  • py::module_ m_socket = m_native.def_submodule("socket");
  • m_socket
  •    .def("listenSocketEmptyConfig", &listenSocketEmptyConfig)
    
  •    .def("listenSocketInetConfig", &listenSocketInetConfig)
    
  •    .def("listenSocketUnixFileConfig", &listenSocketUnixFileConfig)
    
  •    .def("listenSocketUnixAbstractConfig",
    
  •            &listenSocketUnixAbstractConfig);
    
  • py::class_<ListenSocketConfig>(m_socket, "ListenSocketConfig");
    +}
  • void
    pybind_init_core(py::module_ &m_native)
    {
    @@ -334,6 +348,7 @@
    init_net(m_native);
    init_loader(m_native);
    init_pc(m_native);
  • init_socket(m_native);
    }

} // namespace gem5

--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/69165?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: I1fc7a579074e849b3becd936238c62fb0d9a2087
Gerrit-Change-Number: 69165
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/+/69165?usp=email ) Change subject: base,python: Add a param type for host sockets. ...................................................................... base,python: Add a param type for host sockets. These can either be set to an integer, in which case it's interpreted as a TCP port, or a string, in which case it's treated as a unix domain socket. If the unix domain socket is prefixed with a "@", it will be treated as an abstract socket. When stored in the ini file, there is always a prefix added to make parsing the string more systematic and less ambiguous. A port number is prefixed with "#", an abstract socket with "@", and a socket file with the prefix "P" for "path". Change-Id: I1fc7a579074e849b3becd936238c62fb0d9a2087 --- M src/base/socket.cc M src/base/socket.hh M src/python/m5/params.py M src/python/pybind11/core.cc 4 files changed, 99 insertions(+), 0 deletions(-) diff --git a/src/base/socket.cc b/src/base/socket.cc index c401a08..0ef0062 100644 --- a/src/base/socket.cc +++ b/src/base/socket.cc @@ -196,6 +196,32 @@ return sfd; } +bool +ListenSocketConfig::parseIni(const std::string &value, + ListenSocketConfig &retval) +{ + if (value.size() == 0) { + retval = listenSocketEmptyConfig(); + return true; + } else if (value[0] == '@') { + retval = listenSocketUnixAbstractConfig(value.substr(1)); + return true; + } else if (value[0] == 'P') { + std::filesystem::path p(value.substr(1)); + retval = listenSocketUnixFileConfig(p.parent_path(), p.filename()); + return true; + } else if (value[0] == '#') { + uint64_t port; + bool ret = to_number(value.substr(1), port); + if (!ret) + return false; + retval = listenSocketInetConfig(port); + return true; + } else { + panic("Can't interpret %s as a host socket.", value); + } +} + ListenSocketInet::ListenSocketInet(const std::string &_name, int port) : ListenSocket(_name), _port(port) {} diff --git a/src/base/socket.hh b/src/base/socket.hh index 82e8375..5974348 100644 --- a/src/base/socket.hh +++ b/src/base/socket.hh @@ -152,6 +152,8 @@ operator bool() const { return (bool)builder; } + static bool parseIni(const std::string &value, ListenSocketConfig &retval); + private: Builder builder; }; diff --git a/src/python/m5/params.py b/src/python/m5/params.py index e9047a8..c2c1321 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1085,6 +1085,62 @@ code(f"{ret} to_bool({src}, {dest});") +class HostSocket(ParamValue): + cxx_type = "ListenSocketConfig" + @classmethod + def cxx_predecls(cls, code): + code('#include "base/socket.hh"') + + def __init__(self, value): + if isinstance(value, HostSocket): + self.value = value.value + else: + self.value = value + + def getValue(self): + from _m5.socket import listenSocketEmptyConfig + from _m5.socket import listenSocketInetConfig + from _m5.socket import listenSocketUnixFileConfig + from _m5.socket import listenSocketUnixAbstractConfig + if isinstance(self.value, str): + if self.value[0] == '@': + return listenSocketUnixAbstractConfig(self.value[1:]) + else: + d, f = os.path.split(self.value) + return listenSocketUnixFileConfig(d, f) + else: + if self.value == 0: + return listenSocketEmptyConfig() + else: + return listenSocketInetConfig(self.value) + + def __call__(self, value): + self.__init__(value) + return value + + def __str__(self): + if isinstance(self.value, str): + return self.value + else: + return "#" + str(self.value) + + def ini_str(self): + if isinstance(self.value, str): + if self.value[0] == '@': + return self.value + else: + return 'P' + self.value + else: + return "#" + str(self.value) + + @classmethod + def cxx_ini_predecls(cls, code): + code('#include "base/socket.hh"') + + @classmethod + def cxx_ini_parse(cls, code, src, dest, ret): + code(f"{ret} ListenSocketConfig::parseIni({src}, {dest});") + def IncEthernetAddr(addr, val=1): bytes = [int(x, 16) for x in addr.split(":")] bytes[5] += val diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc index bd83a74..0b03d5a 100644 --- a/src/python/pybind11/core.cc +++ b/src/python/pybind11/core.cc @@ -223,6 +223,20 @@ m.def("setInterpDir", &loader::setInterpDir); } +static void +init_socket(py::module_ &m_native) +{ + py::module_ m_socket = m_native.def_submodule("socket"); + m_socket + .def("listenSocketEmptyConfig", &listenSocketEmptyConfig) + .def("listenSocketInetConfig", &listenSocketInetConfig) + .def("listenSocketUnixFileConfig", &listenSocketUnixFileConfig) + .def("listenSocketUnixAbstractConfig", + &listenSocketUnixAbstractConfig); + + py::class_<ListenSocketConfig>(m_socket, "ListenSocketConfig"); +} + void pybind_init_core(py::module_ &m_native) { @@ -334,6 +348,7 @@ init_net(m_native); init_loader(m_native); init_pc(m_native); + init_socket(m_native); } } // namespace gem5 -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69165?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: I1fc7a579074e849b3becd936238c62fb0d9a2087 Gerrit-Change-Number: 69165 Gerrit-PatchSet: 1 Gerrit-Owner: Gabe Black <gabe.black@gmail.com> Gerrit-CC: Gabe Black <gabeblack@google.com> Gerrit-MessageType: newchange