Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

sched.h

Go to the documentation of this file.
00001 #ifndef _LINUX_SCHED_H
00002 #define _LINUX_SCHED_H
00003 
00004 #include <asm/param.h>  /* for HZ */
00005 
00006 extern unsigned long global_event;
00007 
00008 #include <linux/binfmts.h>
00009 #include <linux/personality.h>
00010 #include <linux/tasks.h>
00011 #include <linux/kernel.h>
00012 #include <linux/types.h>
00013 #include <linux/times.h>
00014 #include <linux/timex.h>
00015 
00016 #include <asm/system.h>
00017 #include <asm/semaphore.h>
00018 #include <asm/page.h>
00019 
00020 #include <linux/smp.h>
00021 #include <linux/tty.h>
00022 #include <linux/sem.h>
00023 #include <linux/signal.h>
00024 #include <linux/securebits.h>
00025 
00026 /*
00027  * cloning flags:
00028  */
00029 #define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
00030 #define CLONE_VM        0x00000100      /* set if VM shared between processes */
00031 #define CLONE_FS        0x00000200      /* set if fs info shared between processes */
00032 #define CLONE_FILES     0x00000400      /* set if open files shared between processes */
00033 #define CLONE_SIGHAND   0x00000800      /* set if signal handlers shared */
00034 #define CLONE_PID       0x00001000      /* set if pid shared */
00035 #define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
00036 #define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
00037 
00038 /*
00039  * These are the constant used to fake the fixed-point load-average
00040  * counting. Some notes:
00041  *  - 11 bit fractions expand to 22 bits by the multiplies: this gives
00042  *    a load-average precision of 10 bits integer + 11 bits fractional
00043  *  - if you want to count load-averages more often, you need more
00044  *    precision, or rounding will get you. With 2-second counting freq,
00045  *    the EXP_n values would be 1981, 2034 and 2043 if still using only
00046  *    11 bit fractions.
00047  */
00048 extern unsigned long avenrun[];         /* Load averages */
00049 
00050 #define FSHIFT          11              /* nr of bits of precision */
00051 #define FIXED_1         (1<<FSHIFT)     /* 1.0 as fixed-point */
00052 #define LOAD_FREQ       (5*HZ)          /* 5 sec intervals */
00053 #define EXP_1           1884            /* 1/exp(5sec/1min) as fixed-point */
00054 #define EXP_5           2014            /* 1/exp(5sec/5min) */
00055 #define EXP_15          2037            /* 1/exp(5sec/15min) */
00056 
00057 #define CALC_LOAD(load,exp,n) \
00058         load *= exp; \
00059         load += n*(FIXED_1-exp); \
00060         load >>= FSHIFT;
00061 
00062 #define CT_TO_SECS(x)   ((x) / HZ)
00063 #define CT_TO_USECS(x)  (((x) % HZ) * 1000000/HZ)
00064 
00065 extern int nr_running, nr_tasks;
00066 extern int last_pid;
00067 
00068 #include <linux/fs.h>
00069 #include <linux/time.h>
00070 #include <linux/param.h>
00071 #include <linux/resource.h>
00072 #include <linux/timer.h>
00073 
00074 #include <asm/processor.h>
00075 
00076 #define TASK_RUNNING            0
00077 #define TASK_INTERRUPTIBLE      1
00078 #define TASK_UNINTERRUPTIBLE    2
00079 #define TASK_ZOMBIE             4
00080 #define TASK_STOPPED            8
00081 #define TASK_SWAPPING           16
00082 #define TASK_EXCLUSIVE          32
00083 
00084 /*
00085  * Scheduling policies
00086  */
00087 #define SCHED_OTHER             0
00088 #define SCHED_FIFO              1
00089 #define SCHED_RR                2
00090 
00091 /*
00092  * This is an additional bit set when we want to
00093  * yield the CPU for one re-schedule..
00094  */
00095 #define SCHED_YIELD             0x10
00096 
00097 struct sched_param {
00098         int sched_priority;
00099 };
00100 
00101 #ifdef __KERNEL__
00102 
00103 #include <asm/spinlock.h>
00104 
00105 /*
00106  * This serializes "schedule()" and also protects
00107  * the run-queue from deletions/modifications (but
00108  * _adding_ to the beginning of the run-queue has
00109  * a separate lock).
00110  */
00111 extern rwlock_t tasklist_lock;
00112 extern spinlock_t runqueue_lock;
00113 
00114 extern void sched_init(void);
00115 extern void init_idle(void);
00116 extern void show_state(void);
00117 extern void trap_init(void);
00118 
00119 #define MAX_SCHEDULE_TIMEOUT    LONG_MAX
00120 extern signed long FASTCALL(schedule_timeout(signed long timeout));
00121 asmlinkage void schedule(void);
00122 
00123 extern int schedule_task(struct tq_struct *task);
00124 extern void flush_scheduled_tasks(void);
00125 extern int start_context_thread(void);
00126 extern int current_is_keventd(void);
00127 
00128 /*
00129  * The default fd array needs to be at least BITS_PER_LONG,
00130  * as this is the granularity returned by copy_fdset().
00131  */
00132 #define NR_OPEN_DEFAULT BITS_PER_LONG
00133 
00134 /*
00135  * Open file table structure
00136  */
00137 struct files_struct {
00138         atomic_t count;
00139         int max_fds;
00140         int max_fdset;
00141         int next_fd;
00142         struct file ** fd;      /* current fd array */
00143         fd_set *close_on_exec;
00144         fd_set *open_fds;
00145         fd_set close_on_exec_init;
00146         fd_set open_fds_init;
00147         struct file * fd_array[NR_OPEN_DEFAULT];
00148 };
00149 
00150 #define INIT_FILES { \
00151         ATOMIC_INIT(1), \
00152         NR_OPEN_DEFAULT, \
00153         __FD_SETSIZE, \
00154         0, \
00155         &init_files.fd_array[0], \
00156         &init_files.close_on_exec_init, \
00157         &init_files.open_fds_init, \
00158         { { 0, } }, \
00159         { { 0, } }, \
00160         { NULL, } \
00161 }
00162 
00163 struct fs_struct {
00164         atomic_t count;
00165         int umask;
00166         struct dentry * root, * pwd;
00167 };
00168 
00169 #define INIT_FS { \
00170         ATOMIC_INIT(1), \
00171         0022, \
00172         NULL, NULL \
00173 }
00174 
00175 /* Maximum number of active map areas.. This is a random (large) number */
00176 #define MAX_MAP_COUNT   (65536)
00177 
00178 /* Number of map areas at which the AVL tree is activated. This is arbitrary. */
00179 #define AVL_MIN_MAP_COUNT       32
00180 
00181 struct mm_struct {
00182         struct vm_area_struct *mmap;            /* list of VMAs */
00183         struct vm_area_struct *mmap_avl;        /* tree of VMAs */
00184         struct vm_area_struct *mmap_cache;      /* last find_vma result */
00185         pgd_t * pgd;
00186         atomic_t count;
00187         int map_count;                          /* number of VMAs */
00188         struct semaphore mmap_sem;
00189 #ifdef __alpha__
00190         unsigned long context[NR_CPUS];
00191 #else
00192         unsigned long context;
00193 #endif
00194         unsigned long start_code, end_code, start_data, end_data;
00195         unsigned long start_brk, brk, start_stack;
00196         unsigned long arg_start, arg_end, env_start, env_end;
00197         unsigned long rss, total_vm, locked_vm;
00198         unsigned long def_flags;
00199         unsigned long cpu_vm_mask;
00200         unsigned long swap_cnt; /* number of pages to swap on next pass */
00201         unsigned long swap_address;
00202         /*
00203          * This is an architecture-specific pointer: the portable
00204          * part of Linux does not know about any segments.
00205          */
00206         void * segments;
00207 };
00208 
00209 #ifdef __alpha__
00210 #define CONTEXT_INIT    { 0, }
00211 #else
00212 #define CONTEXT_INIT    0
00213 #endif
00214 
00215 #define INIT_MM {                                       \
00216                 &init_mmap, NULL, NULL,                 \
00217                 swapper_pg_dir,                         \
00218                 ATOMIC_INIT(1), 1,                      \
00219                 MUTEX,                                  \
00220                 CONTEXT_INIT,                           \
00221                 0, 0, 0, 0,                             \
00222                 0, 0, 0,                                \
00223                 0, 0, 0, 0,                             \
00224                 0, 0, 0,                                \
00225                 0, 0, 0, 0, NULL }
00226 
00227 struct signal_struct {
00228         atomic_t                count;
00229         struct k_sigaction      action[_NSIG];
00230         spinlock_t              siglock;
00231 };
00232 
00233 
00234 #define INIT_SIGNALS { \
00235                 ATOMIC_INIT(1), \
00236                 { {{0,}}, }, \
00237                 SPIN_LOCK_UNLOCKED }
00238 
00239 /*
00240  * Some day this will be a full-fledged user tracking system..
00241  * Right now it is only used to track how many processes a
00242  * user has, but it has the potential to track memory usage etc.
00243  */
00244 struct user_struct;
00245 
00246 struct task_struct {
00247 /* these are hardcoded - don't touch */
00248         volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
00249         unsigned long flags;    /* per process flags, defined below */
00250         int sigpending;
00251         mm_segment_t addr_limit;        /* thread address space:
00252                                                 0-0xBFFFFFFF for user-thead
00253                                                 0-0xFFFFFFFF for kernel-thread
00254                                          */
00255         struct exec_domain *exec_domain;
00256         long need_resched;
00257         unsigned long ptrace;
00258 
00259 /* various fields */
00260         long counter;
00261         long priority;
00262         cycles_t avg_slice;
00263 /* SMP and runqueue state */
00264         int has_cpu;
00265         int processor;
00266         int last_processor;
00267         int lock_depth;         /* Lock depth. We can context switch in and out of holding a syscall kernel lock... */  
00268         struct task_struct *next_task, *prev_task;
00269         struct task_struct *next_run,  *prev_run;
00270 
00271         unsigned int task_exclusive;    /* task wants wake-one semantics in __wake_up() */
00272 /* task state */
00273         struct linux_binfmt *binfmt;
00274         int exit_code, exit_signal;
00275         int pdeath_signal;  /*  The signal sent when the parent dies  */
00276         /* ??? */
00277         unsigned long personality;
00278         unsigned int dumpable:1;
00279         int did_exec:1;
00280         pid_t pid;
00281         pid_t pgrp;
00282         pid_t tty_old_pgrp;
00283         pid_t session;
00284         /* boolean value for session group leader */
00285         int leader;
00286         /* 
00287          * pointers to (original) parent process, youngest child, younger sibling,
00288          * older sibling, respectively.  (p->father can be replaced with 
00289          * p->p_pptr->pid)
00290          */
00291         struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
00292 
00293         /* PID hash table linkage. */
00294         struct task_struct *pidhash_next;
00295         struct task_struct **pidhash_pprev;
00296 
00297         /* Pointer to task[] array linkage. */
00298         struct task_struct **tarray_ptr;
00299 
00300         struct wait_queue *wait_chldexit;       /* for wait4() */
00301         struct semaphore *vfork_sem;            /* for vfork() */
00302         unsigned long policy, rt_priority;
00303         unsigned long it_real_value, it_prof_value, it_virt_value;
00304         unsigned long it_real_incr, it_prof_incr, it_virt_incr;
00305         struct timer_list real_timer;
00306         struct tms times;
00307         unsigned long start_time;
00308         long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
00309 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
00310         unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
00311         int swappable:1;
00312 /* process credentials */
00313         uid_t uid,euid,suid,fsuid;
00314         gid_t gid,egid,sgid,fsgid;
00315         int ngroups;
00316         gid_t   groups[NGROUPS];
00317         kernel_cap_t   cap_effective, cap_inheritable, cap_permitted;
00318         int keep_capabilities:1;
00319         struct user_struct *user;
00320 /* limits */
00321         struct rlimit rlim[RLIM_NLIMITS];
00322         unsigned short used_math;
00323         char comm[16];
00324 /* file system info */
00325         int link_count;
00326         struct tty_struct *tty; /* NULL if no tty */
00327 /* ipc stuff */
00328         struct sem_undo *semundo;
00329         struct sem_queue *semsleeping;
00330 /* tss for this task */
00331         struct thread_struct tss;
00332 /* filesystem information */
00333         struct fs_struct *fs;
00334 /* open file information */
00335         struct files_struct *files;
00336 /* memory management info */
00337         struct mm_struct *mm;
00338         struct list_head local_pages;
00339         int allocation_order, nr_local_pages;
00340         int fs_locks;
00341 
00342 /* signal handlers */
00343         spinlock_t sigmask_lock;        /* Protects signal and blocked */
00344         struct signal_struct *sig;
00345         sigset_t signal, blocked;
00346         struct signal_queue *sigqueue, **sigqueue_tail;
00347         unsigned long sas_ss_sp;
00348         size_t sas_ss_size;
00349         
00350 /* Thread group tracking */
00351         u32 parent_exec_id;
00352         u32 self_exec_id;
00353 
00354 /* oom handling */
00355         int oom_kill_try;
00356 };
00357 
00358 /*
00359  * Per process flags
00360  */
00361 #define PF_ALIGNWARN    0x00000001      /* Print alignment warning msgs */
00362                                         /* Not implemented yet, only for 486*/
00363 #define PF_STARTING     0x00000002      /* being created */
00364 #define PF_EXITING      0x00000004      /* getting shut down */
00365 #define PF_FORKNOEXEC   0x00000040      /* forked but didn't exec */
00366 #define PF_SUPERPRIV    0x00000100      /* used super-user privileges */
00367 #define PF_DUMPCORE     0x00000200      /* dumped core */
00368 #define PF_SIGNALED     0x00000400      /* killed by a signal */
00369 #define PF_MEMALLOC     0x00000800      /* Allocating memory */
00370 #define PF_VFORK        0x00001000      /* Wake up parent in mm_release */
00371 #define PF_FREE_PAGES   0x00002000      /* The current-> */
00372 
00373 #define PF_USEDFPU      0x00100000      /* task used FPU this quantum (SMP) */
00374 
00375 /*
00376  * Ptrace flags
00377  */
00378 #define PT_PTRACED      0x00000001      /* set if ptrace (0) has been called */
00379 #define PT_TRACESYS     0x00000002      /* tracing system calls */
00380 #define PT_DTRACE       0x00000004      /* delayed trace (used on m68k, i386) */
00381 
00382 
00383 /*
00384  * Limit the stack by to some sane default: root can always
00385  * increase this limit if needed..  8MB seems reasonable.
00386  */
00387 #define _STK_LIM        (8*1024*1024)
00388 
00389 #define DEF_PRIORITY    (20*HZ/100)     /* 210 ms time slices */
00390 
00391 /*
00392  *  INIT_TASK is used to set up the first task table, touch at
00393  * your own risk!. Base=0, limit=0x1fffff (=2MB)
00394  */
00395 #define INIT_TASK \
00396 /* state etc */ { 0,0,0,KERNEL_DS,&default_exec_domain,0,0, \
00397 /* counter */   DEF_PRIORITY,DEF_PRIORITY,0, \
00398 /* SMP */       0,0,0,-1, \
00399 /* schedlink */ &init_task,&init_task, &init_task, &init_task, \
00400 /* task_exclusive */ 0, \
00401 /* binfmt */    NULL, \
00402 /* ec,brk... */ 0,0,0,0,0,0, \
00403 /* pid etc.. */ 0,0,0,0,0, \
00404 /* proc links*/ &init_task,&init_task,NULL,NULL,NULL, \
00405 /* pidhash */   NULL, NULL, \
00406 /* tarray */    &task[0], \
00407 /* chld wait */ NULL, NULL, \
00408 /* timeout */   SCHED_OTHER,0,0,0,0,0,0,0, \
00409 /* timer */     { NULL, NULL, 0, 0, it_real_fn }, \
00410 /* utime */     {0,0,0,0},0, \
00411 /* per CPU times */ {0, }, {0, }, \
00412 /* flt */       0,0,0,0,0,0, \
00413 /* swp */       0, \
00414 /* process credentials */                                       \
00415 /* uid etc */   0,0,0,0,0,0,0,0,                                \
00416 /* suppl grps*/ 0, {0,},                                        \
00417 /* caps */      CAP_INIT_EFF_SET,CAP_INIT_INH_SET,CAP_FULL_SET, \
00418 /* keep_caps */ 0,                                              \
00419 /* user */      NULL,                                           \
00420 /* rlimits */   INIT_RLIMITS, \
00421 /* math */      0, \
00422 /* comm */      "swapper", \
00423 /* fs info */   0,NULL, \
00424 /* ipc */       NULL, NULL, \
00425 /* tss */       INIT_TSS, \
00426 /* fs */        &init_fs, \
00427 /* files */     &init_files, \
00428 /* mm */        &init_mm, { &init_task.local_pages, &init_task.local_pages}, 0, 0, 0, \
00429 /* signals */   SPIN_LOCK_UNLOCKED, &init_signals, {{0}}, {{0}}, NULL, &init_task.sigqueue, 0, 0, \
00430 /* exec cts */  0,0, \
00431 /* oom */       0, \
00432 }
00433 
00434 union task_union {
00435         struct task_struct task;
00436         unsigned long stack[2048];
00437 };
00438 
00439 extern union task_union init_task_union;
00440 
00441 extern struct   mm_struct init_mm;
00442 extern struct task_struct *task[NR_TASKS];
00443 
00444 extern struct task_struct **tarray_freelist;
00445 extern spinlock_t taskslot_lock;
00446 
00447 extern __inline__ void add_free_taskslot(struct task_struct **t)
00448 {
00449         spin_lock(&taskslot_lock);
00450         *t = (struct task_struct *) tarray_freelist;
00451         tarray_freelist = t;
00452         spin_unlock(&taskslot_lock);
00453 }
00454 
00455 extern __inline__ struct task_struct **get_free_taskslot(void)
00456 {
00457         struct task_struct **tslot;
00458 
00459         spin_lock(&taskslot_lock);
00460         if((tslot = tarray_freelist) != NULL)
00461                 tarray_freelist = (struct task_struct **) *tslot;
00462         spin_unlock(&taskslot_lock);
00463 
00464         return tslot;
00465 }
00466 
00467 /* PID hashing. */
00468 #define PIDHASH_SZ (NR_TASKS >> 2)
00469 extern struct task_struct *pidhash[PIDHASH_SZ];
00470 
00471 #define pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
00472 
00473 extern __inline__ void hash_pid(struct task_struct *p)
00474 {
00475         struct task_struct **htable = &pidhash[pid_hashfn(p->pid)];
00476 
00477         if((p->pidhash_next = *htable) != NULL)
00478                 (*htable)->pidhash_pprev = &p->pidhash_next;
00479         *htable = p;
00480         p->pidhash_pprev = htable;
00481 }
00482 
00483 extern __inline__ void unhash_pid(struct task_struct *p)
00484 {
00485         if(p->pidhash_next)
00486                 p->pidhash_next->pidhash_pprev = p->pidhash_pprev;
00487         *p->pidhash_pprev = p->pidhash_next;
00488 }
00489 
00490 extern __inline__ struct task_struct *find_task_by_pid(int pid)
00491 {
00492         struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];
00493 
00494         for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
00495                 ;
00496 
00497         return p;
00498 }
00499 
00500 /* per-UID process charging. */
00501 extern int alloc_uid(struct task_struct *p);
00502 void free_uid(struct task_struct *p);
00503 
00504 #include <asm/current.h>
00505 
00506 extern unsigned long volatile jiffies;
00507 extern unsigned long itimer_ticks;
00508 extern unsigned long itimer_next;
00509 extern volatile struct timeval xtime;
00510 extern void do_timer(struct pt_regs *);
00511 
00512 extern unsigned int * prof_buffer;
00513 extern unsigned long prof_len;
00514 extern unsigned long prof_shift;
00515 
00516 #define CURRENT_TIME (xtime.tv_sec)
00517 
00518 extern void FASTCALL(__wake_up(struct wait_queue ** p, unsigned int mode));
00519 extern void FASTCALL(sleep_on(struct wait_queue ** p));
00520 extern long FASTCALL(sleep_on_timeout(struct wait_queue ** p,
00521                                       signed long timeout));
00522 extern void FASTCALL(interruptible_sleep_on(struct wait_queue ** p));
00523 extern long FASTCALL(interruptible_sleep_on_timeout(struct wait_queue ** p,
00524                                                     signed long timeout));
00525 extern void FASTCALL(wake_up_process(struct task_struct * tsk));
00526 
00527 #define wake_up(x)                      __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)
00528 #define wake_up_interruptible(x)        __wake_up((x),TASK_INTERRUPTIBLE | TASK_EXCLUSIVE)
00529 
00530 #define __set_task_state(tsk, state_value)      do { (tsk)->state = state_value; } while (0)
00531 #ifdef __SMP__
00532 #define set_task_state(tsk, state_value)        do { __set_task_state(tsk, state_value); mb(); } while (0)
00533 #else
00534 #define set_task_state(tsk, state_value)        __set_task_state(tsk, state_value)
00535 #endif
00536 
00537 #define __set_current_state(state_value)        do { current->state = state_value; } while (0)
00538 #ifdef __SMP__
00539 #define set_current_state(state_value)          do { __set_current_state(state_value); mb(); } while (0)
00540 #else
00541 #define set_current_state(state_value)          __set_current_state(state_value)
00542 #endif
00543 
00544 extern int in_group_p(gid_t grp);
00545 extern int in_egroup_p(gid_t grp);
00546 
00547 extern void flush_signals(struct task_struct *);
00548 extern void flush_signal_handlers(struct task_struct *);
00549 extern int dequeue_signal(sigset_t *block, siginfo_t *);
00550 extern int send_sig_info(int, struct siginfo *info, struct task_struct *);
00551 extern int force_sig_info(int, struct siginfo *info, struct task_struct *);
00552 extern int kill_pg_info(int, struct siginfo *info, pid_t);
00553 extern int kill_sl_info(int, struct siginfo *info, pid_t);
00554 extern int kill_proc_info(int, struct siginfo *info, pid_t);
00555 extern int kill_something_info(int, struct siginfo *info, int);
00556 extern void notify_parent(struct task_struct * tsk, int);
00557 extern void force_sig(int sig, struct task_struct * p);
00558 extern int send_sig(int sig, struct task_struct * p, int priv);
00559 extern int kill_pg(pid_t, int, int);
00560 extern int kill_sl(pid_t, int, int);
00561 extern int kill_proc(pid_t, int, int);
00562 extern int do_sigaction(int sig, const struct k_sigaction *act,
00563                         struct k_sigaction *oact);
00564 extern int do_sigaltstack(const stack_t *ss, stack_t *oss, unsigned long sp);
00565 
00566 extern inline int signal_pending(struct task_struct *p)
00567 {
00568         return (p->sigpending != 0);
00569 }
00570 
00571 /* Reevaluate whether the task has signals pending delivery.
00572    This is required every time the blocked sigset_t changes.
00573    All callers should have t->sigmask_lock.  */
00574 
00575 static inline void recalc_sigpending(struct task_struct *t)
00576 {
00577         unsigned long ready;
00578         long i;
00579 
00580         switch (_NSIG_WORDS) {
00581         default:
00582                 for (i = _NSIG_WORDS, ready = 0; --i >= 0 ;)
00583                         ready |= t->signal.sig[i] &~ t->blocked.sig[i];
00584                 break;
00585 
00586         case 4: ready  = t->signal.sig[3] &~ t->blocked.sig[3];
00587                 ready |= t->signal.sig[2] &~ t->blocked.sig[2];
00588                 ready |= t->signal.sig[1] &~ t->blocked.sig[1];
00589                 ready |= t->signal.sig[0] &~ t->blocked.sig[0];
00590                 break;
00591 
00592         case 2: ready  = t->signal.sig[1] &~ t->blocked.sig[1];
00593                 ready |= t->signal.sig[0] &~ t->blocked.sig[0];
00594                 break;
00595 
00596         case 1: ready  = t->signal.sig[0] &~ t->blocked.sig[0];
00597         }
00598 
00599         t->sigpending = (ready != 0);
00600 }
00601 
00602 /* True if we are on the alternate signal stack.  */
00603 
00604 static inline int on_sig_stack(unsigned long sp)
00605 {
00606         return (sp >= current->sas_ss_sp
00607                 && sp < current->sas_ss_sp + current->sas_ss_size);
00608 }
00609 
00610 static inline int sas_ss_flags(unsigned long sp)
00611 {
00612         return (current->sas_ss_size == 0 ? SS_DISABLE
00613                 : on_sig_stack(sp) ? SS_ONSTACK : 0);
00614 }
00615 
00616 extern int request_irq(unsigned int irq,
00617                        void (*handler)(int, void *, struct pt_regs *),
00618                        unsigned long flags, 
00619                        const char *device,
00620                        void *dev_id);
00621 extern void free_irq(unsigned int irq, void *dev_id);
00622 
00623 /*
00624  * This has now become a routine instead of a macro, it sets a flag if
00625  * it returns true (to do BSD-style accounting where the process is flagged
00626  * if it uses root privs). The implication of this is that you should do
00627  * normal permissions checks first, and check suser() last.
00628  *
00629  * [Dec 1997 -- Chris Evans]
00630  * For correctness, the above considerations need to be extended to
00631  * fsuser(). This is done, along with moving fsuser() checks to be
00632  * last.
00633  *
00634  * These will be removed, but in the mean time, when the SECURE_NOROOT 
00635  * flag is set, uids don't grant privilege.
00636  */
00637 extern inline int suser(void)
00638 {
00639         if (!issecure(SECURE_NOROOT) && current->euid == 0) { 
00640                 current->flags |= PF_SUPERPRIV;
00641                 return 1;
00642         }
00643         return 0;
00644 }
00645 
00646 extern inline int fsuser(void)
00647 {
00648         if (!issecure(SECURE_NOROOT) && current->fsuid == 0) {
00649                 current->flags |= PF_SUPERPRIV;
00650                 return 1;
00651         }
00652         return 0;
00653 }
00654 
00655 /*
00656  * capable() checks for a particular capability.  
00657  * New privilege checks should use this interface, rather than suser() or
00658  * fsuser(). See include/linux/capability.h for defined capabilities.
00659  */
00660 
00661 extern inline int capable(int cap)
00662 {
00663 #if 1 /* ok now */
00664         if (cap_raised(current->cap_effective, cap))
00665 #else
00666         if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
00667 #endif
00668         {
00669                 current->flags |= PF_SUPERPRIV;
00670                 return 1;
00671         }
00672         return 0;
00673 }
00674 
00675 /*
00676  * Routines for handling mm_structs
00677  */
00678 extern struct mm_struct * mm_alloc(void);
00679 static inline void mmget(struct mm_struct * mm)
00680 {
00681         atomic_inc(&mm->count);
00682 }
00683 extern void mmput(struct mm_struct *);
00684 /* Remove the current tasks stale references to the old mm_struct */
00685 extern void mm_release(void);
00686 
00687 /*
00688  * Routines for handling the fd arrays
00689  */
00690 extern struct file ** alloc_fd_array(int);
00691 extern int expand_fd_array(struct files_struct *, int nr);
00692 extern void free_fd_array(struct file **, int);
00693 
00694 extern fd_set *alloc_fdset(int);
00695 extern int expand_fdset(struct files_struct *, int nr);
00696 extern void free_fdset(fd_set *, int);
00697 
00698 /* Expand files.  Return <0 on error; 0 nothing done; 1 files expanded,
00699  * we may have blocked. */
00700 static inline int expand_files(struct files_struct *files, int nr)
00701 {
00702         int err, expand = 0;
00703 #ifdef FDSET_DEBUG      
00704         printk (KERN_ERR __FUNCTION__ " %d: nr = %d\n", current->pid, nr);
00705 #endif
00706         
00707         if (nr >= files->max_fdset) {
00708                 expand = 1;
00709                 if ((err = expand_fdset(files, nr + 1)))
00710                         goto out;
00711         }
00712         if (nr >= files->max_fds) {
00713                 expand = 1;
00714                 if ((err = expand_fd_array(files, nr + 1)))
00715                         goto out;
00716         }
00717         err = expand;
00718  out:
00719 #ifdef FDSET_DEBUG      
00720         if (err)
00721                 printk (KERN_ERR __FUNCTION__ " %d: return %d\n", current->pid, err);
00722 #endif
00723         return err;
00724 }
00725 
00726 extern int  copy_thread(int, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
00727 extern void flush_thread(void);
00728 extern void exit_thread(void);
00729 
00730 extern void exit_mm(struct task_struct *);
00731 extern void exit_fs(struct task_struct *);
00732 extern void exit_files(struct task_struct *);
00733 extern void exit_sighand(struct task_struct *);
00734 
00735 extern void daemonize(void);
00736 
00737 extern int do_execve(char *, char **, char **, struct pt_regs *);
00738 extern int do_fork(unsigned long, unsigned long, struct pt_regs *);
00739 
00740 /*
00741  * The wait-queues are circular lists, and you have to be *very* sure
00742  * to keep them correct. Use only these two functions to add/remove
00743  * entries in the queues.
00744  */
00745 extern inline void __add_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
00746 {
00747         wait->next = *p ? : WAIT_QUEUE_HEAD(p);
00748         *p = wait;
00749 }
00750 
00751 extern rwlock_t waitqueue_lock;
00752 
00753 extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
00754 {
00755         unsigned long flags;
00756 
00757         write_lock_irqsave(&waitqueue_lock, flags);
00758         __add_wait_queue(p, wait);
00759         write_unlock_irqrestore(&waitqueue_lock, flags);
00760 }
00761 
00762 extern inline void __remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
00763 {
00764         struct wait_queue * next = wait->next;
00765         struct wait_queue * head = next;
00766         struct wait_queue * tmp;
00767 
00768         while ((tmp = head->next) != wait) {
00769                 head = tmp;
00770         }
00771         head->next = next;
00772 }
00773 
00774 extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait)
00775 {
00776         unsigned long flags;
00777 
00778         write_lock_irqsave(&waitqueue_lock, flags);
00779         __remove_wait_queue(p, wait);
00780         write_unlock_irqrestore(&waitqueue_lock, flags); 
00781 }
00782 
00783 #define __wait_event(wq, condition)                                     \
00784 do {                                                                    \
00785         struct wait_queue __wait;                                       \
00786                                                                         \
00787         __wait.task = current;                                          \
00788         add_wait_queue(&wq, &__wait);                                   \
00789         for (;;) {                                                      \
00790                 current->state = TASK_UNINTERRUPTIBLE;                  \
00791                 mb();                                                   \
00792                 if (condition)                                          \
00793                         break;                                          \
00794                 schedule();                                             \
00795         }                                                               \
00796         current->state = TASK_RUNNING;                                  \
00797         remove_wait_queue(&wq, &__wait);                                \
00798 } while (0)
00799 
00800 #define wait_event(wq, condition)                                       \
00801 do {                                                                    \
00802         if (condition)                                                  \
00803                 break;                                                  \
00804         __wait_event(wq, condition);                                    \
00805 } while (0)
00806 
00807 #define __wait_event_interruptible(wq, condition, ret)                  \
00808 do {                                                                    \
00809         struct wait_queue __wait;                                       \
00810                                                                         \
00811         __wait.task = current;                                          \
00812         add_wait_queue(&wq, &__wait);                                   \
00813         for (;;) {                                                      \
00814                 current->state = TASK_INTERRUPTIBLE;                    \
00815                 mb();                                                   \
00816                 if (condition)                                          \
00817                         break;                                          \
00818                 if (!signal_pending(current)) {                         \
00819                         schedule();                                     \
00820                         continue;                                       \
00821                 }                                                       \
00822                 ret = -ERESTARTSYS;                                     \
00823                 break;                                                  \
00824         }                                                               \
00825         current->state = TASK_RUNNING;                                  \
00826         remove_wait_queue(&wq, &__wait);                                \
00827 } while (0)
00828         
00829 #define wait_event_interruptible(wq, condition)                         \
00830 ({                                                                      \
00831         int __ret = 0;                                                  \
00832         if (!(condition))                                               \
00833                 __wait_event_interruptible(wq, condition, __ret);       \
00834         __ret;                                                          \
00835 })
00836 
00837 #define REMOVE_LINKS(p) do { \
00838         (p)->next_task->prev_task = (p)->prev_task; \
00839         (p)->prev_task->next_task = (p)->next_task; \
00840         if ((p)->p_osptr) \
00841                 (p)->p_osptr->p_ysptr = (p)->p_ysptr; \
00842         if ((p)->p_ysptr) \
00843                 (p)->p_ysptr->p_osptr = (p)->p_osptr; \
00844         else \
00845                 (p)->p_pptr->p_cptr = (p)->p_osptr; \
00846         } while (0)
00847 
00848 #define SET_LINKS(p) do { \
00849         (p)->next_task = &init_task; \
00850         (p)->prev_task = init_task.prev_task; \
00851         init_task.prev_task->next_task = (p); \
00852         init_task.prev_task = (p); \
00853         (p)->p_ysptr = NULL; \
00854         if (((p)->p_osptr = (p)->p_pptr->p_cptr) != NULL) \
00855                 (p)->p_osptr->p_ysptr = p; \
00856         (p)->p_pptr->p_cptr = p; \
00857         } while (0)
00858 
00859 #define for_each_task(p) \
00860         for (p = &init_task ; (p = p->next_task) != &init_task ; )
00861 
00862 #endif /* __KERNEL__ */
00863 
00864 #endif