[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Lost] [Patch] kernel2: Syscalls fuer p/v
+ kernel2: Syscalls fuer p() und v()
Index: trunk/src/kernel2/src/syscalls/pv.c
===================================================================
--- /dev/null
+++ trunk/src/kernel2/src/syscalls/pv.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 <types.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "syscall.h"
+#include "tasks.h"
+#include "cpu.h"
+
+/**
+ * Kritischen Abschnitt einleiten (Keine RPCs ausser Antworten sind mehr
+ * zulaessig)
+ */
+int syscall_pm_p(void)
+{
+ pm_block_rpc(cpu_get_current()->thread->process,
+ cpu_get_current()->thread->process->pid);
+
+ return 0;
+}
+
+/**
+ * Kritischen Abschnitt verlassen
+ *
+ * @param pid PID, fuer die wieder RPCs zugelassen werden sollen. 0 fuer
+ * den aufrufenden Prozess selbst
+ */
+int syscall_pm_v(pid_t pid)
+{
+ if (pid == 0) {
+ pm_unblock_rpc(cpu_get_current()->thread->process,
+ cpu_get_current()->thread->process->pid);
+ } else {
+ pm_unblock_rpc(pm_get(pid), cpu_get_current()->thread->process->pid);
+ }
+
+ return 0;
+}
Index: trunk/src/kernel2/src/syscall.c
===================================================================
--- trunk.orig/src/kernel2/src/syscall.c
+++ trunk/src/kernel2/src/syscall.c
@@ -57,6 +57,9 @@ void syscall_init()
syscall_register(SYSCALL_PM_GET_CMDLINE, (void*) syscall_pm_get_cmdline,
0);
+ syscall_register(SYSCALL_PM_P, (void*) &syscall_pm_p, 0);
+ syscall_register(SYSCALL_PM_V, (void*) &syscall_pm_v, 1);
+
syscall_register(SYSCALL_SET_RPC_HANDLER, (void*) &syscall_set_rpc_handler,
1);
Index: trunk/src/kernel2/include/syscall.h
===================================================================
--- trunk.orig/src/kernel2/include/syscall.h
+++ trunk/src/kernel2/include/syscall.h
@@ -90,6 +90,11 @@ pid_t syscall_pm_get_parent_pid(pid_t pi
/// Befehlszeile des aktuellen Prozesses abfragen
const char* syscall_pm_get_cmdline();
+/// Kritischen Abschnitt betreten
+int syscall_pm_p(void);
+
+/// Kritischen Abschnitt verlassen
+int syscall_pm_v(pid_t pid);
// RPC
/// RPC-Handler registrieren
Index: trunk/src/kernel2/include/tasks.h
===================================================================
--- trunk.orig/src/kernel2/include/tasks.h
+++ trunk/src/kernel2/include/tasks.h
@@ -70,6 +70,12 @@ typedef struct {
/// Der RPC-Handler fuer diesen Prozess
vaddr_t rpc_handler;
+
+ /// Die PID des Prozesses, der RPC fuer diesen Prozess abgestellt hat
+ dword blocked_by_pid;
+
+ /// Die Anzahl von p()s (RPC wird erst bei 0 wieder freigegeben)
+ dword blocked_count;
} pm_process_t;
@@ -115,6 +121,13 @@ bool pm_unblock(pm_process_t* process);
/// Prozess anhand seiner PID suchen
pm_process_t* pm_get(pid_t pid);
+/// RPC-Empfang fuer einen Prozess blockieren
+bool pm_block_rpc(pm_process_t* task, pid_t blocked_by);
+
+/// RPC-Empfang fuer einen Prozess wieder freigeben
+bool pm_unblock_rpc(pm_process_t* task, pid_t blocked_by);
+
+
/**
* Threadverwaltung
*/
Index: trunk/src/kernel2/src/tasks/pm.c
===================================================================
--- trunk.orig/src/kernel2/src/tasks/pm.c
+++ trunk/src/kernel2/src/tasks/pm.c
@@ -239,3 +239,51 @@ pm_process_t* pm_get(pid_t pid) {
}
return process;
}
+
+/**
+ * Blockiert einen Task. Zu einem blockierten Task können keine RPC-Aufrufe
+ * durchgeführt werden. Wenn der Task durch einen anderen Task blockiert ist,
+ * wird er auÃ?erdem vom Scheduler nicht mehr aufgerufen, bis der Task
+ * entblockt wird.
+ *
+ * @param task Zu blockierender Task
+ * @param blocked_by PID des blockierenden Tasks
+ */
+bool pm_block_rpc(pm_process_t* task, pid_t blocked_by)
+{
+ if(task->blocked_by_pid == blocked_by) {
+ task->blocked_count++;
+ return TRUE;
+ }
+
+ if (task->blocked_by_pid) {
+ return FALSE;
+ }
+
+ task->blocked_by_pid = blocked_by;
+ task->blocked_count = 1;
+
+ return TRUE;
+}
+
+/**
+ * Entblockt einen blockierten Task. Dies ist nur möglich, wenn der
+ * aufrufende Task dem blockierenden Task entspricht
+ *
+ * @param task Zu entblockender Task
+ * @param blocked_by Aufrufender Task
+ *
+ * @return true, wenn der Task erfolgreich entblockt wurde, false
+ * im Fehlerfall.
+ */
+bool pm_unblock_rpc(pm_process_t* task, pid_t blocked_by)
+{
+ if (task->blocked_by_pid == blocked_by) {
+ if(--(task->blocked_count) == 0) {
+ task->blocked_by_pid = 0;
+ }
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}