Use a ring buffer for mail
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m30s

This commit is contained in:
2026-02-21 15:52:31 +01:00
parent 7601ea68e2
commit dc021c0469
3 changed files with 25 additions and 15 deletions

View File

@@ -1,5 +1,6 @@
#include <libk/list.h> #include <libk/list.h>
#include <libk/minmax.h> #include <libk/minmax.h>
#include <libk/ringbuffer.h>
#include <libk/std.h> #include <libk/std.h>
#include <libk/string.h> #include <libk/string.h>
#include <mm/liballoc.h> #include <mm/liballoc.h>
@@ -15,10 +16,7 @@ void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedu
spin_lock (&mail->resource->lock); spin_lock (&mail->resource->lock);
if (mail->pending_mesg != NULL) ringbuffer_fini (&mail->ringbuffer);
free (mail->pending_mesg);
mail->pending_mesg_size = 0;
spin_lock (&mail->send_sq.lock); 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); spin_lock (&mail->resource->lock);
/* mail full */ /* 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); proc_sq_suspend (proc, &mail->send_sq, &mail->resource->lock, rctx);
return; 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 */ /* mail is empty and nobody is waiting */
void* mesg = malloc (data_size); void* mesg = malloc (data_size);
if (mesg != NULL) { if (mesg != NULL) {
mail->pending_mesg = mesg; memcpy (mesg, data, data_size);
memcpy (mail->pending_mesg, data, data_size); struct mail_packet packet = {.packet_buffer = mesg, .packet_size = data_size};
mail->pending_mesg_size = data_size; ringbuffer_push (struct mail_packet, &mail->ringbuffer, packet);
} }
spin_unlock (&mail->resource->lock); 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); spin_lock (&mail->resource->lock);
/* consume mesg if available */ /* consume mesg if available */
if (mail->pending_mesg != NULL) { if (mail->ringbuffer.count > 0) {
memcpy (recv_buffer, mail->pending_mesg, min (recv_size, mail->pending_mesg_size)); struct mail_packet packet;
free (mail->pending_mesg); ringbuffer_pop (struct mail_packet, &mail->ringbuffer, &packet);
mail->pending_mesg = NULL; memcpy (recv_buffer, packet.packet_buffer, min (recv_size, packet.packet_size));
mail->pending_mesg_size = 0; free (packet.packet_buffer);
/* check for suspended sender */ /* check for suspended sender */
spin_lock (&mail->send_sq.lock); spin_lock (&mail->send_sq.lock);

View File

@@ -2,21 +2,28 @@
#define _KERNEL_PROC_MAIL_H #define _KERNEL_PROC_MAIL_H
#include <libk/list.h> #include <libk/list.h>
#include <libk/ringbuffer.h>
#include <libk/std.h> #include <libk/std.h>
#include <proc/suspension_q.h> #include <proc/suspension_q.h>
#define PROC_MAIL_MAX 1024
struct proc; struct proc;
struct proc_resource; struct proc_resource;
struct cpu; struct cpu;
struct reschedule_ctx; struct reschedule_ctx;
struct mail_packet {
void* packet_buffer;
size_t packet_size;
};
struct proc_mail { struct proc_mail {
struct proc_resource* resource; struct proc_resource* resource;
struct proc_suspension_q send_sq; struct proc_suspension_q send_sq;
struct proc_suspension_q recv_sq; struct proc_suspension_q recv_sq;
void* pending_mesg; struct ringbuffer ringbuffer;
size_t pending_mesg_size;
}; };
void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx); void proc_cleanup_resource_mail (struct proc_resource* resource, struct reschedule_ctx* rctx);

View File

@@ -69,6 +69,11 @@ struct proc_resource* proc_create_resource_mail (struct procgroup* procgroup, in
resource->rid = rid; resource->rid = rid;
resource->type = PR_MAIL; 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); spin_lock (&procgroup->lock);
rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link, rbtree_insert (struct proc_resource, &procgroup->resource_tree, &resource->resource_tree_link,
resource_tree_link, rid); resource_tree_link, rid);