From 668990b81b59d1e4fb2407e1171dfb3644facb5e Mon Sep 17 00:00:00 2001 From: jewelcodes Date: Fri, 4 Oct 2024 20:23:27 -0400 Subject: [PATCH] ipc: refactor sockets for performance --- src/include/kernel/socket.h | 3 ++ src/ipc/sockio.c | 55 +++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/include/kernel/socket.h b/src/include/kernel/socket.h index 750f89b..20580b7 100644 --- a/src/include/kernel/socket.h +++ b/src/include/kernel/socket.h @@ -17,6 +17,8 @@ #define MAX_SOCKETS (1 << 18) // 262k #define SOCKET_DEFAULT_BACKLOG 1024 // default socket backlog size +#define SOCKET_IO_BACKLOG 64 // default I/O backlog size + /* socket family/domain - only Unix sockets will be implemented in the kernel */ #define AF_UNIX 1 #define AF_LOCAL AF_UNIX @@ -58,6 +60,7 @@ typedef struct SocketDescriptor { bool listener; int globalIndex; int type, protocol, backlogMax, backlogCount; + int inboundMax, outboundMax; // buffer sizes int inboundCount, outboundCount; void **inbound, **outbound; size_t *inboundLen, *outboundLen; diff --git a/src/ipc/sockio.c b/src/ipc/sockio.c index 0ca6efe..e361f52 100644 --- a/src/ipc/sockio.c +++ b/src/ipc/sockio.c @@ -46,24 +46,40 @@ ssize_t send(Thread *t, int sd, const void *buffer, size_t len, int flags) { sa_family_t family = self->address.sa_family; if(family == AF_UNIX || family == AF_LOCAL) { - // simply append to the peer's inbound list - void **newlist = realloc(peer->inbound, (peer->inboundCount+1) * sizeof(void *)); - if(!newlist) { - socketRelease(); - return -ENOBUFS; + if(!peer->inbound || !peer->inboundLen || !peer->inboundMax) { + // ensure that the peer's inbound list exists at all + peer->inbound = calloc(SOCKET_IO_BACKLOG, sizeof(void *)); + peer->inboundLen = calloc(SOCKET_IO_BACKLOG, sizeof(size_t)); + + if(!peer->inbound || !peer->inboundLen) { + socketRelease(); + return -ENOMEM; + } + + peer->inboundMax = SOCKET_IO_BACKLOG; + peer->inboundCount = 0; } - peer->inbound = newlist; + if(peer->inboundCount >= peer->inboundMax) { + // reallocate the backlog if necessary + void **newlist = realloc(peer->inbound, peer->inboundMax * 2 * sizeof(void *)); + if(!newlist) { + socketRelease(); + return -ENOMEM; + } + + peer->inbound = newlist; - size_t *newlen = realloc(peer->inboundLen, (peer->inboundCount+1) * sizeof(size_t)); + size_t *newlen = realloc(peer->inboundLen, peer->inboundMax * 2 * sizeof(void *)); + if(!newlen) { + socketRelease(); + return -ENOMEM; + } - if(!newlen) { - socketRelease(); - return -ENOBUFS; + peer->inboundLen = newlen; + peer->inboundMax *= 2; } - peer->inboundLen = newlen; - void *message = malloc(len); if(!message) { socketRelease(); @@ -72,8 +88,8 @@ ssize_t send(Thread *t, int sd, const void *buffer, size_t len, int flags) { // and send memcpy(message, buffer, len); - newlist[peer->inboundCount] = message; - newlen[peer->inboundCount] = len; + peer->inbound[peer->inboundCount] = message; + peer->inboundLen[peer->inboundCount] = len; peer->inboundCount++; socketRelease(); @@ -136,15 +152,8 @@ ssize_t recv(Thread *t, int sd, void *buffer, size_t len, int flags) { self->inboundCount--; if(self->inboundCount) { - memmove(&self->inbound[0], &self->inbound[1], self->inboundCount * sizeof(void *)); - memmove(&self->inboundLen[0], &self->inboundLen[1], self->inboundCount * sizeof(size_t)); - //self->inbound = realloc(self->inbound, self->inboundCount * sizeof(void *)); - //self->inboundLen = realloc(self->inboundLen, self->inboundCount * sizeof(size_t)); - } else { - free(self->inbound); - free(self->inboundLen); - self->inbound = NULL; - self->inboundLen = NULL; + memcpy(&self->inbound[0], &self->inbound[1], self->inboundCount * sizeof(void *)); + memcpy(&self->inboundLen[0], &self->inboundLen[1], self->inboundCount * sizeof(size_t)); } }