From 153ac6df9a7731fcbe5ba1389e8380f64d58f921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Fri, 17 Dec 2021 18:32:11 +0100 Subject: [PATCH 1/3] Use recursive mutexes in the C++ thread implementation --- src/cpp11_thread.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpp11_thread.cpp b/src/cpp11_thread.cpp index 96eb4a2e1..02bd87143 100644 --- a/src/cpp11_thread.cpp +++ b/src/cpp11_thread.cpp @@ -41,7 +41,7 @@ thread_wait(thread_t *arg, int timeout) mutex_t * thread_create_mutex(void) { - auto mutex = new std::mutex; + auto mutex = new std::recursive_mutex; return mutex; } @@ -50,7 +50,7 @@ thread_wait_mutex(mutex_t *_mutex) { if (_mutex == nullptr) return(0); - auto mutex = reinterpret_cast(_mutex); + auto mutex = reinterpret_cast(_mutex); mutex->lock(); return 1; } @@ -61,7 +61,7 @@ thread_release_mutex(mutex_t *_mutex) { if (_mutex == nullptr) return(0); - auto mutex = reinterpret_cast(_mutex); + auto mutex = reinterpret_cast(_mutex); mutex->unlock(); return 1; } @@ -70,7 +70,7 @@ thread_release_mutex(mutex_t *_mutex) void thread_close_mutex(mutex_t *_mutex) { - auto mutex = reinterpret_cast(_mutex); + auto mutex = reinterpret_cast(_mutex); delete mutex; } From 9c7a3477aa9ffec2d10ee0b89e11dcee87c9d642 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Dec 2021 18:48:13 +0100 Subject: [PATCH 2/3] Proper reimplementation of C++11 thread event signaling and the network code now uses an atomic instead of mutexes for wait. --- src/cpp11_thread.cpp | 22 ++++++++++++---------- src/network/net_pcap.c | 8 +++++--- src/network/network.c | 9 +++------ 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/cpp11_thread.cpp b/src/cpp11_thread.cpp index 02bd87143..1f5dd4d2b 100644 --- a/src/cpp11_thread.cpp +++ b/src/cpp11_thread.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include <86box/plat.h> @@ -77,25 +78,25 @@ thread_close_mutex(mutex_t *_mutex) event_t * thread_create_event() { - auto ev = new event_cpp11_t; - return ev; + auto event = new event_cpp11_t; + return event; } int thread_wait_event(event_t *handle, int timeout) { auto event = reinterpret_cast(handle); - auto lock = std::unique_lock(event->mutex); + std::unique_lock lock(event->mutex); if (timeout < 0) { - event->cond.wait(lock, [event] { return event->state; }); + event->cond.wait(lock, [event] { return (event->state == true); }); } else { auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout); std::cv_status status; do { status = event->cond.wait_until(lock, to); - } while ((status != std::cv_status::timeout) && !event->state); + } while ((status != std::cv_status::timeout) && (event->state == false)); if (status == std::cv_status::timeout) { return 1; @@ -108,10 +109,9 @@ void thread_set_event(event_t *handle) { auto event = reinterpret_cast(handle); - { - auto lock = std::unique_lock(event->mutex); - event->state = true; - } + std::lock_guard lock(event->mutex); + + event->state = true; event->cond.notify_all(); } @@ -119,8 +119,10 @@ void thread_reset_event(event_t *handle) { auto event = reinterpret_cast(handle); - auto lock = std::unique_lock(event->mutex); + std::lock_guard lock(event->mutex); + event->state = false; + // event->cond.notify_all(); } void diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index ba56cebfb..ccdbb3c10 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -172,6 +172,7 @@ poll_thread(void *arg) thread_set_event(poll_state); /* Create a waitable event. */ + pcap_log("PCAP: Creating event...\n"); evt = thread_create_event(); /* As long as the channel is open.. */ @@ -185,8 +186,6 @@ poll_thread(void *arg) if (pcap == NULL) break; - /* Wait for the next packet to arrive. */ - tx = network_tx_queue_check(); if (network_get_wait() || (poll_card->set_link_state && poll_card->set_link_state(poll_card->priv)) || (poll_card->wait && poll_card->wait(poll_card->priv))) data = NULL; else @@ -208,11 +207,14 @@ poll_thread(void *arg) } } + /* Wait for the next packet to arrive. */ + tx = network_tx_queue_check(); + if (tx) network_do_tx(); /* If we did not get anything, wait a while. */ - if ((data == NULL) && !tx) + if (!tx) thread_wait_event(evt, 10); /* Release ownership of the device. */ diff --git a/src/network/network.c b/src/network/network.c index b545b08ca..0e7f16bac 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -49,6 +49,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include #include #include @@ -107,7 +108,7 @@ int nic_do_log = ENABLE_NIC_LOG; /* Local variables. */ -static volatile int net_wait = 0; +static volatile atomic_int net_wait = 0; static mutex_t *network_mutex; static uint8_t *network_mac; static uint8_t network_timer_active = 0; @@ -388,8 +389,8 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKST network_set_wait(0); /* Create the network events. */ - poll_data.wake_poll_thread = thread_create_event(); poll_data.poll_complete = thread_create_event(); + poll_data.wake_poll_thread = thread_create_event(); /* Activate the platform module. */ switch(network_type) { @@ -671,9 +672,7 @@ network_card_get_from_internal_name(char *s) void network_set_wait(int wait) { - network_wait(1); net_wait = wait; - network_wait(0); } @@ -682,8 +681,6 @@ network_get_wait(void) { int ret; - network_wait(1); ret = net_wait; - network_wait(0); return ret; } From 0131550432f7b3f8e4e59efaf397be70f736f893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Fri, 17 Dec 2021 18:51:16 +0100 Subject: [PATCH 3/3] Revert "Use recursive mutexes in the C++ thread implementation" This reverts commit 153ac6df9a7731fcbe5ba1389e8380f64d58f921. --- src/cpp11_thread.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpp11_thread.cpp b/src/cpp11_thread.cpp index 1f5dd4d2b..071c013a1 100644 --- a/src/cpp11_thread.cpp +++ b/src/cpp11_thread.cpp @@ -42,7 +42,7 @@ thread_wait(thread_t *arg, int timeout) mutex_t * thread_create_mutex(void) { - auto mutex = new std::recursive_mutex; + auto mutex = new std::mutex; return mutex; } @@ -51,7 +51,7 @@ thread_wait_mutex(mutex_t *_mutex) { if (_mutex == nullptr) return(0); - auto mutex = reinterpret_cast(_mutex); + auto mutex = reinterpret_cast(_mutex); mutex->lock(); return 1; } @@ -62,7 +62,7 @@ thread_release_mutex(mutex_t *_mutex) { if (_mutex == nullptr) return(0); - auto mutex = reinterpret_cast(_mutex); + auto mutex = reinterpret_cast(_mutex); mutex->unlock(); return 1; } @@ -71,7 +71,7 @@ thread_release_mutex(mutex_t *_mutex) void thread_close_mutex(mutex_t *_mutex) { - auto mutex = reinterpret_cast(_mutex); + auto mutex = reinterpret_cast(_mutex); delete mutex; }