mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-28 21:28:21 +00:00
kernel: do preparation work for copyless read/write
This commit is contained in:
@@ -365,6 +365,11 @@ static int localsock_send(socket_t *socket, sockdesc_t *sockdesc) {
|
||||
}
|
||||
|
||||
sockdesc->donecount = ringbuffer_write(&peer->ringbuffer, sockdesc->buffer, sockdesc->count);
|
||||
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
|
||||
error = EFAULT;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
__assert(sockdesc->donecount > 0);
|
||||
|
||||
error = sendctrl(socket, sockdesc->ctrl, sockdesc->ctrllen, sockdesc->donecount);
|
||||
@@ -465,8 +470,17 @@ static int localsock_recv(socket_t *socket, sockdesc_t *sockdesc) {
|
||||
|
||||
if (flags & SOCKET_RECV_FLAGS_PEEK) {
|
||||
sockdesc->donecount = ringbuffer_peek(&localsocket->ringbuffer, sockdesc->buffer, 0, recvcount);
|
||||
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
|
||||
error = EFAULT;
|
||||
goto leave;
|
||||
}
|
||||
} else {
|
||||
sockdesc->donecount = ringbuffer_read(&localsocket->ringbuffer, sockdesc->buffer, recvcount);
|
||||
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
|
||||
error = EPIPE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
localsocket_t *peer = pair->client == localsocket ? pair->server : pair->client;
|
||||
// signal that there is space to write for any threads blocked on this socket
|
||||
if (peer && sockdesc->donecount)
|
||||
|
||||
+20
-5
@@ -1305,8 +1305,13 @@ static int tcp_send(socket_t *socket, sockdesc_t *sockdesc) {
|
||||
size_t writesize = min(TCB_RINGBUFFER_SIZE - RINGBUFFER_DATACOUNT(&tcb->transmitbuffer), sockdesc->count);
|
||||
__assert(writesize);
|
||||
|
||||
__assert(ringbuffer_write(&tcb->transmitbuffer, sockdesc->buffer, writesize) == writesize);
|
||||
sockdesc->donecount = writesize;
|
||||
sockdesc->donecount = ringbuffer_write(&tcb->transmitbuffer, sockdesc->buffer, writesize);
|
||||
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
|
||||
error = EFAULT;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
__assert(sockdesc->donecount == writesize);
|
||||
|
||||
if (tcb->sndnext == tcb->sndunack)
|
||||
error = tcp_transmitnextsegment(tcb);
|
||||
@@ -1381,14 +1386,24 @@ static int tcp_recv(socket_t *socket, sockdesc_t *sockdesc) {
|
||||
|
||||
size_t copycount = min(RINGBUFFER_DATACOUNT(&tcb->receivebuffer), sockdesc->count);
|
||||
if (flags & SOCKET_RECV_FLAGS_PEEK) {
|
||||
__assert(ringbuffer_peek(&tcb->receivebuffer, sockdesc->buffer, 0, copycount) == copycount);
|
||||
sockdesc->donecount = ringbuffer_peek(&tcb->receivebuffer, sockdesc->buffer, 0, copycount);
|
||||
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
|
||||
error = EFAULT;
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
__assert(ringbuffer_read(&tcb->receivebuffer, sockdesc->buffer, copycount) == copycount);
|
||||
sockdesc->donecount = ringbuffer_read(&tcb->receivebuffer, sockdesc->buffer, copycount);
|
||||
if (sockdesc->donecount == RINGBUFFER_USER_COPY_FAILED) {
|
||||
error = EFAULT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
tcb->rcvwindow += copycount;
|
||||
// notify about the window increase
|
||||
tcp_ack(tcb);
|
||||
}
|
||||
sockdesc->donecount = copycount;
|
||||
|
||||
__assert(sockdesc->donecount == copycount);
|
||||
|
||||
cleanup:
|
||||
MUTEX_RELEASE(&tcb->mutex);
|
||||
|
||||
@@ -262,6 +262,7 @@ static int udp_recv(socket_t *socket, sockdesc_t *sockdesc) {
|
||||
bool intstate = interrupt_set(false);
|
||||
spinlock_acquire(&udpsocket->ringbufferlock);
|
||||
|
||||
// TODO rewrite this to handle a possible sleep in the ringbuffer
|
||||
size_t copycount;
|
||||
dataheader_t header;
|
||||
if (flags & SOCKET_RECV_FLAGS_PEEK) {
|
||||
|
||||
Reference in New Issue
Block a user