From: Matthias Kruk Date: Fri, 13 Mar 2020 18:14:05 +0000 (+0900) Subject: kernel/core: Finish IPC mailbox implementation X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=b8db8cfe009d7cff64818d5c5100c1c65f8431fe;p=corax kernel/core: Finish IPC mailbox implementation --- diff --git a/kernel/core/Makefile b/kernel/core/Makefile index 38a6754..6ef7ddd 100644 --- a/kernel/core/Makefile +++ b/kernel/core/Makefile @@ -1,4 +1,4 @@ -OBJECTS = main.o process.o cxipc.o syscall.o posixcall.o net.o signal.o +OBJECTS = main.o process.o cxipc.o syscall.o posixcall.o net.o signal.o mailbox.o OUTPUT = core.o INCLUDES = -I../include -I../../include -I../.. CFLAGS += $(INCLUDES) -nostdinc -fno-builtin -fno-builtin-memcpy diff --git a/kernel/core/mailbox.c b/kernel/core/mailbox.c index f0a1940..1167995 100644 --- a/kernel/core/mailbox.c +++ b/kernel/core/mailbox.c @@ -1,5 +1,7 @@ -#include +#include #include +#include +#include #include "mailbox.h" int mailbox_init(struct mailbox *mbox) @@ -11,9 +13,7 @@ int mailbox_init(struct mailbox *mbox) if(mbox) { /* zero the entire mailbox */ memset(mbox, 0, sizeof(*mbox)); - - /* this should really always return zero */ - ret_val = sem_post(&(mbox->mb_wsem)); + ret_val = 0; } return(ret_val); @@ -27,34 +27,58 @@ int mailbox_put(struct mailbox *mbox, void *msg) if(mbox) { /* - * Wait until the mailbox is available. The sem_wait() - * function always succeeds, so we don't need to bother - * checking its return value + * Wait until the mailbox is available. We don't need + * to perform any error handling here since the + * mutex_lock() function will always succeed. */ - sem_wait(&(mbox->mb_wsem)); + mutex_lock(&(mbox->mb_lock)); /* place the message in the mailbox */ mbox->mb_msg = msg; /* - * Notify receivers that a message is ready to be received. - * Since we're only putting one message at a time into the - * mailbox, this really shouldn't overflow. If it does, some - * other part of the kernel must have overwritten the memory - * of we have a use-after-free bug. Either way, the mailbox - * isn't really safe to use anymore. + * Notify receivers that a message is ready to be + * received. Since we're only putting one message at a + * time into the mailbox, this really shouldn't + * overflow. If it does, some other part of the kernel + * must have overwritten the memory of we have a + * use-after-free bug. Either way, the mailbox isn't + * safe to use anymore. */ ret_val = sem_post(&(mbox->mb_rsem)); if(!ret_val) { - /* wait for synchronization */ - ret_val = sem_wait(&(mbox->mb_ssem)); - } else { - /* put the semaphore back into its original state */ - sem_post(&(mbox->mb_wsem)); + /* rendevouz with the sender */ + sem_wait(&(mbox->mb_ssem)); } + + /* + * The message has been retrieved by some other task. + * Unlock the mutex so the next task can put a message + * into the mailbox. The mutex_unlock() function + * should absolutely not fail, unless there is a bug + * in the kernel. + */ + ret_val = mutex_unlock(&(mbox->mb_lock)); + + /* + * We return the return value from mutex_unlock() so + * that the caller can determine if a kernel bug has + * occured (in which case it should probably attempt + * to exit safely. + */ } + /* + * Return values: + * 0 + * Everything went better than expected + * -EINVAL + * mbox was NULL + * -EALREADY, -EPERM + * Kernel bug + */ + return(ret_val); } @@ -66,9 +90,9 @@ int mailbox_get(struct mailbox *mbox, void **dst) if(mbox) { /* - * Wait for a message to be placed in the mailbox. This - * function always succeeds, so we don't have to check its - * return value. + * Wait for a message to be placed in the mailbox. + * This function always succeeds, so we don't have to + * check its return value. */ sem_wait(&(mbox->mb_rsem)); @@ -76,7 +100,10 @@ int mailbox_get(struct mailbox *mbox, void **dst) *dst = mbox->mb_msg; /* - + * Rendevouz with the sender: Let them know we have + * received their message. + */ + ret_val = sem_post(&(mbox->mb_ssem)); } return(ret_val); diff --git a/kernel/core/mailbox.h b/kernel/core/mailbox.h index 863658a..b5c50be 100644 --- a/kernel/core/mailbox.h +++ b/kernel/core/mailbox.h @@ -1,7 +1,7 @@ #ifndef _MAILBOX_H #define _MAILBOX_H -#include +#include #include /* @@ -25,7 +25,7 @@ * | | +------+ | | * | | | | * | | +------+   | | - * v +-(sem_post)->| wsem |<-(sem_wait)-= | + * v +-(sem_post)->| rsem |<-(sem_wait)-= | * +-------+ | +------+ | | * | mutex | | +----' * +-------+ | +------+ | @@ -90,8 +90,8 @@ struct mailbox { mutex_t mb_lock; - sem_t mb_rsem; - sem_t mb_ssem; + sem_t mb_rsem; /* read-semaphore */ + sem_t mb_ssem; /* sync-semaphore */ void *mb_msg; };