]> git.corax.cc Git - corax/commitdiff
kernel/core: Finish IPC mailbox implementation
authorMatthias Kruk <m@m10k.eu>
Fri, 13 Mar 2020 18:14:05 +0000 (03:14 +0900)
committerMatthias Kruk <m@m10k.eu>
Fri, 13 Mar 2020 18:14:05 +0000 (03:14 +0900)
kernel/core/Makefile
kernel/core/mailbox.c
kernel/core/mailbox.h

index 38a6754d98cb25e50728bf08416da582fdabb65d..6ef7ddd338bde96ac6c7a78affd2d28b7f1cb03c 100644 (file)
@@ -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
index f0a194057e8aa90bb63a3702b864928784997f0b..116799573f83b5878333b0e3d7d6843cd993fb67 100644 (file)
@@ -1,5 +1,7 @@
-#include <spinlock.h>
+#include <mutex.h>
 #include <sem.h>
+#include <corax/errno.h>
+#include <string.h>
 #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);
index 863658ae83e6559ebe6b36c0aac38c5c3c720d24..b5c50be10cc3ac7ab3d8cca825f4a943d635bc99 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _MAILBOX_H
 #define _MAILBOX_H
 
-#include <spinlock.h>
+#include <mutex.h>
 #include <sem.h>
 
 /*
@@ -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;
 };