summaryrefslogtreecommitdiff
path: root/boot-proxy-exc/mach_proxy.c~
diff options
context:
space:
mode:
authorroot <root@(null).(none)>2009-05-03 17:20:00 +0200
committerroot <root@(null).(none)>2009-05-03 17:20:00 +0200
commite0faf22f31c48fb27b43c1825897d26e58feafc4 (patch)
tree65a09372b31e08a3a865bd0a88cd2718bafcd643 /boot-proxy-exc/mach_proxy.c~
This is my initial working version.
There is a bug in boot in this version: subhurd sometimes cannot boot.
Diffstat (limited to 'boot-proxy-exc/mach_proxy.c~')
-rw-r--r--boot-proxy-exc/mach_proxy.c~97
1 files changed, 97 insertions, 0 deletions
diff --git a/boot-proxy-exc/mach_proxy.c~ b/boot-proxy-exc/mach_proxy.c~
new file mode 100644
index 00000000..1bb46821
--- /dev/null
+++ b/boot-proxy-exc/mach_proxy.c~
@@ -0,0 +1,97 @@
+/*
+ Copyright (C) 2009 Free Software Foundation, Inc.
+ Written by Zheng Da.
+
+ This file is part of the GNU Hurd.
+
+ The GNU Hurd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ The GNU Hurd is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with the GNU Hurd; see the file COPYING. If not, write to
+ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <string.h>
+
+#include "util.h"
+#include "mach_proxy.h"
+
+static LIST_HEADER (tasks_head);
+
+static struct mutex tasks_lock = MUTEX_INITIALIZER;
+
+int create_pseudo_task (task_t real_task, task_t *ret_pseudo_task)
+{
+ /* the first task is the kernel task. */
+ struct task_info *task_pi;
+ task_t pseudo_task;
+ error_t err;
+
+ err = ports_create_port (task_portclass, port_bucket,
+ sizeof (struct task_info), &task_pi);
+ if (err)
+ return err;
+
+ task_pi->task_port = real_task;
+ task_pi->exc_pi = NULL;
+ task_pi->user_exc_port = 0;
+ mutex_info (&task_pi->lock);
+ entry_init (&task_pi->list);
+ mutex_lock (&tasks_lock);
+ add_entry_end (&tasks_head, &task_pi->list);
+ mutex_unlock (&tasks_lock);
+
+ pseudo_task = ports_get_right (task_pi);
+ mach_port_insert_right (mach_task_self (), pseudo_task, pseudo_task,
+ MACH_MSG_TYPE_MAKE_SEND);
+ ports_port_deref (task_pi);
+
+ if (ret_pseudo_task)
+ *ret_pseudo_task = pseudo_task;
+
+ err = task_set_kernel_port (real_task, pseudo_task);
+ if (err)
+ {
+ debug ("fail to set the kernel port: %s", strerror (err));
+ ports_destroy_right (task_pi);
+ }
+
+ return err;
+}
+
+void clean_pseudo_task (void *pi)
+{
+ struct task_info *task = pi;
+
+ debug ("remove a pseudo task from the list");
+ mutex_lock (&tasks_lock);
+ remove_entry (&task->list);
+ mutex_unlock (&tasks_lock);
+
+ if (task->exc_pi)
+ ports_destroy_right (task->exc_pi);
+ if (task->user_exc_port)
+ mach_port_deallocate (mach_task_self (), task->user_exc_port);
+}
+
+void foreach_task (task_callback_t callback)
+{
+ struct list *entry = &tasks_head;
+ mutex_lock (&tasks_lock);
+ for (entry = tasks_head.next; entry != &tasks_head; entry = entry->next)
+ {
+// mutex_unlock (&tasks_lock);
+ struct task_info *task_pi = LIST_ENTRY (entry, struct task_info, list);
+ if (callback (task_pi))
+ break;
+// mutex_lock (&tasks_lock);
+ }
+ mutex_unlock (&tasks_lock);
+}