[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Lost] [PATCH 2/2] kernel2: Shared Memory



+ kernel2: Shared Memory
---
 src/kernel2/include/mm.h       |   16 ++++
 src/kernel2/include/syscall.h  |   11 +++
 src/kernel2/src/init.c         |    3 +
 src/kernel2/src/mm/shm.c       |  171 ++++++++++++++++++++++++++++++++++++++++
 src/kernel2/src/syscall.c      |    4 +
 src/kernel2/src/syscalls/shm.c |   72 +++++++++++++++++
 src/kernel2/src/tasks/pm.c     |    2 +
 7 files changed, 279 insertions(+), 0 deletions(-)
 create mode 100644 src/kernel2/src/mm/shm.c
 create mode 100644 src/kernel2/src/syscalls/shm.c

diff --git a/src/kernel2/include/mm.h b/src/kernel2/include/mm.h
index dba075c..eeb144c 100644
--- a/src/kernel2/include/mm.h
+++ b/src/kernel2/include/mm.h
@@ -97,5 +97,21 @@ void mmc_activate(mmc_context_t* context);
 
 #define mmc_current_context() (*cpu_get_current()->mm_context)
 
+/*
+ * Shared Memory
+ */
+
+/// Initialisiert die SHM-Verwaltung
+void shm_init(void);
+
+///  Neuen Shared Memory reservieren
+uint32_t shm_create(size_t size);
+
+/// Bestehenden Shared Memory oeffnen.
+void* shm_attach(uint32_t id);
+
+/// Shared Memory schliessen.
+void shm_detach(uint32_t id);
+
 #endif
 
diff --git a/src/kernel2/include/syscall.h b/src/kernel2/include/syscall.h
index 32c8141..ff4fe29 100644
--- a/src/kernel2/include/syscall.h
+++ b/src/kernel2/include/syscall.h
@@ -120,6 +120,17 @@ void syscall_io_request_port(uint32_t port, uint32_t length);
 uint64_t syscall_get_tick_count(void);
 
 
+// SHM
+/// Neuen Shared Memory reservieren
+uint32_t syscall_shm_create(size_t size);
+
+/// Bestehenden Shared Memory oeffnen
+void* syscall_shm_attach(uint32_t id);
+
+/// Shared Memory schliessen
+void syscall_shm_detach(uint32_t id);
+
+
 // RPC
 /// RPC-Handler registrieren
 void syscall_set_rpc_handler(vaddr_t address);
diff --git a/src/kernel2/src/init.c b/src/kernel2/src/init.c
index 744abc6..9d1909b 100644
--- a/src/kernel2/src/init.c
+++ b/src/kernel2/src/init.c
@@ -197,6 +197,9 @@ void init(int multiboot_magic, struct multiboot_info *boot_info, bool bsp)
         // Prozessverwaltung initialisieren
         pm_init();
 
+        // Shared Memory initialisieren
+        shm_init();
+
         // Init-Modul laden
         load_init_module(&multiboot_info);
 
diff --git a/src/kernel2/src/mm/shm.c b/src/kernel2/src/mm/shm.c
new file mode 100644
index 0000000..b48defc
--- /dev/null
+++ b/src/kernel2/src/mm/shm.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008 The LOST Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the LOST Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the LOST Project
+ *     and its contributors.
+ * 4. Neither the name of the LOST Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <collections.h>
+
+#include "mm.h"
+#include "cpu.h"
+#include "tasks.h"
+
+struct shm_desc {
+    uint64_t            id;
+    struct tree_item    tree_item;
+
+    paddr_t             paddr;
+    size_t              num_pages;
+    list_t*             processes;
+};
+
+struct shm_process {
+    pm_process_t*       process;
+    vaddr_t             vaddr;
+};
+
+static tree_t* shms = NULL;
+static uint32_t shm_last_id = 0;
+
+/**
+ * Initialisiert die SHM-Verwaltung
+ */
+void shm_init(void)
+{
+    shms = tree_create(
+        offsetof(struct shm_desc, tree_item),
+        offsetof(struct shm_desc, id));
+}
+
+/**
+ * Neuen Shared Memory reservieren
+ *
+ * @return ID des neu angelegten Shared Memory. Der Aufrufer muss anschliessend
+ * syscall_shm_attach aufrufen, um auf den Speicher zugreifen zu koennen.
+ */
+uint32_t shm_create(size_t size)
+{
+    // FIXME Die Pages muessen nicht physisch zusammenhaengend sein
+    paddr_t shm_phys = pmm_alloc(NUM_PAGES(size));
+    uint32_t id = ++shm_last_id;
+    struct shm_desc* shm;
+
+    while (tree_search(shms, id)) {
+        id++;
+    }
+
+    shm = calloc(1, sizeof(*shm));
+    shm->id = id;
+    shm->num_pages = NUM_PAGES(size);
+    shm->paddr = shm_phys;
+    shm->processes = list_create();
+
+    tree_insert(shms, shm);
+
+    return id;
+}
+
+/**
+ * Bestehenden Shared Memory oeffnen.
+ *
+ * @param id ID des zu oeffnenden Shared Memory
+ * @return Virtuelle Adresse des geoeffneten Shared Memory; NULL, wenn der
+ * Shared Memory mit der angegebenen ID nicht existiert.
+ */
+void* shm_attach(uint32_t id)
+{
+    struct shm_desc* shm = tree_search(shms, id);
+    void* ret;
+    struct shm_process* shm_proc;
+
+    if (shm == NULL) {
+        return NULL;
+    }
+
+    ret = mmc_automap(&mmc_current_context(), shm->paddr, shm->num_pages,
+        MM_USER_START, MM_USER_END, MM_FLAGS_USER_DATA);
+
+    if (ret == NULL) {
+        return NULL;
+    }
+
+    shm_proc = calloc(1, sizeof(*shm_proc));
+    shm_proc->process = cpu_get_current()->thread->process;
+    shm_proc->vaddr = ret;
+    list_push(shm->processes, shm_proc);
+
+    return ret;
+}
+
+/**
+ * Shared Memory schliessen. Wenn keine Prozesse den Shared Memory mehr
+ * geoeffnet haben, wird er geloescht.
+ *
+ * @param id ID des zu schliessenden Shared Memory
+ */
+void shm_detach(uint32_t id)
+{
+    struct shm_desc* shm = tree_search(shms, id);
+    struct shm_process* shm_proc;
+    pm_process_t* current_proc = cpu_get_current()->thread->process;
+    int i;
+
+    if (shm == NULL) {
+        return;
+    }
+
+    for (i = 0; (shm_proc = list_get_element_at(shm->processes, i)); i++) {
+        if (shm_proc->process == current_proc) {
+            list_remove(shm->processes, i);
+            goto found;
+        }
+    }
+
+    return;
+
+found:
+
+    mmc_unmap(&mmc_current_context(), shm_proc->vaddr, shm->num_pages);
+
+    // Wenn es der letzte Benutzer war, SHM loeschen
+    if (list_is_empty(shm->processes)) {
+        list_destroy(shm->processes);
+        pmm_free(shm->paddr, shm->num_pages);
+        tree_remove(shms, shm);
+        free(shm);
+    }
+
+    return;
+}
diff --git a/src/kernel2/src/syscall.c b/src/kernel2/src/syscall.c
index 5870706..730fe40 100644
--- a/src/kernel2/src/syscall.c
+++ b/src/kernel2/src/syscall.c
@@ -80,6 +80,10 @@ void syscall_init()
 
     syscall_register(SYSCALL_PUTSN, (void*) &syscall_putsn, 2);
     syscall_register(SYSCALL_GET_TICK_COUNT, syscall_get_tick_count, 0);
+
+    syscall_register(SYSCALL_SHM_CREATE, &syscall_shm_create, 1);
+    syscall_register(SYSCALL_SHM_ATTACH, &syscall_shm_attach, 1);
+    syscall_register(SYSCALL_SHM_DETACH, &syscall_shm_detach, 1);
 }
 
 /**
diff --git a/src/kernel2/src/syscalls/shm.c b/src/kernel2/src/syscalls/shm.c
new file mode 100644
index 0000000..89667f9
--- /dev/null
+++ b/src/kernel2/src/syscalls/shm.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2008 The LOST Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the LOST Project
+ * by Kevin Wolf.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the LOST Project
+ *     and its contributors.
+ * 4. Neither the name of the LOST Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "syscall.h"
+#include "mm.h"
+
+/**
+ * Neuen Shared Memory reservieren
+ *
+ * @return ID des neu angelegten Shared Memory. Der Aufrufer muss anschliessend
+ * syscall_shm_attach aufrufen, um auf den Speicher zugreifen zu koennen.
+ */
+uint32_t syscall_shm_create(size_t size)
+{
+    return shm_create(size);
+}
+
+/**
+ * Bestehenden Shared Memory oeffnen.
+ *
+ * @param id ID des zu oeffnenden Shared Memory
+ * @return Virtuelle Adresse des geoeffneten Shared Memory; NULL, wenn der
+ * Shared Memory mit der angegebenen ID nicht existiert.
+ */
+void* syscall_shm_attach(uint32_t id)
+{
+    return shm_attach(id);
+}
+
+/**
+ * Shared Memory schliessen. Wenn keine Prozesse den Shared Memory mehr
+ * geoeffnet haben, wird er geloescht.
+ *
+ * @param id ID des zu schliessenden Shared Memory
+ */
+void syscall_shm_detach(uint32_t id)
+{
+    shm_detach(id);
+}
+
diff --git a/src/kernel2/src/tasks/pm.c b/src/kernel2/src/tasks/pm.c
index e47a11c..64a814c 100644
--- a/src/kernel2/src/tasks/pm.c
+++ b/src/kernel2/src/tasks/pm.c
@@ -166,6 +166,8 @@ void pm_destroy(pm_process_t* process)
     // TODO Die einzelnen Listenglieder freigeben
     list_destroy(process->rpcs);
 
+    // TODO Alle SHMs freigeben
+
     // Den Prozess aus der Liste entfernen
     pm_process_t* _proc;
     int i = 0;
-- 
1.5.4.5