diff options
author | Anton Kling <anton@kling.gg> | 2024-07-04 20:09:51 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-07-04 20:10:47 +0200 |
commit | afc2b4d4766b0e4ee8519ac6fcd98353d3864322 (patch) | |
tree | 65094046734586e5f2da5d553305103ebb87a34f /kernel | |
parent | f89eef4733b7905dbf362cbde9aebb2dd0dcfe7d (diff) |
TCP: Allow delay for sends
This is not at all optimal for applications that already buffer their
data but can have a huge impact on those that don't. Applications that
don't wish to use this should disable this for their socket.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/drivers/pit.c | 3 | ||||
-rw-r--r-- | kernel/network/tcp.c | 2 | ||||
-rw-r--r-- | kernel/socket.c | 26 | ||||
-rw-r--r-- | kernel/socket.h | 1 | ||||
-rw-r--r-- | kernel/timer.c | 1 |
5 files changed, 25 insertions, 8 deletions
diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c index 9161885..b875449 100644 --- a/kernel/drivers/pit.c +++ b/kernel/drivers/pit.c @@ -51,7 +51,8 @@ void int_clock(reg_t *regs) { timer_current_uptime = tsc_calculate_ms(current_tsc); random_add_entropy_fast((u8 *)¤t_tsc, sizeof(current_tsc)); switch_counter++; - if (timer_current_uptime - last_flush > 50) { + if (timer_current_uptime - last_flush > 5) { + tcp_flush_buffers(); tcp_flush_acks(); last_flush = timer_current_uptime; } diff --git a/kernel/network/tcp.c b/kernel/network/tcp.c index acdbdb3..6bec93e 100644 --- a/kernel/network/tcp.c +++ b/kernel/network/tcp.c @@ -288,7 +288,7 @@ void handle_tcp(ipv4_t src_ip, ipv4_t dst_ip, const u8 *payload, } if (tcp_payload_length > 0) { if (tcp_payload_length > ringbuffer_unused(&con->incoming_buffer)) { - return; + break; } int rc = ringbuffer_write(&con->incoming_buffer, tcp_payload, tcp_payload_length); diff --git a/kernel/socket.c b/kernel/socket.c index bab80c5..82e8140 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -69,6 +69,24 @@ struct TcpConnection *tcp_find_connection(ipv4_t src_ip, u16 src_port, return NULL; } +int tcp_sync_buffer(struct TcpConnection *con); +void tcp_flush_buffers(void) { + for (int i = 0;; i++) { + struct TcpConnection *c; + int end; + if (!relist_get(&open_tcp_connections, i, (void **)&c, &end)) { + if (end) { + break; + } + continue; + } + if (TCP_STATE_CLOSED == c->state) { + continue; + } + tcp_sync_buffer(c); + } +} + void tcp_flush_acks(void) { for (int i = 0;; i++) { struct TcpConnection *c; @@ -127,9 +145,7 @@ struct UdpConnection *udp_find_connection(ipv4_t src_ip, u16 src_port, return NULL; } -int tcp_sync_buffer(vfs_fd_t *fd) { - struct TcpConnection *con = fd->inode->internal_object; - assert(con); +int tcp_sync_buffer(struct TcpConnection *con) { if (TCP_STATE_CLOSED == con->state) { return 0; } @@ -156,7 +172,7 @@ int tcp_sync_buffer(vfs_fd_t *fd) { void tcp_close(vfs_fd_t *fd) { struct TcpConnection *con = fd->inode->internal_object; assert(con); - tcp_sync_buffer(fd); + tcp_sync_buffer(con); tcp_close_connection(con); } @@ -214,7 +230,7 @@ int tcp_write(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) { struct ringbuffer *rb = &con->outgoing_buffer; if (ringbuffer_unused(rb) < len) { - if (!tcp_sync_buffer(fd)) { + if (!tcp_sync_buffer(con)) { return 0; } if (!send_tcp_packet(con, buffer, len)) { diff --git a/kernel/socket.h b/kernel/socket.h index e0cf92f..5ea71f5 100644 --- a/kernel/socket.h +++ b/kernel/socket.h @@ -144,4 +144,5 @@ int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len); void tcp_remove_connection(struct TcpConnection *con); void tcp_flush_acks(void); +void tcp_flush_buffers(void); #endif diff --git a/kernel/timer.c b/kernel/timer.c index 2121462..21020b0 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -19,7 +19,6 @@ void timer_start_init(void) { enable_interrupts(); cmos_init(); cmos_start_call(1, &has_unix_time, &start_unix_time); - enable_interrupts(); } void timer_wait_for_init(void) { |