From dc021c0469e061f5a7c0db78a8692ab54e33bc73 Mon Sep 17 00:00:00 2001 From: kamkow1 Date: Sat, 21 Feb 2026 15:52:31 +0100 Subject: [PATCH] Use a ring buffer for mail --- kernel/proc/mail.c | 24 +++++++++++------------- kernel/proc/mail.h | 11 +++++++++-- kernel/proc/resource.c | 5 +++++ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/kernel/proc/mail.c b/kernel/proc/mail.c index d979e78..cedb57d 100644 --- a/kernel/proc/mail.c +++ b/kernel/proc/mail.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -15,10 +16,7 @@ void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedu spin_lock (&mail->resource->lock); - if (mail->pending_mesg != NULL) - free (mail->pending_mesg); - - mail->pending_mesg_size = 0; + ringbuffer_fini (&mail->ringbuffer); spin_lock (&mail->send_sq.lock); @@ -45,7 +43,7 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul spin_lock (&mail->resource->lock); /* mail full */ - if (mail->pending_mesg != NULL) { + if (mail->ringbuffer.count == mail->ringbuffer.capacity) { proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, rctx); return; } @@ -83,9 +81,9 @@ void proc_mail_send (struct proc* proc, struct proc_mail* mail, struct reschedul /* mail is empty and nobody is waiting */ void* mesg = malloc (data_size); if (mesg != NULL) { - mail->pending_mesg = mesg; - memcpy (mail->pending_mesg, data, data_size); - mail->pending_mesg_size = data_size; + memcpy (mesg, data, data_size); + struct mail_packet packet = {.packet_buffer = mesg, .packet_size = data_size}; + ringbuffer_push (struct mail_packet, &mail->ringbuffer, packet); } spin_unlock (&mail->resource->lock); @@ -101,11 +99,11 @@ void proc_mail_receive (struct proc* proc, struct proc_mail* mail, struct resche spin_lock (&mail->resource->lock); /* consume mesg if available */ - if (mail->pending_mesg != NULL) { - memcpy (recv_buffer, mail->pending_mesg, min (recv_size, mail->pending_mesg_size)); - free (mail->pending_mesg); - mail->pending_mesg = NULL; - mail->pending_mesg_size = 0; + if (mail->ringbuffer.count > 0) { + struct mail_packet packet; + ringbuffer_pop (struct mail_packet, &mail->ringbuffer, &packet); + memcpy (recv_buffer, packet.packet_buffer, min (recv_size, packet.packet_size)); + free (packet.packet_buffer); /* check for suspended sender */ spin_lock (&mail->send_sq.lock); diff --git a/kernel/proc/mail.h b/kernel/proc/mail.h index 29cc9f7..d2fc949 100644 --- a/kernel/proc/mail.h +++ b/kernel/proc/mail.h @@ -2,21 +2,28 @@ #define _KERNEL_PROC_MAIL_H #include +#include #include #include +#define PROC_MAIL_MAX 1024 + struct proc; struct proc_resource; struct cpu; struct reschedule_ctx; +struct mail_packet { + void* packet_buffer; + size_t packet_size; +}; + struct proc_mail { struct proc_resource* resource; struct proc_suspension_q send_sq; struct proc_suspension_q recv_sq; - void* pending_mesg; - size_t pending_mesg_size; + struct ringbuffer ringbuffer; }; void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx); diff --git a/kernel/proc/resource.c b/kernel/proc/resource.c index a7c9bdf..0cc8b06 100644 --- a/kernel/proc/resource.c +++ b/kernel/proc/resource.c @@ -69,6 +69,11 @@ struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup, in resource->rid = rid; resource->type = PR_MAIL; + if (!ringbuffer_init (&resource->u.mail.ringbuffer, PROC_MAIL_MAX, sizeof (struct mail_packet))) { + free (resource); + return NULL; + } + spin_lock (&procgroup->lock); rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, resource_tree_link, rid);