SLiRP: Introduce a new queue for packets received immediately transmssion - those are now collected into said queue and processed immediately after, improves SLiRP operation.
This commit is contained in:
@@ -57,7 +57,7 @@
|
||||
/* Queue size must be a power of 2 */
|
||||
#define NET_QUEUE_LEN 16
|
||||
#define NET_QUEUE_LEN_MASK (NET_QUEUE_LEN - 1)
|
||||
#define NET_QUEUE_COUNT 3
|
||||
#define NET_QUEUE_COUNT 4
|
||||
#define NET_CARD_MAX 4
|
||||
#define NET_HOST_INTF_MAX 64
|
||||
|
||||
@@ -84,9 +84,10 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
NET_QUEUE_RX = 0,
|
||||
NET_QUEUE_TX_VM = 1,
|
||||
NET_QUEUE_TX_HOST = 2
|
||||
NET_QUEUE_RX = 0,
|
||||
NET_QUEUE_TX_VM = 1,
|
||||
NET_QUEUE_TX_HOST = 2,
|
||||
NET_QUEUE_RX_ON_TX = 3
|
||||
};
|
||||
|
||||
typedef struct netcard_conf_t {
|
||||
@@ -199,7 +200,10 @@ extern const device_t *network_card_getdevice(int);
|
||||
extern int network_tx_pop(netcard_t *card, netpkt_t *out_pkt);
|
||||
extern int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size);
|
||||
extern int network_rx_put(netcard_t *card, uint8_t *bufp, int len);
|
||||
extern int network_rx_on_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size);
|
||||
extern int network_rx_on_tx_put(netcard_t *card, uint8_t *bufp, int len);
|
||||
extern int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt);
|
||||
extern int network_rx_on_tx_put_pkt(netcard_t *card, netpkt_t *pkt);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
/* 3Com Etherlink */
|
||||
|
||||
@@ -60,16 +60,19 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct net_slirp_t {
|
||||
Slirp *slirp;
|
||||
uint8_t mac_addr[6];
|
||||
netcard_t *card; /* netcard attached to us */
|
||||
thread_t *poll_tid;
|
||||
net_evt_t tx_event;
|
||||
net_evt_t stop_event;
|
||||
netpkt_t pkt;
|
||||
netpkt_t pkt_tx_v[SLIRP_PKT_BATCH];
|
||||
Slirp * slirp;
|
||||
uint8_t mac_addr[6];
|
||||
netcard_t * card; /* netcard attached to us */
|
||||
thread_t * poll_tid;
|
||||
net_evt_t rx_event;
|
||||
net_evt_t tx_event;
|
||||
net_evt_t stop_event;
|
||||
netpkt_t pkt;
|
||||
netpkt_t pkt_tx_v[SLIRP_PKT_BATCH];
|
||||
int during_tx;
|
||||
int recv_on_tx;
|
||||
#ifdef _WIN32
|
||||
HANDLE sock_event;
|
||||
HANDLE sock_event;
|
||||
#else
|
||||
uint32_t pfd_len;
|
||||
uint32_t pfd_size;
|
||||
@@ -184,7 +187,11 @@ net_slirp_send_packet(const void *qp, size_t pkt_len, void *opaque)
|
||||
|
||||
memcpy(slirp->pkt.data, (uint8_t *) qp, pkt_len);
|
||||
slirp->pkt.len = pkt_len;
|
||||
network_rx_put_pkt(slirp->card, &slirp->pkt);
|
||||
if (slirp->during_tx) {
|
||||
network_rx_on_tx_put_pkt(slirp->card, &slirp->pkt);
|
||||
slirp->recv_on_tx = 1;
|
||||
} else
|
||||
network_rx_put_pkt(slirp->card, &slirp->pkt);
|
||||
|
||||
return pkt_len;
|
||||
}
|
||||
@@ -324,6 +331,21 @@ net_slirp_in_available(void *priv)
|
||||
net_event_set(&slirp->tx_event);
|
||||
}
|
||||
|
||||
static void
|
||||
net_slirp_rx_deferred_packets(net_slirp_t *slirp)
|
||||
{
|
||||
int packets = 0;
|
||||
|
||||
if (slirp->recv_on_tx) {
|
||||
do {
|
||||
packets = network_rx_on_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
|
||||
for (int i = 0; i < packets; i++)
|
||||
network_rx_put_pkt(slirp->card, &(slirp->pkt_tx_v[i]));
|
||||
} while (packets > 0);
|
||||
slirp->recv_on_tx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static void
|
||||
net_slirp_thread(void *priv)
|
||||
@@ -352,10 +374,13 @@ net_slirp_thread(void *priv)
|
||||
|
||||
case NET_EVENT_TX:
|
||||
{
|
||||
slirp->during_tx = 1;
|
||||
int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
|
||||
for (int i = 0; i < packets; i++) {
|
||||
for (int i = 0; i < packets; i++)
|
||||
net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len);
|
||||
}
|
||||
slirp->during_tx = 0;
|
||||
|
||||
net_slirp_rx_deferred_packets(slirp);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -398,10 +423,13 @@ net_slirp_thread(void *priv)
|
||||
if (slirp->pfd[NET_EVENT_TX].revents & POLLIN) {
|
||||
net_event_clear(&slirp->tx_event);
|
||||
|
||||
slirp->during_tx = 1;
|
||||
int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
|
||||
for (int i = 0; i < packets; i++) {
|
||||
for (int i = 0; i < packets; i++)
|
||||
net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len);
|
||||
}
|
||||
slirp->during_tx = 0;
|
||||
|
||||
net_slirp_rx_deferred_packets(slirp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -477,6 +505,7 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv
|
||||
slirp->pkt_tx_v[i].data = calloc(1, NET_MAX_FRAME);
|
||||
}
|
||||
slirp->pkt.data = calloc(1, NET_MAX_FRAME);
|
||||
net_event_init(&slirp->rx_event);
|
||||
net_event_init(&slirp->tx_event);
|
||||
net_event_init(&slirp->stop_event);
|
||||
#ifdef _WIN32
|
||||
@@ -531,8 +560,9 @@ net_slirp_close(void *priv)
|
||||
slirp_log("SLiRP: waiting for thread to end...\n");
|
||||
thread_wait(slirp->poll_tid);
|
||||
|
||||
net_event_close(&slirp->tx_event);
|
||||
net_event_close(&slirp->stop_event);
|
||||
net_event_close(&slirp->tx_event);
|
||||
net_event_close(&slirp->rx_event);
|
||||
slirp_cleanup(slirp->slirp);
|
||||
for (int i = 0; i < SLIRP_PKT_BATCH; i++) {
|
||||
free(slirp->pkt_tx_v[i].data);
|
||||
|
||||
@@ -643,6 +643,43 @@ network_rx_put(netcard_t *card, uint8_t *bufp, int len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
network_rx_on_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size)
|
||||
{
|
||||
int pkt_count = 0;
|
||||
|
||||
netqueue_t *queue = &card->queues[NET_QUEUE_RX_ON_TX];
|
||||
for (int i = 0; i < vec_size; i++) {
|
||||
if (!network_queue_get_swap(queue, pkt_vec))
|
||||
break;
|
||||
network_dump_packet(pkt_vec);
|
||||
pkt_count++;
|
||||
pkt_vec++;
|
||||
}
|
||||
|
||||
return pkt_count;
|
||||
}
|
||||
|
||||
int
|
||||
network_rx_on_tx_put(netcard_t *card, uint8_t *bufp, int len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = network_queue_put(&card->queues[NET_QUEUE_RX_ON_TX], bufp, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
network_rx_on_tx_put_pkt(netcard_t *card, netpkt_t *pkt)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = network_queue_put_swap(&card->queues[NET_QUEUE_RX_ON_TX], pkt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
network_rx_put_pkt(netcard_t *card, netpkt_t *pkt)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user