/*1* Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 20092* The President and Fellows of Harvard College.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12* 3. Neither the name of the University nor the names of its contributors13* may be used to endorse or promote products derived from this software14* without specific prior written permission.15*16* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#ifndef _THREAD_H_30#define _THREAD_H_3132/*33* Definition of a thread.34*35* Note: curthread is defined by <current.h>.36*/3738#include <spinlock.h>39#include <threadlist.h>40#include <proc.h>4142struct addrspace;43struct cpu;44struct vnode;4546/* get machine-dependent defs */47#include <machine/thread.h>484950/* Size of kernel stacks; must be power of 2 */51#define STACK_SIZE 40965253/* Mask for extracting the stack base address of a kernel stack pointer */54#define STACK_MASK (~(vaddr_t)(STACK_SIZE-1))5556/* Macro to test if two addresses are on the same kernel stack */57#define SAME_STACK(p1, p2) (((p1) & STACK_MASK) == ((p2) & STACK_MASK))585960/* States a thread can be in. */61typedef enum {62S_RUN, /* running */63S_READY, /* ready to run */64S_SLEEP, /* sleeping */65S_ZOMBIE, /* zombie; exited but not yet deleted */66} threadstate_t;6768/* Thread structure. */69struct thread {70/*71* These go up front so they're easy to get to even if the72* debugger is messed up.73*/74char *t_name; /* Name of this thread */75const char *t_wchan_name; /* Name of wait channel, if sleeping */76threadstate_t t_state; /* State this thread is in */7778/*79* Thread subsystem internal fields.80*/81struct thread_machdep t_machdep; /* Any machine-dependent goo */82struct threadlistnode t_listnode; /* Link for run/sleep/zombie lists */83void *t_stack; /* Kernel-level stack */84struct switchframe *t_context; /* Saved register context (on stack) */85struct cpu *t_cpu; /* CPU thread runs on */8687/*88* Interrupt state fields.89*90* t_in_interrupt is true if current execution is in an91* interrupt handler, which means the thread's normal context92* of execution is stopped somewhere in the middle of doing93* something else. This makes assorted operations unsafe.94*95* See notes in spinlock.c regarding t_curspl and t_iplhigh_count.96*97* Exercise for the student: why is this material per-thread98* rather than per-cpu or global?99*/100bool t_in_interrupt; /* Are we in an interrupt? */101int t_curspl; /* Current spl*() state */102int t_iplhigh_count; /* # of times IPL has been raised */103int t_vmp_count; /* # of vmpages locks */104int t_clone;105106/*107* Public fields108*/109110/* VM */111struct addrspace *t_addrspace; /* virtual address space */112113/* VFS */114struct vnode *t_cwd; /* current working directory */115116/* modifications for ASST2 */117struct proc *td_proc; /* process associated with this thread */118};119120/* Call once during system startup to allocate data structures. */121void thread_bootstrap(void);122123/* Call late in system startup to get secondary CPUs running. */124void thread_start_cpus(void);125126/* Call during panic to stop other threads in their tracks */127void thread_panic(void);128129/* Call during system shutdown to offline other CPUs. */130void thread_shutdown(void);131132/*133* Make a new thread, which will start executing at "func". The "data"134* arguments (one pointer, one number) are passed to the function. The135* current thread is used as a prototype for creating the new one. If136* "ret" is non-null, the thread structure for the new thread is137* handed back. (Note that using said thread structure from the parent138* thread should be done only with caution, because in general the139* child thread might exit at any time.) Returns an error code.140*/141int thread_fork(const char *name,142void (*func)(void *, unsigned long),143void *data1, unsigned long data2,144struct thread **ret);145146/*147* Cause the current thread to exit.148* Interrupts need not be disabled.149*/150void thread_exit(void);151152/*153* Cause the current thread to yield to the next runnable thread, but154* itself stay runnable.155* Interrupts need not be disabled.156*/157void thread_yield(void);158159/*160* Reshuffle the run queue. Called from the timer interrupt.161*/162void schedule(void);163164/*165* Potentially migrate ready threads to other CPUs. Called from the166* timer interrupt.167*/168void thread_consider_migration(void);169170171#endif /* _THREAD_H_ */172173174