Proper reimplementation of C++11 thread event signaling and the network code now uses an atomic instead of mutexes for wait.

This commit is contained in:
OBattler
2021-12-17 18:48:13 +01:00
parent 153ac6df9a
commit 9c7a3477aa
3 changed files with 20 additions and 19 deletions

View File

@@ -1,6 +1,7 @@
#include <mutex> #include <mutex>
#include <thread> #include <thread>
#include <condition_variable> #include <condition_variable>
#include <atomic>
#include <86box/plat.h> #include <86box/plat.h>
@@ -77,25 +78,25 @@ thread_close_mutex(mutex_t *_mutex)
event_t * event_t *
thread_create_event() thread_create_event()
{ {
auto ev = new event_cpp11_t; auto event = new event_cpp11_t;
return ev; return event;
} }
int int
thread_wait_event(event_t *handle, int timeout) thread_wait_event(event_t *handle, int timeout)
{ {
auto event = reinterpret_cast<event_cpp11_t*>(handle); auto event = reinterpret_cast<event_cpp11_t*>(handle);
auto lock = std::unique_lock<std::mutex>(event->mutex); std::unique_lock<std::mutex> lock(event->mutex);
if (timeout < 0) { if (timeout < 0) {
event->cond.wait(lock, [event] { return event->state; }); event->cond.wait(lock, [event] { return (event->state == true); });
} else { } else {
auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout); auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
std::cv_status status; std::cv_status status;
do { do {
status = event->cond.wait_until(lock, to); 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) { if (status == std::cv_status::timeout) {
return 1; return 1;
@@ -108,10 +109,9 @@ void
thread_set_event(event_t *handle) thread_set_event(event_t *handle)
{ {
auto event = reinterpret_cast<event_cpp11_t*>(handle); auto event = reinterpret_cast<event_cpp11_t*>(handle);
{ std::lock_guard<std::mutex> lock(event->mutex);
auto lock = std::unique_lock<std::mutex>(event->mutex);
event->state = true; event->state = true;
}
event->cond.notify_all(); event->cond.notify_all();
} }
@@ -119,8 +119,10 @@ void
thread_reset_event(event_t *handle) thread_reset_event(event_t *handle)
{ {
auto event = reinterpret_cast<event_cpp11_t*>(handle); auto event = reinterpret_cast<event_cpp11_t*>(handle);
auto lock = std::unique_lock<std::mutex>(event->mutex); std::lock_guard<std::mutex> lock(event->mutex);
event->state = false; event->state = false;
// event->cond.notify_all();
} }
void void

View File

@@ -172,6 +172,7 @@ poll_thread(void *arg)
thread_set_event(poll_state); thread_set_event(poll_state);
/* Create a waitable event. */ /* Create a waitable event. */
pcap_log("PCAP: Creating event...\n");
evt = thread_create_event(); evt = thread_create_event();
/* As long as the channel is open.. */ /* As long as the channel is open.. */
@@ -185,8 +186,6 @@ poll_thread(void *arg)
if (pcap == NULL) if (pcap == NULL)
break; 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))) 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; data = NULL;
else else
@@ -208,11 +207,14 @@ poll_thread(void *arg)
} }
} }
/* Wait for the next packet to arrive. */
tx = network_tx_queue_check();
if (tx) if (tx)
network_do_tx(); network_do_tx();
/* If we did not get anything, wait a while. */ /* If we did not get anything, wait a while. */
if ((data == NULL) && !tx) if (!tx)
thread_wait_event(evt, 10); thread_wait_event(evt, 10);
/* Release ownership of the device. */ /* Release ownership of the device. */

View File

@@ -49,6 +49,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <stdarg.h> #include <stdarg.h>
#include <stdatomic.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -107,7 +108,7 @@ int nic_do_log = ENABLE_NIC_LOG;
/* Local variables. */ /* Local variables. */
static volatile int net_wait = 0; static volatile atomic_int net_wait = 0;
static mutex_t *network_mutex; static mutex_t *network_mutex;
static uint8_t *network_mac; static uint8_t *network_mac;
static uint8_t network_timer_active = 0; 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); network_set_wait(0);
/* Create the network events. */ /* Create the network events. */
poll_data.wake_poll_thread = thread_create_event();
poll_data.poll_complete = thread_create_event(); poll_data.poll_complete = thread_create_event();
poll_data.wake_poll_thread = thread_create_event();
/* Activate the platform module. */ /* Activate the platform module. */
switch(network_type) { switch(network_type) {
@@ -671,9 +672,7 @@ network_card_get_from_internal_name(char *s)
void void
network_set_wait(int wait) network_set_wait(int wait)
{ {
network_wait(1);
net_wait = wait; net_wait = wait;
network_wait(0);
} }
@@ -682,8 +681,6 @@ network_get_wait(void)
{ {
int ret; int ret;
network_wait(1);
ret = net_wait; ret = net_wait;
network_wait(0);
return ret; return ret;
} }