From be900f1d32b3dee90a85db69dc42562bc71b6e51 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 20 Feb 2022 15:04:24 +0600 Subject: [PATCH 01/10] qt: Fix high CPU usage when paused --- src/qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index cae6c6e5c..a1be6d565 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -114,7 +114,7 @@ main_thread_fn() } } else { /* Just so we dont overload the host OS. */ - if (drawits < -1) + if (drawits < -1 || dopause) std::this_thread::sleep_for(std::chrono::milliseconds(1)); else std::this_thread::yield(); From 01e0609ab6b6c995e63901601131e0025baac037 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 13:58:38 +0100 Subject: [PATCH 02/10] And more network clean-ups and fixes. --- src/include/86box/network.h | 2 -- src/network/net_pcap.c | 10 +------- src/network/net_slirp.c | 10 +------- src/network/network.c | 50 +++++++++++++------------------------ 4 files changed, 19 insertions(+), 53 deletions(-) diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 015eb6a34..1d6763b44 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -105,7 +105,6 @@ extern netdev_t network_devs[32]; /* Function prototypes. */ extern void network_wait(uint8_t wait); -extern void network_poll(void); extern void network_busy(uint8_t set); extern void network_end(void); @@ -115,7 +114,6 @@ extern void network_close(void); extern void network_reset(void); extern int network_available(void); extern void network_tx(uint8_t *, int); -extern void network_do_tx(void); extern int network_tx_queue_check(void); extern int net_pcap_prepare(netdev_t *); diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index cfa4837dc..6fd22f571 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -180,11 +180,6 @@ poll_thread(void *arg) /* Request ownership of the device. */ network_wait(1); -#if 0 - /* Wait for a poll request. */ - network_poll(); -#endif - if (pcap == NULL) { network_wait(0); break; @@ -211,12 +206,9 @@ poll_thread(void *arg) } } - /* Wait for the next packet to arrive. */ + /* Wait for the next packet to arrive - network_do_tx() is called from there. */ tx = network_tx_queue_check(); - if (tx) - network_do_tx(); - /* Release ownership of the device. */ network_wait(0); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index aeb28ad37..514126118 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -362,11 +362,6 @@ poll_thread(void *arg) /* Request ownership of the queue. */ network_wait(1); -#if 0 - /* Wait for a poll request. */ - network_poll(); -#endif - /* Stop processing if asked to. */ if (slirp->stop) { network_wait(0); @@ -376,12 +371,9 @@ poll_thread(void *arg) /* See if there is any work. */ slirp_tic(slirp); - /* Wait for the next packet to arrive. */ + /* Wait for the next packet to arrive - network_do_tx() is called from there. */ tx = network_tx_queue_check(); - if (tx) - network_do_tx(); - /* Release ownership of the queue. */ network_wait(0); diff --git a/src/network/network.c b/src/network/network.c index 7f4e83514..bcb19e9ef 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -120,8 +120,8 @@ static mutex_t *network_mutex; static uint8_t *network_mac; static uint8_t network_timer_active = 0; static pc_timer_t network_rx_queue_timer; -static netpkt_t *first_pkt[2] = { NULL, NULL }, - *last_pkt[2] = { NULL, NULL }; +static netpkt_t *first_pkt[3] = { NULL, NULL, NULL }, + *last_pkt[3] = { NULL, NULL, NULL }; static struct { @@ -201,20 +201,6 @@ network_wait(uint8_t wait) } -void -network_poll(void) -{ - network_wait(0); - - while (poll_data.busy) - thread_wait_event(poll_data.wake_poll_thread, -1); - - network_wait(1); - - thread_reset_event(poll_data.wake_poll_thread); -} - - void network_busy(uint8_t set) { @@ -359,7 +345,7 @@ network_rx_queue(void *priv) return; } - network_busy(1); + // network_busy(1); network_queue_get(0, &pkt); if ((pkt != NULL) && (pkt->len > 0)) { @@ -374,7 +360,11 @@ network_rx_queue(void *priv) if (ret) network_queue_advance(0); - network_busy(0); + /* Transmission. */ + network_queue_get(2, &pkt); + network_queue_put(1, pkt->priv, pkt->data, pkt->len); + + // network_busy(0); network_wait(0); } @@ -416,8 +406,8 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKST break; } - first_pkt[0] = first_pkt[1] = NULL; - last_pkt[0] = last_pkt[1] = NULL; + first_pkt[0] = first_pkt[1] = first_pkt[2] = NULL; + last_pkt[0] = last_pkt[1] = last_pkt[2] = NULL; memset(&network_rx_queue_timer, 0x00, sizeof(pc_timer_t)); timer_add(&network_rx_queue_timer, network_rx_queue, NULL, 0); /* 10 mbps. */ @@ -555,7 +545,7 @@ network_tx(uint8_t *bufp, int len) ui_sb_update_icon(SB_NETWORK, 1); - network_queue_put(1, NULL, bufp, len); + network_queue_put(2, NULL, bufp, len); ui_sb_update_icon(SB_NETWORK, 0); @@ -564,13 +554,16 @@ network_tx(uint8_t *bufp, int len) /* Actually transmit the packet. */ -void -network_do_tx(void) +int +network_tx_queue_check(void) { netpkt_t *pkt = NULL; + if ((first_pkt[1] == NULL) && (last_pkt[1] == NULL)) + return 0; + if (network_tx_pause) - return; + return 1; network_queue_get(1, &pkt); if ((pkt != NULL) && (pkt->len > 0)) { @@ -586,15 +579,6 @@ network_do_tx(void) } } network_queue_advance(1); -} - - -int -network_tx_queue_check(void) -{ - if ((first_pkt[1] == NULL) && (last_pkt[1] == NULL)) - return 0; - return 1; } From c19b06d404de82bccce17772543ea91d3c8eeed3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 14:19:38 +0100 Subject: [PATCH 03/10] Added a sanity check and more clean-ups. --- src/include/86box/network.h | 2 -- src/network/net_pcap.c | 2 -- src/network/net_slirp.c | 2 -- src/network/network.c | 48 ++----------------------------------- 4 files changed, 2 insertions(+), 52 deletions(-) diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 1d6763b44..f559d55a0 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -105,8 +105,6 @@ extern netdev_t network_devs[32]; /* Function prototypes. */ extern void network_wait(uint8_t wait); -extern void network_busy(uint8_t set); -extern void network_end(void); extern void network_init(void); extern void network_attach(void *, uint8_t *, NETRXCB, NETWAITCB, NETSETLINKSTATE); diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 6fd22f571..1fff7255c 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -338,8 +338,6 @@ net_pcap_close(void) /* Tell the thread to terminate. */ if (poll_tid != NULL) { - network_busy(0); - /* Wait for the thread to finish. */ pcap_log("PCAP: waiting for thread to end...\n"); thread_wait_event(poll_state, -1); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 514126118..fc4afcf78 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -446,8 +446,6 @@ net_slirp_close(void) /* Tell the thread to terminate. */ if (slirp->poll_tid) { - network_busy(0); - /* Wait for the thread to finish. */ slirp_log("SLiRP: waiting for thread to end...\n"); thread_wait_event(slirp->poll_state, -1); diff --git a/src/network/network.c b/src/network/network.c index bcb19e9ef..4e78434e6 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -124,16 +124,6 @@ static netpkt_t *first_pkt[3] = { NULL, NULL, NULL }, *last_pkt[3] = { NULL, NULL, NULL }; -static struct { - volatile int busy, - queue_in_use; - - event_t *wake_poll_thread, - *poll_complete, - *queue_not_in_use; -} poll_data; - - #ifdef ENABLE_NETWORK_LOG int network_do_log = ENABLE_NETWORK_LOG; static FILE *network_dump = NULL; @@ -201,23 +191,6 @@ network_wait(uint8_t wait) } -void -network_busy(uint8_t set) -{ - poll_data.busy = !!set; - - if (! set) - thread_set_event(poll_data.wake_poll_thread); -} - - -void -network_end(void) -{ - thread_set_event(poll_data.poll_complete); -} - - /* * Initialize the configured network cards. * @@ -362,7 +335,8 @@ network_rx_queue(void *priv) /* Transmission. */ network_queue_get(2, &pkt); - network_queue_put(1, pkt->priv, pkt->data, pkt->len); + if (pkt != NULL) + network_queue_put(1, pkt->priv, pkt->data, pkt->len); // network_busy(0); @@ -391,10 +365,6 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKST network_set_wait(0); - /* Create the network events. */ - poll_data.poll_complete = thread_create_event(); - poll_data.wake_poll_thread = thread_create_event(); - /* Activate the platform module. */ switch(network_type) { case NET_TYPE_PCAP: @@ -443,16 +413,6 @@ network_close(void) /* Force-close the SLIRP module. */ net_slirp_close(); - /* Close the network events. */ - if (poll_data.wake_poll_thread != NULL) { - thread_destroy_event(poll_data.wake_poll_thread); - poll_data.wake_poll_thread = NULL; - } - if (poll_data.poll_complete != NULL) { - thread_destroy_event(poll_data.poll_complete); - poll_data.poll_complete = NULL; - } - /* Close the network thread mutex. */ thread_close_mutex(network_mutex); network_mutex = NULL; @@ -541,15 +501,11 @@ network_reset(void) void network_tx(uint8_t *bufp, int len) { - network_busy(1); - ui_sb_update_icon(SB_NETWORK, 1); network_queue_put(2, NULL, bufp, len); ui_sb_update_icon(SB_NETWORK, 0); - - network_busy(0); } From f80937d350383921451f7b9b7730b0ad227bcfa3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 17:01:46 +0100 Subject: [PATCH 04/10] Actually advance the interim queue after getting from it. --- src/network/network.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/network.c b/src/network/network.c index 4e78434e6..6877e04c4 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -335,8 +335,10 @@ network_rx_queue(void *priv) /* Transmission. */ network_queue_get(2, &pkt); - if (pkt != NULL) + if (pkt != NULL) { network_queue_put(1, pkt->priv, pkt->data, pkt->len); + network_queue_advance(2); + } // network_busy(0); From b18d7795f6477ef5bd1b6a75770647a9d8d7c536 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 19:37:47 +0100 Subject: [PATCH 05/10] Changed the way failed packed deliveries are handled. --- src/network/network.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/network/network.c b/src/network/network.c index 6877e04c4..99264773a 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -310,20 +310,18 @@ static void network_rx_queue(void *priv) { int ret = 1; - - netpkt_t *pkt = NULL; + static netpkt_t *pkt = NULL; if (network_rx_pause || !thread_test_mutex(network_mutex)) { timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); return; } - // network_busy(1); - - network_queue_get(0, &pkt); + if (pkt == NULL) + network_queue_get(0, &pkt); if ((pkt != NULL) && (pkt->len > 0)) { network_dump_packet(pkt); - ret = net_cards[network_card].rx(pkt->priv, pkt->data, pkt->len); + ret = net_cards[network_card].rx(pkt->priv, pkt->data, pkt->len);5 if (pkt->len >= 128) timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) pkt->len)); else @@ -331,7 +329,8 @@ network_rx_queue(void *priv) } else timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); if (ret) - network_queue_advance(0); + pkt = NULL; + network_queue_advance(0); /* Transmission. */ network_queue_get(2, &pkt); @@ -340,8 +339,6 @@ network_rx_queue(void *priv) network_queue_advance(2); } - // network_busy(0); - network_wait(0); } From 9b09a5058c1112838849b829dc2fef6bcc397581 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 19:41:34 +0100 Subject: [PATCH 06/10] And some fixes. --- src/network/network.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/network/network.c b/src/network/network.c index 99264773a..f2f34eec5 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -122,6 +122,7 @@ static uint8_t network_timer_active = 0; static pc_timer_t network_rx_queue_timer; static netpkt_t *first_pkt[3] = { NULL, NULL, NULL }, *last_pkt[3] = { NULL, NULL, NULL }; +static netpkt_t *queued_pkt = NULL; #ifdef ENABLE_NETWORK_LOG @@ -310,32 +311,32 @@ static void network_rx_queue(void *priv) { int ret = 1; - static netpkt_t *pkt = NULL; + netpkt_t *tx_queued_pkt = NULL; if (network_rx_pause || !thread_test_mutex(network_mutex)) { timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); return; } - if (pkt == NULL) - network_queue_get(0, &pkt); - if ((pkt != NULL) && (pkt->len > 0)) { - network_dump_packet(pkt); - ret = net_cards[network_card].rx(pkt->priv, pkt->data, pkt->len);5 - if (pkt->len >= 128) - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) pkt->len)); + if (queued_pkt == NULL) + network_queue_get(0, &queued_pkt); + if ((queued_pkt != NULL) && (queued_pkt->len > 0)) { + network_dump_packet(queued_pkt); + ret = net_cards[network_card].rx(queued_pkt->priv, queued_pkt->data, queued_pkt->len); + if (queued_pkt->len >= 128) + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) queued_pkt->len)); else timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); } else timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); if (ret) - pkt = NULL; + queued_pkt = NULL; network_queue_advance(0); /* Transmission. */ - network_queue_get(2, &pkt); - if (pkt != NULL) { - network_queue_put(1, pkt->priv, pkt->data, pkt->len); + network_queue_get(2, &tx_queued_pkt); + if (tx_queued_pkt != NULL) { + network_queue_put(1, tx_queued_pkt->priv, tx_queued_pkt->data, tx_queued_pkt->len); network_queue_advance(2); } @@ -377,6 +378,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKST first_pkt[0] = first_pkt[1] = first_pkt[2] = NULL; last_pkt[0] = last_pkt[1] = last_pkt[2] = NULL; + queued_pkt = NULL; memset(&network_rx_queue_timer, 0x00, sizeof(pc_timer_t)); timer_add(&network_rx_queue_timer, network_rx_queue, NULL, 0); /* 10 mbps. */ From 3b5be8b619e576b2c6b05867edafacd4ea58d114 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 20:11:41 +0100 Subject: [PATCH 07/10] Reduced some network times. --- src/network/network.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/network/network.c b/src/network/network.c index f2f34eec5..45de94937 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -314,7 +314,7 @@ network_rx_queue(void *priv) netpkt_t *tx_queued_pkt = NULL; if (network_rx_pause || !thread_test_mutex(network_mutex)) { - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 64.0); return; } @@ -323,12 +323,15 @@ network_rx_queue(void *priv) if ((queued_pkt != NULL) && (queued_pkt->len > 0)) { network_dump_packet(queued_pkt); ret = net_cards[network_card].rx(queued_pkt->priv, queued_pkt->data, queued_pkt->len); - if (queued_pkt->len >= 128) - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) queued_pkt->len)); - else - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); + if (ret) { + if (queued_pkt->len >= 128) + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) queued_pkt->len)); + else + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); + } else + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 64.0); } else - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 64.0); if (ret) queued_pkt = NULL; network_queue_advance(0); From f19aaa14ae8df93c408ebdf5268707a24ccea97f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 20:30:20 +0100 Subject: [PATCH 08/10] Fixed three instances of undefined behavior. --- src/codegen_new/codegen_ir_defs.h | 2 +- src/pic.c | 2 +- src/video/vid_svga.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 86276a053..618bd9b7f 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -9,7 +9,7 @@ All registers must have been written back or discarded. This should be used when calling external functions that may change any emulated registers.*/ -#define UOP_TYPE_BARRIER (1 << 31) +#define UOP_TYPE_BARRIER (1u << 31) /*uOP is a barrier. All previous uOPs must have completed before this one executes. All registers must have been written back, but do not have to be discarded. diff --git a/src/pic.c b/src/pic.c index 899029c14..efe81f470 100644 --- a/src/pic.c +++ b/src/pic.c @@ -222,7 +222,7 @@ find_best_interrupt(pic_t *dev) if (dev == &pic2) intr += 8; - if (cpu_fast_off_flags & (1 << intr)) + if (cpu_fast_off_flags & (1u << intr)) cpu_fast_off_count = cpu_fast_off_val + 1; } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index c5ff2ed43..b760945a7 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -936,11 +936,11 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, svga->dispontime = 1000ull << 32; svga->dispofftime = 1000ull << 32; svga->bpp = 8; - svga->vram = malloc(memsize); + svga->vram = calloc(memsize, 1); svga->vram_max = memsize; svga->vram_display_mask = svga->vram_mask = memsize - 1; svga->decode_mask = 0x7fffff; - svga->changedvram = malloc(memsize >> 12); + svga->changedvram = calloc(memsize >> 12, 1); svga->recalctimings_ex = recalctimings_ex; svga->video_in = video_in; svga->video_out = video_out; From ac2bdcf84c3b2bc76333b4c7013d8da2c7c2dc67 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 20:39:39 +0100 Subject: [PATCH 09/10] And it turns out we can actually use network_wait(1) in the CPU thread just fine. --- src/network/network.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/network/network.c b/src/network/network.c index 45de94937..efcbc9ccf 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -313,25 +313,24 @@ network_rx_queue(void *priv) int ret = 1; netpkt_t *tx_queued_pkt = NULL; - if (network_rx_pause || !thread_test_mutex(network_mutex)) { - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 64.0); + if (network_rx_pause) { + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); return; } + network_wait(1); + if (queued_pkt == NULL) network_queue_get(0, &queued_pkt); if ((queued_pkt != NULL) && (queued_pkt->len > 0)) { network_dump_packet(queued_pkt); ret = net_cards[network_card].rx(queued_pkt->priv, queued_pkt->data, queued_pkt->len); - if (ret) { - if (queued_pkt->len >= 128) - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) queued_pkt->len)); - else - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); - } else - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 64.0); + if (queued_pkt->len >= 128) + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) queued_pkt->len)); + else + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); } else - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 64.0); + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); if (ret) queued_pkt = NULL; network_queue_advance(0); From 2a0b72739bce981f37606c95db630bff2861a399 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 20 Feb 2022 21:04:30 +0100 Subject: [PATCH 10/10] More changes in network.c. --- src/network/network.c | 122 ++++++++++++++++++++++++++---------------- 1 file changed, 76 insertions(+), 46 deletions(-) diff --git a/src/network/network.c b/src/network/network.c index efcbc9ccf..2428d7305 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -122,7 +122,7 @@ static uint8_t network_timer_active = 0; static pc_timer_t network_rx_queue_timer; static netpkt_t *first_pkt[3] = { NULL, NULL, NULL }, *last_pkt[3] = { NULL, NULL, NULL }; -static netpkt_t *queued_pkt = NULL; +static netpkt_t queued_pkt; #ifdef ENABLE_NETWORK_LOG @@ -244,8 +244,7 @@ network_queue_put(int tx, void *priv, uint8_t *data, int len) { netpkt_t *temp; - temp = (netpkt_t *) malloc(sizeof(netpkt_t)); - memset(temp, 0, sizeof(netpkt_t)); + temp = (netpkt_t *) calloc(sizeof(netpkt_t), 1); temp->priv = priv; memcpy(temp->data, data, len); temp->len = len; @@ -262,17 +261,29 @@ network_queue_put(int tx, void *priv, uint8_t *data, int len) static void -network_queue_get(int tx, netpkt_t **pkt) +network_queue_get(int tx, netpkt_t *pkt) { + netpkt_t *temp; + + temp = first_pkt[tx]; + + if (temp == NULL) { + memset(pkt, 0x00, sizeof(netpkt_t)); + return; + } + + memcpy(pkt, temp, sizeof(netpkt_t)); + + first_pkt[tx] = temp->next; + free(temp); + if (first_pkt[tx] == NULL) - *pkt = NULL; - else - *pkt = first_pkt[tx]; + last_pkt[tx] = NULL; } static void -network_queue_advance(int tx) +network_queue_transmit(int tx) { netpkt_t *temp; @@ -281,6 +292,20 @@ network_queue_advance(int tx) if (temp == NULL) return; + if (temp->len > 0) { + network_dump_packet(temp); + /* Why on earth is this not a function pointer?! */ + switch(network_type) { + case NET_TYPE_PCAP: + net_pcap_in(temp->data, temp->len); + break; + + case NET_TYPE_SLIRP: + net_slirp_in(temp->data, temp->len); + break; + } + } + first_pkt[tx] = temp->next; free(temp); @@ -289,6 +314,38 @@ network_queue_advance(int tx) } +static void +network_queue_copy(int dest, int src) +{ + netpkt_t *temp, *temp2; + + temp = first_pkt[src]; + + if (temp == NULL) + return; + + temp2 = (netpkt_t *) calloc(sizeof(netpkt_t), 1); + temp2->priv = temp->priv; + memcpy(temp2->data, temp->data, temp->len); + temp2->len = temp->len; + temp2->prev = last_pkt[dest]; + temp2->next = NULL; + + if (last_pkt[dest] != NULL) + last_pkt[dest]->next = temp2; + last_pkt[dest] = temp2; + + if (first_pkt[dest] == NULL) + first_pkt[dest] = temp2; + + first_pkt[src] = temp->next; + free(temp); + + if (first_pkt[src] == NULL) + last_pkt[src] = NULL; +} + + static void network_queue_clear(int tx) { @@ -311,36 +368,24 @@ static void network_rx_queue(void *priv) { int ret = 1; - netpkt_t *tx_queued_pkt = NULL; - if (network_rx_pause) { + if (network_rx_pause || !thread_test_mutex(network_mutex)) { timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); return; } - network_wait(1); - - if (queued_pkt == NULL) + if (queued_pkt.len == 0) network_queue_get(0, &queued_pkt); - if ((queued_pkt != NULL) && (queued_pkt->len > 0)) { - network_dump_packet(queued_pkt); - ret = net_cards[network_card].rx(queued_pkt->priv, queued_pkt->data, queued_pkt->len); - if (queued_pkt->len >= 128) - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((double) queued_pkt->len)); - else - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); - } else - timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * 128.0); + if (queued_pkt.len > 0) { + network_dump_packet(&queued_pkt); + ret = net_cards[network_card].rx(queued_pkt.priv, queued_pkt.data, queued_pkt.len); + } + timer_on_auto(&network_rx_queue_timer, 0.762939453125 * 2.0 * ((queued_pkt.len >= 128) ? ((double) queued_pkt.len) : 128.0)); if (ret) - queued_pkt = NULL; - network_queue_advance(0); + queued_pkt.len = 0; /* Transmission. */ - network_queue_get(2, &tx_queued_pkt); - if (tx_queued_pkt != NULL) { - network_queue_put(1, tx_queued_pkt->priv, tx_queued_pkt->data, tx_queued_pkt->len); - network_queue_advance(2); - } + network_queue_copy(1, 2); network_wait(0); } @@ -380,7 +425,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKST first_pkt[0] = first_pkt[1] = first_pkt[2] = NULL; last_pkt[0] = last_pkt[1] = last_pkt[2] = NULL; - queued_pkt = NULL; + memset(&queued_pkt, 0x00, sizeof(netpkt_t)); memset(&network_rx_queue_timer, 0x00, sizeof(pc_timer_t)); timer_add(&network_rx_queue_timer, network_rx_queue, NULL, 0); /* 10 mbps. */ @@ -516,28 +561,13 @@ network_tx(uint8_t *bufp, int len) int network_tx_queue_check(void) { - netpkt_t *pkt = NULL; - if ((first_pkt[1] == NULL) && (last_pkt[1] == NULL)) return 0; if (network_tx_pause) return 1; - network_queue_get(1, &pkt); - if ((pkt != NULL) && (pkt->len > 0)) { - network_dump_packet(pkt); - switch(network_type) { - case NET_TYPE_PCAP: - net_pcap_in(pkt->data, pkt->len); - break; - - case NET_TYPE_SLIRP: - net_slirp_in(pkt->data, pkt->len); - break; - } - } - network_queue_advance(1); + network_queue_transmit(1); return 1; }