[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