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:
@@ -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
|
||||||
|
@@ -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. */
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user