/* thread.h - Thread object interface. Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. Written by Neal H. Walfield . 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 3 of the License, 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 this program. If not, see . */ #ifndef RM_THREAD_H #define RM_THREAD_H #include #include #include #include #include "object.h" #include "list.h" #include "vm.h" #include "sys.h" /* Forward. */ struct activity; enum thread_state { THREAD_SUSPENDED = 0, THREAD_RUNNABLE = 1, THREAD_RUNNING = 2, }; static inline const char * thread_state_string (enum thread_state state) { switch (state) { case THREAD_SUSPENDED: return "suspended"; case THREAD_RUNNABLE: return "runnable"; case THREAD_RUNNING: return "running"; default: panic ("Unknown thread state!"); } } struct thread { /* User accessible fields. */ /* Address space. */ struct vg_cap aspace; /* The current associated activity. (Not the activity out of which this thread's storage is allocated!) */ struct vg_cap activity; /* A capability designating a messenger to which to deliver exceptions. */ struct vg_cap exception_messenger; /* A capability the page that contains the thread's UTCB. */ struct vg_cap utcb; /* Non-user-accessible fields. */ /* Whether the thread data structure has been initialized. */ uint32_t init : 1; /* List of mappings mapped into this thread's hardware address space. */ hurd_btree_vm_thread_mappings_t vm_mappings; struct vg_object_name name; /* The last fault. */ int last_fault_idx; uintptr_t last_fault[4]; uintptr_t last_fault_ip[4]; enum thread_state state; struct list_node run_queue_node; /* The amount of time, in milliseconds, allocated to this thread. */ int time; uint64_t last_payout; uint64_t total_time; #ifdef THREAD_SYSDEP_MEMBERS THREAD_SYSDEP_MEMBERS #endif }; LIST_CLASS(thread_queue, struct thread, run_queue_node, true) /* The hardwired base of the UTCB (2.5GB). */ #define UTCB_AREA_BASE (0xA0000000) /* The size of the UTCB. */ #define UTCB_AREA_SIZE (2 * l4_utcb_area_size ()) /* The hardwired base of the KIP. */ #define KIP_BASE (UTCB_AREA_BASE + UTCB_AREA_SIZE) /* Bootstrap the thread subsystem. */ extern void thread_bootstrap (void); /* Create a new thread. Uses the object THREAD to store the thread information. */ extern void thread_init (struct thread *thread); /* Destroy the thread object THREAD (and the accompanying thread). */ extern void thread_deinit (struct activity *activity, struct thread *thread); /* Prepare the thread object THREAD to run. (Called after bringing a thread object into core.) */ extern void thread_commission (struct thread *thread); /* Save any state of the thread THREAD and destroy any ephemeral resources. (Called before sending the object to backing store.) */ extern void thread_decommission (struct thread *thread); /* Perform an exregs on thread THREAD. CONTROL, SP, IP, EFLAGS and USER_HANDLER are as per l4_exchange_regs, however, the caller may not set the pager. */ extern error_t thread_exregs (struct activity *principal, struct thread *thread, uintptr_t control, struct vg_cap aspace, uintptr_t flags, struct vg_cap_properties properties, struct vg_cap activity, struct vg_cap utcb, struct vg_cap exception_messenger, uintptr_t *sp, uintptr_t *ip, uintptr_t *eflags, uintptr_t *user_handle); /* Deliver the message carried by messenger MESSENGER to thread thread. If thread is not activated, activate the thread. Returns whether the message was delivered or the messenger was enqueued on the thread. */ extern bool thread_activate (struct activity *activity, struct thread *thread, struct messenger *messenger, bool may_block); /* Send thread THREAD's exception messenger the exception described by MESSAGE. If this would block, silently discards MESSAGE. */ extern void thread_raise_exception (struct activity *activity, struct thread *thread, struct vg_message *message); /* Deliver a pending message, if any and if possible. */ extern void thread_deliver_pending (struct activity *activity, struct thread *thread); /* Given the thread id THREADID, find the associated thread. */ extern struct thread *thread_lookup (vg_thread_id_t threadid); extern void thread_arch_bootstrap (void); /* Initialize the architecture dependent parts of THREAD, a new thread object. */ extern void thread_arch_init (struct thread *thread); /* The dual of thread_arch_init. */ extern void thread_arch_deinit (struct thread *thread); /* Resume executing the current thread. */ extern void thread_resume (void); #endif