summaryrefslogtreecommitdiff
path: root/libviengoos/viengoos/thread.h
diff options
context:
space:
mode:
Diffstat (limited to 'libviengoos/viengoos/thread.h')
-rw-r--r--libviengoos/viengoos/thread.h281
1 files changed, 281 insertions, 0 deletions
diff --git a/libviengoos/viengoos/thread.h b/libviengoos/viengoos/thread.h
new file mode 100644
index 0000000..d8a69eb
--- /dev/null
+++ b/libviengoos/viengoos/thread.h
@@ -0,0 +1,281 @@
+/* thread.h - Thread definitions.
+ Copyright (C) 2007, 2008 Free Software Foundation, Inc.
+ Written by Neal H. Walfield <neal@gnu.org>.
+
+ GNU Hurd is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with GNU Hurd. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef __have_vg_thread_id_t
+# define __have_vg_thread_id_t
+
+# ifdef USE_L4
+# include <l4.h>
+typedef l4_thread_id_t vg_thread_id_t;
+# define vg_niltid l4_nilthread
+# define VG_THREAD_ID_FMT "%x"
+# else
+# include <stdint.h>
+typedef uint64_t vg_thread_id_t;
+# define vg_niltid -1
+# define VG_THREAD_ID_FMT "%llx"
+# endif
+
+#endif /* !__have_vg_thread_id_t */
+
+#if defined(__need_vg_thread_id_t)
+# undef __need_vg_thread_id_t
+#else
+
+#ifndef _VIENGOOS_THREAD_H
+#define _VIENGOOS_THREAD_H 1
+
+#include <stdint.h>
+#include <viengoos/addr.h>
+#include <viengoos/cap.h>
+#include <viengoos/messenger.h>
+
+/* The user thread control block. */
+struct vg_utcb
+{
+ /* Generic data. */
+ struct
+ {
+ union
+ {
+ struct
+ {
+ union
+ {
+ struct
+ {
+ /* Whether the thread is in activated mode. If so, any
+ activations that arrive during this time will be queued
+ or dropped. */
+ uintptr_t activated_mode : 1;
+ /* Set by the kernel to indicated that there is a pending
+ message. */
+ uintptr_t pending_message : 1;
+ /* Set by the kernel to indicate whether the thread was
+ interrupted while the EIP is in the transition range. */
+ uintptr_t interrupt_in_transition : 1;
+ };
+ uintptr_t mode;
+ };
+
+ /* The value of the IP and SP when the thread was running. */
+ uintptr_t saved_ip;
+ uintptr_t saved_sp;
+
+ uintptr_t activation_handler_sp;
+ uintptr_t activation_handler_ip;
+ uintptr_t activation_handler_end;
+
+ /* The protected payload of the capability that invoked the
+ messenger that caused this activation. */
+ uint64_t protected_payload;
+ /* The messenger's id. */
+ uint64_t messenger_id;
+
+ uintptr_t inline_words[VG_MESSENGER_INLINE_WORDS];
+ addr_t inline_caps[VG_MESSENGER_INLINE_CAPS];
+
+ union
+ {
+ struct
+ {
+ int inline_word_count : 2;
+ int inline_cap_count : 1;
+ };
+ int inline_data : 3;
+ };
+ };
+
+ char data[256];
+ };
+ };
+
+ /* Architecture-specific data. */
+ struct
+ {
+ union
+ {
+ struct
+ {
+ };
+
+ char data[256];
+ };
+ };
+};
+
+/* A thread object's user accessible capability slots. */
+enum
+ {
+ /* Root of the address space. */
+ THREAD_ASPACE_SLOT = 0,
+ /* The activity the thread is bound to. */
+ THREAD_ACTIVITY_SLOT = 1,
+ /* The messenger to post exceptions to. */
+ THREAD_EXCEPTION_MESSENGER = 2,
+ /* The user thread control block. Must be a cap_page. */
+ THREAD_UTCB = 3,
+
+ /* Total number of capability slots in a thread object. This must
+ be a power of 2. */
+ THREAD_SLOTS = 4,
+ };
+#define THREAD_SLOTS_LOG2 2
+
+enum
+{
+ HURD_EXREGS_SET_UTCB = 0x2000,
+ HURD_EXREGS_SET_EXCEPTION_MESSENGER = 0x1000,
+ HURD_EXREGS_SET_ASPACE = 0x800,
+ HURD_EXREGS_SET_ACTIVITY = 0x400,
+ HURD_EXREGS_SET_SP = _L4_XCHG_REGS_SET_SP,
+ HURD_EXREGS_SET_IP = _L4_XCHG_REGS_SET_IP,
+ HURD_EXREGS_SET_SP_IP = _L4_XCHG_REGS_SET_SP | _L4_XCHG_REGS_SET_IP,
+ HURD_EXREGS_SET_EFLAGS = _L4_XCHG_REGS_SET_FLAGS,
+ HURD_EXREGS_SET_USER_HANDLE = _L4_XCHG_REGS_SET_USER_HANDLE,
+ HURD_EXREGS_SET_REGS = (HURD_EXREGS_SET_UTCB
+ | HURD_EXREGS_SET_EXCEPTION_MESSENGER
+ | HURD_EXREGS_SET_ASPACE
+ | HURD_EXREGS_SET_ACTIVITY
+ | HURD_EXREGS_SET_SP
+ | HURD_EXREGS_SET_IP
+ | HURD_EXREGS_SET_EFLAGS
+ | HURD_EXREGS_SET_USER_HANDLE),
+
+ HURD_EXREGS_GET_REGS = _L4_XCHG_REGS_DELIVER,
+
+ HURD_EXREGS_START = _L4_XCHG_REGS_SET_HALT,
+ HURD_EXREGS_STOP = _L4_XCHG_REGS_SET_HALT | _L4_XCHG_REGS_HALT,
+
+ HURD_EXREGS_ABORT_SEND = _L4_XCHG_REGS_CANCEL_SEND,
+ HURD_EXREGS_ABORT_RECEIVE = _L4_XCHG_REGS_CANCEL_RECV,
+ HURD_EXREGS_ABORT_IPC = HURD_EXREGS_ABORT_SEND | _L4_XCHG_REGS_CANCEL_RECV,
+};
+
+enum
+ {
+ RM_thread_exregs = 600,
+ RM_thread_id,
+ RM_thread_activation_collect,
+ };
+
+#ifdef RM_INTERN
+struct thread;
+typedef struct thread *thread_t;
+#else
+typedef addr_t thread_t;
+#endif
+
+#define RPC_STUB_PREFIX rm
+#define RPC_ID_PREFIX RM
+
+#include <viengoos/rpc.h>
+
+struct hurd_thread_exregs_in
+{
+ uintptr_t aspace_cap_properties_flags;
+ struct cap_properties aspace_cap_properties;
+
+ uintptr_t sp;
+ uintptr_t ip;
+ uintptr_t eflags;
+ uintptr_t user_handle;
+};
+
+struct hurd_thread_exregs_out
+{
+ uintptr_t sp;
+ uintptr_t ip;
+ uintptr_t eflags;
+ uintptr_t user_handle;
+};
+
+/* l4_exregs wrapper. */
+RPC (thread_exregs, 6, 1, 4,
+ /* cap_t principal, cap_t thread, */
+ uintptr_t, control, struct hurd_thread_exregs_in, in,
+ cap_t, aspace, cap_t, activity, cap_t, utcb, cap_t, exception_messenger,
+ /* Out: */
+ struct hurd_thread_exregs_out, out,
+ cap_t, aspace_out, cap_t, activity_out, cap_t, utcb_out,
+ cap_t, exception_messenger_out)
+
+static inline error_t
+thread_start (addr_t thread)
+{
+ struct hurd_thread_exregs_in in;
+ struct hurd_thread_exregs_out out;
+
+ return rm_thread_exregs (ADDR_VOID, thread,
+ HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC,
+ in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID,
+ &out, NULL, NULL, NULL, NULL);
+}
+
+static inline error_t
+thread_start_sp_ip (addr_t thread, uintptr_t sp, uintptr_t ip)
+{
+ struct hurd_thread_exregs_in in;
+ struct hurd_thread_exregs_out out;
+
+ in.sp = sp;
+ in.ip = ip;
+
+ return rm_thread_exregs (ADDR_VOID, thread,
+ HURD_EXREGS_START | HURD_EXREGS_ABORT_IPC
+ | HURD_EXREGS_SET_SP_IP,
+ in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID,
+ &out, NULL, NULL, NULL, NULL);
+}
+
+static inline error_t
+thread_stop (addr_t thread)
+{
+ struct hurd_thread_exregs_in in;
+ struct hurd_thread_exregs_out out;
+
+ return rm_thread_exregs (ADDR_VOID, thread,
+ HURD_EXREGS_STOP | HURD_EXREGS_ABORT_IPC,
+ in, ADDR_VOID, ADDR_VOID, ADDR_VOID, ADDR_VOID,
+ &out, NULL, NULL, NULL, NULL);
+}
+
+/* Return the unique integer associated with thread THREAD. */
+RPC(thread_id, 0, 1, 0,
+ /* cap_t, principal, cap_t, thread, */
+ vg_thread_id_t, tid)
+
+/* Cause the delivery of a pending message, if any. */
+RPC(thread_activation_collect, 0, 0, 0
+ /* cap_t principal, cap_t thread */)
+
+#undef RPC_STUB_PREFIX
+#undef RPC_ID_PREFIX
+
+static inline vg_thread_id_t
+vg_myself (void)
+{
+ vg_thread_id_t tid;
+ error_t err = rm_thread_id (ADDR_VOID, ADDR_VOID, &tid);
+ if (err)
+ return vg_niltid;
+ return tid;
+}
+
+#endif /* _VIENGOOS_THREAD_H */
+#endif /* __need_vg_thread_id_t */