diff --git a/src/Makefile b/src/Makefile index b57047245..b4178b680 100644 --- a/src/Makefile +++ b/src/Makefile @@ -44,7 +44,8 @@ UARCH_RAM_IMAGE ?= ../uarch/uarch-ram.bin release?=no sanitize?=no coverage?=no -nothreads?=no +threads?=yes +slirp?=yes COVERAGE_TOOLCHAIN?=gcc COVERAGE_OUTPUT_DIR?=coverage @@ -132,15 +133,22 @@ PROFILE_DATA= endif -LIBCARTESI_LIBS=$(SLIRP_LIB) -LIBCARTESI_GRPC_LIBS=$(SLIRP_LIB) $(GRPC_PROTOBUF_LIB) -LIBCARTESI_JSONRPC_LIBS=$(SLIRP_LIB) -LUACARTESI_LIBS=$(SLIRP_LIB) -LUACARTESI_GRPC_LIBS=$(SLIRP_LIB) $(GRPC_PROTOBUF_LIB) -LUACARTESI_JSONRPC_LIBS=$(SLIRP_LIB) -REMOTE_CARTESI_MACHINE_LIBS=$(SLIRP_LIB) $(GRPC_PROTOBUF_LIB) -JSONRPC_REMOTE_CARTESI_MACHINE_LIBS=$(SLIRP_LIB) -TEST_MACHINE_C_API_LIBS=$(SLIRP_LIB) $(GRPC_PROTOBUF_LIB) +ifeq ($(slirp),yes) +INCS+=$(SLIRP_INC) +LIBCARTESI_COMMON_LIBS+=$(SLIRP_LIB) +else +DEFS+=-DNO_SLIRP +endif + +LIBCARTESI_LIBS=$(LIBCARTESI_COMMON_LIBS) +LIBCARTESI_GRPC_LIBS=$(LIBCARTESI_COMMON_LIBS) $(GRPC_PROTOBUF_LIB) +LIBCARTESI_JSONRPC_LIBS=$(LIBCARTESI_COMMON_LIBS) +LUACARTESI_LIBS=$(LIBCARTESI_COMMON_LIBS) +LUACARTESI_GRPC_LIBS=$(LIBCARTESI_COMMON_LIBS) $(GRPC_PROTOBUF_LIB) +LUACARTESI_JSONRPC_LIBS=$(LIBCARTESI_COMMON_LIBS) +REMOTE_CARTESI_MACHINE_LIBS=$(LIBCARTESI_COMMON_LIBS) $(GRPC_PROTOBUF_LIB) +JSONRPC_REMOTE_CARTESI_MACHINE_LIBS=$(LIBCARTESI_COMMON_LIBS) +TEST_MACHINE_C_API_LIBS=$(LIBCARTESI_COMMON_LIBS) $(GRPC_PROTOBUF_LIB) HASH_LIBS= #DEFS+= -DMT_ALL_DIRTY @@ -153,7 +161,7 @@ INCS+= \ -I../third-party/tiny_sha3 \ -I../third-party/downloads \ -I../third-party/mongoose-7.12 \ - $(SLIRP_INC) $(BOOST_INC) + $(BOOST_INC) # Use 64-bit offsets for file operations in POSIX APIs DEFS+=-D_FILE_OFFSET_BITS=64 @@ -271,7 +279,7 @@ EMPTY:= SPACE:=$(EMPTY) $(EMPTY) CLANG_TIDY_HEADER_FILTER=$(PWD)/($(subst $(SPACE),|,$(LINTER_HEADERS))) -ifeq ($(nothreads),no) +ifeq ($(threads),yes) CFLAGS+=$(PTHREAD_CFLAGS) CXXFLAGS+=$(PTHREAD_CFLAGS) LDFLAGS+=$(PTHREAD_LDFLAGS) diff --git a/src/machine.cpp b/src/machine.cpp index 4d377791b..512113c49 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -462,17 +462,31 @@ machine::machine(const machine_config &c, const machine_runtime_config &r) : pma_name = "VirtIO Console"; vdev = std::make_unique(m_vdevs.size()); } else if constexpr (std::is_same_v) { +#ifdef HAVE_POSIX_FS pma_name = "VirtIO 9P"; vdev = std::make_unique(m_vdevs.size(), vdev_config.tag, vdev_config.host_directory); +#else + throw std::invalid_argument("virtio 9p device is unsupported in this platform"); +#endif } else if constexpr (std::is_same_v) { +#ifdef HAVE_SLIRP pma_name = "VirtIO Net User"; vdev = std::make_unique(m_vdevs.size(), std::make_unique(vdev_config)); +#else + throw std::invalid_argument("virtio network user device is unsupported in this platform"); + +#endif } else if constexpr (std::is_same_v) { +#ifdef HAVE_TUNTAP pma_name = "VirtIO Net TUN/TAP"; vdev = std::make_unique(m_vdevs.size(), std::make_unique(vdev_config.iface)); +#else + + throw std::invalid_argument("virtio network TUN/TAP device is unsupported in this platform"); +#endif } else { throw std::invalid_argument("invalid virtio device configuration"); } diff --git a/src/os-features.h b/src/os-features.h new file mode 100644 index 000000000..895b239ef --- /dev/null +++ b/src/os-features.h @@ -0,0 +1,68 @@ +// Copyright Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with this program (see COPYING). If not, see . +// + +#ifndef OS_FEATURES_H +#define OS_FEATURES_H + +#if !defined(NO_TTY) +#define HAVE_TTY +#endif + +#if !defined(NO_THREADS) +#define HAVE_THREADS +#endif + +#if !defined(NO_TERMIOS) && !defined(_WIN32) && !defined(__wasi__) +#define HAVE_TERMIOS +#endif + +#if !defined(NO_IOCTL) && !defined(_WIN32) && !defined(__wasi__) +#define HAVE_IOCTL +#endif + +#if !defined(NO_MMAP) && !defined(_WIN32) && !defined(__wasi__) +#define HAVE_MMAP +#endif + +#if !defined(NO_MKDIR) +#define HAVE_MKDIR +#endif + +#if !defined(NO_TUNTAP) && defined(__linux__) +#define HAVE_TUNTAP +#endif + +#if !defined(NO_SLIRP) && !defined(__wasi__) +#define HAVE_SLIRP +#endif + +#if !defined(NO_SIGACTION) && !defined(__wasi__) && !defined(_WIN32) +#define HAVE_SIGACTION +#endif + +#if !defined(NO_SELECT) +#define HAVE_SELECT +#endif + +#if !defined(NO_POSIX_FILE) && !defined(__wasi__) && !defined(_WIN32) +#define HAVE_POSIX_FS +#endif + +#if !defined(NO_USLEEP) && defined(__unix__) +#define HAVE_USLEEP +#endif + +#endif diff --git a/src/os.cpp b/src/os.cpp index aa51903bc..cb1a48750 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -14,33 +14,8 @@ // with this program (see COPYING). If not, see . // -#if !defined(NO_TTY) -#define HAVE_TTY -#endif - -#if !defined(NO_THREADS) -#define HAVE_THREADS -#endif - -#if !defined(_WIN32) && !defined(__wasi__) && !defined(NO_TERMIOS) -#define HAVE_TERMIOS -#endif - -#if !defined(_WIN32) && !defined(__wasi__) && !defined(NO_IOCTL) -#define HAVE_IOCTL -#endif - -#if !defined(_WIN32) && !defined(__wasi__) && !defined(NO_MMAP) -#define HAVE_MMAP -#endif - -#if !defined(NO_MKDIR) -#define HAVE_MKDIR -#endif - #include #include -#include #include #include #include @@ -49,9 +24,14 @@ #include #include +#include "os-features.h" #include "os.h" #include "unique-c-ptr.h" +#ifdef HAVE_SIGACTION +#include +#endif + #ifdef HAVE_THREADS #include #include @@ -98,13 +78,17 @@ #define plat_write _write #define plat_mkdir(a, mode) _mkdir(a) +#if defined(HAVE_SELECT) +#include // select +#endif + #else // not _WIN32 -#if defined(HAVE_TTY) || defined(HAVE_MMAP) || defined(HAVE_TERMIOS) +#if defined(HAVE_TTY) || defined(HAVE_MMAP) || defined(HAVE_TERMIOS) || defined(HAVE_USLEEP) #include // write/read/close #endif -#if defined(HAVE_TTY) +#if defined(HAVE_SELECT) #include // select #endif @@ -174,6 +158,7 @@ static int get_ttyfd(void) { } #endif // HAVE_TERMIOS +#ifdef HAVE_SIGACTION /// \brief Signal raised whenever TTY size changes static void os_SIGWINCH_handler(int sig) { (void) sig; @@ -185,6 +170,7 @@ static void os_SIGWINCH_handler(int sig) { // therefore we will actually update the console size in the next get size request. s->resize_pending = true; } +#endif bool os_update_tty_size(tty_state *s) { #ifdef HAVE_TTY @@ -202,8 +188,21 @@ bool os_update_tty_size(tty_state *s) { #endif } -#else - // TODO(edubart): what to do on Windows and MacOS? +#elif defined(_WIN32) + CONSOLE_SCREEN_BUFFER_INFO csbi{}; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { + int cols = csbi.srWindow.Right - csbi.srWindow.Left + 1; + int rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + if (cols >= 1 && rows >= 1) { + s->cols = cols; + s->rows = rows; + return true; + } + } else { +#ifdef DEBUG_OS + (void) fprintf(stderr, "os_update_tty_size(): GetConsoleScreenBufferInfo failed\n"); +#endif + } #endif // defined(HAVE_TERMIOS) && defined(HAVE_IOCTL) #endif // HAVE_TTY @@ -299,7 +298,7 @@ void os_open_tty(void) { // Get tty initial size os_update_tty_size(s); - // TODO(edubart): does this handler works on Windows and MacOS? +#ifdef HAVE_SIGACTION // Install console resize signal handler struct sigaction sigact {}; sigact.sa_flags = SA_RESTART; @@ -309,6 +308,7 @@ void os_open_tty(void) { (void) fprintf(stderr, "os_open_tty(): failed to install SIGWINCH handler\n"); #endif } +#endif #else throw std::runtime_error("unable to open console input, stdin is unsupported in this platform"); @@ -369,7 +369,7 @@ void os_prepare_tty_select(select_fd_sets *fds) { fds->maxfd = STDIN_FILENO; } #else - (void) data; + (void) fds; #endif #endif } @@ -438,8 +438,8 @@ bool os_poll_tty(uint64_t timeout_us) { } if (s->hStdin) { // Wait for an input event - const uint64_t wait_millis = (wait_us + 999) / 1000; - if (WaitForSingleObject(s->hStdin, wait_millis) != WAIT_OBJECT_0) { + const uint64_t wait_ms = (timeout_us + 999) / 1000; + if (WaitForSingleObject(s->hStdin, wait_ms) != WAIT_OBJECT_0) { // No input events return false; } @@ -722,6 +722,7 @@ bool os_select_fds(const os_select_before_callback &before_cb, const os_select_a // Create empty fd sets select_fd_sets fds{}; fds.maxfd = -1; +#ifdef HAVE_SELECT fd_set readfds{}; fd_set writefds{}; fd_set exceptfds{}; @@ -738,13 +739,19 @@ bool os_select_fds(const os_select_before_callback &before_cb, const os_select_a tv.tv_sec = static_cast(*timeout_us / 1000000); tv.tv_usec = static_cast(*timeout_us % 1000000); // Wait for events - // TODO(edubart): consider supporting other OSes const int select_ret = select(fds.maxfd + 1, &readfds, &writefds, &exceptfds, &tv); + return after_cb(select_ret, &fds); +#else + // Act like select failed + before_cb(&fds, timeout_us); + const int select_ret = -1; +#endif // Process ready fds return after_cb(select_ret, &fds); } void os_disable_sigpipe() { +#ifdef HAVE_SIGACTION struct sigaction sigact {}; sigact.sa_handler = SIG_IGN; sigact.sa_flags = SA_RESTART; @@ -753,12 +760,14 @@ void os_disable_sigpipe() { (void) fprintf(stderr, "os_disable_sigpipe(): failed to disable SIGPIPE handler\n"); #endif } +#endif } void os_sleep_us(uint64_t timeout_us) { if (timeout_us == 0) { return; } +#ifdef HAVE_SELECT // Select without fds just to sleep os_select_fds( [](select_fd_sets *fds, const uint64_t *timeout_us) -> void { @@ -771,5 +780,10 @@ void os_sleep_us(uint64_t timeout_us) { return false; }, &timeout_us); +#elif defined(HAVE_USLEEP) + usleep(static_cast(*timeout_us)); +#elif defined(_WIN32) + Sleep(timeout_us / 1000); +#endif } } // namespace cartesi diff --git a/src/virtio-device.h b/src/virtio-device.h index 5b5c0c096..9bf0f2cc2 100644 --- a/src/virtio-device.h +++ b/src/virtio-device.h @@ -21,8 +21,6 @@ #include #include -#include - #include "i-device-state-access.h" #include "os.h" #include "pma.h" diff --git a/src/virtio-net-carrier-slirp.cpp b/src/virtio-net-carrier-slirp.cpp index 5013e6b0f..04b2e5d25 100644 --- a/src/virtio-net-carrier-slirp.cpp +++ b/src/virtio-net-carrier-slirp.cpp @@ -55,6 +55,8 @@ #include "virtio-net-carrier-slirp.h" +#ifdef HAVE_SLIRP + #include #include #include @@ -380,3 +382,5 @@ bool virtio_net_carrier_slirp::read_packet_from_host(i_device_state_access *a, v } } // namespace cartesi + +#endif // HAVE_SLIRP diff --git a/src/virtio-net-carrier-slirp.h b/src/virtio-net-carrier-slirp.h index f4cce2f27..a5050fcac 100644 --- a/src/virtio-net-carrier-slirp.h +++ b/src/virtio-net-carrier-slirp.h @@ -17,6 +17,10 @@ #ifndef VIRTIO_NET_CARRIER_SLIRP_H #define VIRTIO_NET_CARRIER_SLIRP_H +#include "os-features.h" + +#ifdef HAVE_SLIRP + #include "machine-config.h" #include "virtio-net.h" @@ -85,4 +89,6 @@ class virtio_net_carrier_slirp final : public virtio_net_carrier { } // namespace cartesi +#endif // HAVE_SLIRP + #endif diff --git a/src/virtio-net-carrier-tuntap.cpp b/src/virtio-net-carrier-tuntap.cpp index a1f3a56af..c44bee510 100644 --- a/src/virtio-net-carrier-tuntap.cpp +++ b/src/virtio-net-carrier-tuntap.cpp @@ -54,6 +54,8 @@ #include "virtio-net-carrier-tuntap.h" +#ifdef HAVE_TUNTAP + #include #include @@ -213,3 +215,5 @@ bool virtio_net_carrier_tuntap::read_packet_from_host(i_device_state_access *a, } } // namespace cartesi + +#endif // HAVE_TUNTAP diff --git a/src/virtio-net-carrier-tuntap.h b/src/virtio-net-carrier-tuntap.h index ca1532f62..4dc008f99 100644 --- a/src/virtio-net-carrier-tuntap.h +++ b/src/virtio-net-carrier-tuntap.h @@ -17,6 +17,10 @@ #ifndef VIRTIO_NET_CARRIER_TUNTAP_H #define VIRTIO_NET_CARRIER_TUNTAP_H +#include "os-features.h" + +#ifdef HAVE_TUNTAP + #include "virtio-net.h" namespace cartesi { @@ -45,4 +49,6 @@ class virtio_net_carrier_tuntap final : public virtio_net_carrier { } // namespace cartesi +#endif // HAVE_TUNTAP + #endif diff --git a/src/virtio-net.cpp b/src/virtio-net.cpp index ea23fcc17..e8861eed1 100644 --- a/src/virtio-net.cpp +++ b/src/virtio-net.cpp @@ -16,6 +16,8 @@ #include "virtio-net.h" +#ifdef HAVE_SLIRP + namespace cartesi { virtio_net::virtio_net(uint32_t virtio_idx, std::unique_ptr &&carrier) : @@ -138,3 +140,5 @@ bool virtio_net::read_next_packet_from_host(i_device_state_access *a) { } } // namespace cartesi + +#endif // HAVE_SLIRP diff --git a/src/virtio-net.h b/src/virtio-net.h index 883ac504b..864e69618 100644 --- a/src/virtio-net.h +++ b/src/virtio-net.h @@ -17,8 +17,11 @@ #ifndef VIRTIO_NET_H #define VIRTIO_NET_H -#include "virtio-device.h" +#include "os-features.h" + +#ifdef HAVE_SLIRP +#include "virtio-device.h" #include namespace cartesi { @@ -113,4 +116,6 @@ class virtio_net final : public virtio_device { } // namespace cartesi +#endif // HAVE_SLIRP + #endif diff --git a/src/virtio-p9fs.cpp b/src/virtio-p9fs.cpp index 61b562ed1..31838ae8e 100644 --- a/src/virtio-p9fs.cpp +++ b/src/virtio-p9fs.cpp @@ -34,6 +34,8 @@ #include "virtio-p9fs.h" +#ifdef HAVE_POSIX_FS + #include #include @@ -1826,3 +1828,5 @@ bool virtio_p9fs_device::send_error(const virtq_unserializer &in_msg, uint16_t t } } // namespace cartesi + +#endif // HAVE_POSIX_FS \ No newline at end of file diff --git a/src/virtio-p9fs.h b/src/virtio-p9fs.h index 408cd7158..00c4a7d65 100644 --- a/src/virtio-p9fs.h +++ b/src/virtio-p9fs.h @@ -17,6 +17,10 @@ #ifndef VIRTIO_P9FS_H #define VIRTIO_P9FS_H +#include "os-features.h" + +#ifdef HAVE_POSIX_FS + #include "virtio-device.h" #include "virtio-serializer.h" @@ -450,4 +454,6 @@ class virtio_p9fs_device final : public virtio_device { } // namespace cartesi +#endif // HAVE_POSIX_FS + #endif