linux-old/include/linux/sched.h
<<
>>
Prefs
   1#ifndef _LINUX_SCHED_H
   2#define _LINUX_SCHED_H
   3
   4#include <asm/param.h>  /* for HZ */
   5
   6extern unsigned long event;
   7
   8#include <linux/config.h>
   9#include <linux/binfmts.h>
  10#include <linux/threads.h>
  11#include <linux/kernel.h>
  12#include <linux/types.h>
  13#include <linux/times.h>
  14#include <linux/timex.h>
  15#include <linux/rbtree.h>
  16
  17#include <asm/system.h>
  18#include <asm/semaphore.h>
  19#include <asm/page.h>
  20#include <asm/ptrace.h>
  21#include <asm/mmu.h>
  22
  23#include <linux/smp.h>
  24#include <linux/tty.h>
  25#include <linux/sem.h>
  26#include <linux/signal.h>
  27#include <linux/securebits.h>
  28#include <linux/fs_struct.h>
  29
  30struct exec_domain;
  31
  32/*
  33 * cloning flags:
  34 */
  35#define CSIGNAL         0x000000ff      /* signal mask to be sent at exit */
  36#define CLONE_VM        0x00000100      /* set if VM shared between processes */
  37#define CLONE_FS        0x00000200      /* set if fs info shared between processes */
  38#define CLONE_FILES     0x00000400      /* set if open files shared between processes */
  39#define CLONE_SIGHAND   0x00000800      /* set if signal handlers and blocked signals shared */
  40#define CLONE_PID       0x00001000      /* set if pid shared */
  41#define CLONE_PTRACE    0x00002000      /* set if we want to let tracing continue on the child too */
  42#define CLONE_VFORK     0x00004000      /* set if the parent wants the child to wake it up on mm_release */
  43#define CLONE_PARENT    0x00008000      /* set if we want to have the same parent as the cloner */
  44#define CLONE_THREAD    0x00010000      /* Same thread group? */
  45
  46#define CLONE_SIGNAL    (CLONE_SIGHAND | CLONE_THREAD)
  47
  48/*
  49 * These are the constant used to fake the fixed-point load-average
  50 * counting. Some notes:
  51 *  - 11 bit fractions expand to 22 bits by the multiplies: this gives
  52 *    a load-average precision of 10 bits integer + 11 bits fractional
  53 *  - if you want to count load-averages more often, you need more
  54 *    precision, or rounding will get you. With 2-second counting freq,
  55 *    the EXP_n values would be 1981, 2034 and 2043 if still using only
  56 *    11 bit fractions.
  57 */
  58extern unsigned long avenrun[];         /* Load averages */
  59
  60#define FSHIFT          11              /* nr of bits of precision */
  61#define FIXED_1         (1<<FSHIFT)     /* 1.0 as fixed-point */
  62#define LOAD_FREQ       (5*HZ)          /* 5 sec intervals */
  63#define EXP_1           1884            /* 1/exp(5sec/1min) as fixed-point */
  64#define EXP_5           2014            /* 1/exp(5sec/5min) */
  65#define EXP_15          2037            /* 1/exp(5sec/15min) */
  66
  67#define CALC_LOAD(load,exp,n) \
  68        load *= exp; \
  69        load += n*(FIXED_1-exp); \
  70        load >>= FSHIFT;
  71
  72#define CT_TO_SECS(x)   ((x) / HZ)
  73#define CT_TO_USECS(x)  (((x) % HZ) * 1000000/HZ)
  74
  75extern int nr_running, nr_threads;
  76extern int last_pid;
  77
  78#include <linux/fs.h>
  79#include <linux/time.h>
  80#include <linux/param.h>
  81#include <linux/resource.h>
  82#include <linux/timer.h>
  83
  84#include <asm/processor.h>
  85
  86#define TASK_RUNNING            0
  87#define TASK_INTERRUPTIBLE      1
  88#define TASK_UNINTERRUPTIBLE    2
  89#define TASK_ZOMBIE             4
  90#define TASK_STOPPED            8
  91
  92#define __set_task_state(tsk, state_value)              \
  93        do { (tsk)->state = (state_value); } while (0)
  94#ifdef CONFIG_SMP
  95#define set_task_state(tsk, state_value)                \
  96        set_mb((tsk)->state, (state_value))
  97#else
  98#define set_task_state(tsk, state_value)                \
  99        __set_task_state((tsk), (state_value))
 100#endif
 101
 102#define __set_current_state(state_value)                        \
 103        do { current->state = (state_value); } while (0)
 104#ifdef CONFIG_SMP
 105#define set_current_state(state_value)          \
 106        set_mb(current->state, (state_value))
 107#else
 108#define set_current_state(state_value)          \
 109        __set_current_state(state_value)
 110#endif
 111
 112/*
 113 * Scheduling policies
 114 */
 115#define SCHED_OTHER             0
 116#define SCHED_FIFO              1
 117#define SCHED_RR                2
 118
 119/*
 120 * This is an additional bit set when we want to
 121 * yield the CPU for one re-schedule..
 122 */
 123#define SCHED_YIELD             0x10
 124
 125struct sched_param {
 126        int sched_priority;
 127};
 128
 129struct completion;
 130
 131#ifdef __KERNEL__
 132
 133#include <linux/spinlock.h>
 134
 135/*
 136 * This serializes "schedule()" and also protects
 137 * the run-queue from deletions/modifications (but
 138 * _adding_ to the beginning of the run-queue has
 139 * a separate lock).
 140 */
 141extern rwlock_t tasklist_lock;
 142extern spinlock_t runqueue_lock;
 143extern spinlock_t mmlist_lock;
 144
 145extern void sched_init(void);
 146extern void init_idle(void);
 147extern void show_state(void);
 148extern void cpu_init (void);
 149extern void trap_init(void);
 150extern void update_process_times(int user);
 151extern void update_one_process(struct task_struct *p, unsigned long user,
 152                               unsigned long system, int cpu);
 153
 154#define MAX_SCHEDULE_TIMEOUT    LONG_MAX
 155extern signed long FASTCALL(schedule_timeout(signed long timeout));
 156asmlinkage void schedule(void);
 157
 158extern int schedule_task(struct tq_struct *task);
 159extern void flush_scheduled_tasks(void);
 160extern int start_context_thread(void);
 161extern int current_is_keventd(void);
 162
 163/*
 164 * The default fd array needs to be at least BITS_PER_LONG,
 165 * as this is the granularity returned by copy_fdset().
 166 */
 167#define NR_OPEN_DEFAULT BITS_PER_LONG
 168
 169/*
 170 * Open file table structure
 171 */
 172struct files_struct {
 173        atomic_t count;
 174        rwlock_t file_lock;     /* Protects all the below members.  Nests inside tsk->alloc_lock */
 175        int max_fds;
 176        int max_fdset;
 177        int next_fd;
 178        struct file ** fd;      /* current fd array */
 179        fd_set *close_on_exec;
 180        fd_set *open_fds;
 181        fd_set close_on_exec_init;
 182        fd_set open_fds_init;
 183        struct file * fd_array[NR_OPEN_DEFAULT];
 184};
 185
 186#define INIT_FILES \
 187{                                                       \
 188        count:          ATOMIC_INIT(1),                 \
 189        file_lock:      RW_LOCK_UNLOCKED,               \
 190        max_fds:        NR_OPEN_DEFAULT,                \
 191        max_fdset:      __FD_SETSIZE,                   \
 192        next_fd:        0,                              \
 193        fd:             &init_files.fd_array[0],        \
 194        close_on_exec:  &init_files.close_on_exec_init, \
 195        open_fds:       &init_files.open_fds_init,      \
 196        close_on_exec_init: { { 0, } },                 \
 197        open_fds_init:  { { 0, } },                     \
 198        fd_array:       { NULL, }                       \
 199}
 200
 201/* Maximum number of active map areas.. This is a random (large) number */
 202#define MAX_MAP_COUNT   (65536)
 203
 204struct mm_struct {
 205        struct vm_area_struct * mmap;           /* list of VMAs */
 206        rb_root_t mm_rb;
 207        struct vm_area_struct * mmap_cache;     /* last find_vma result */
 208        pgd_t * pgd;
 209        atomic_t mm_users;                      /* How many users with user space? */
 210        atomic_t mm_count;                      /* How many references to "struct mm_struct" (users count as 1) */
 211        int map_count;                          /* number of VMAs */
 212        struct rw_semaphore mmap_sem;
 213        spinlock_t page_table_lock;             /* Protects task page tables and mm->rss */
 214
 215        struct list_head mmlist;                /* List of all active mm's.  These are globally strung
 216                                                 * together off init_mm.mmlist, and are protected
 217                                                 * by mmlist_lock
 218                                                 */
 219
 220        unsigned long start_code, end_code, start_data, end_data;
 221        unsigned long start_brk, brk, start_stack;
 222        unsigned long arg_start, arg_end, env_start, env_end;
 223        unsigned long rss, total_vm, locked_vm;
 224        unsigned long def_flags;
 225        unsigned long cpu_vm_mask;
 226        unsigned long swap_address;
 227
 228        unsigned dumpable:1;
 229
 230        /* Architecture-specific MM context */
 231        mm_context_t context;
 232};
 233
 234extern int mmlist_nr;
 235
 236#define INIT_MM(name) \
 237{                                                       \
 238        mm_rb:          RB_ROOT,                        \
 239        pgd:            swapper_pg_dir,                 \
 240        mm_users:       ATOMIC_INIT(2),                 \
 241        mm_count:       ATOMIC_INIT(1),                 \
 242        mmap_sem:       __RWSEM_INITIALIZER(name.mmap_sem), \
 243        page_table_lock: SPIN_LOCK_UNLOCKED,            \
 244        mmlist:         LIST_HEAD_INIT(name.mmlist),    \
 245}
 246
 247struct signal_struct {
 248        atomic_t                count;
 249        struct k_sigaction      action[_NSIG];
 250        spinlock_t              siglock;
 251};
 252
 253
 254#define INIT_SIGNALS {  \
 255        count:          ATOMIC_INIT(1),                 \
 256        action:         { {{0,}}, },                    \
 257        siglock:        SPIN_LOCK_UNLOCKED              \
 258}
 259
 260/*
 261 * Some day this will be a full-fledged user tracking system..
 262 */
 263struct user_struct {
 264        atomic_t __count;       /* reference count */
 265        atomic_t processes;     /* How many processes does this user have? */
 266        atomic_t files;         /* How many open files does this user have? */
 267
 268        /* Hash table maintenance information */
 269        struct user_struct *next, **pprev;
 270        uid_t uid;
 271};
 272
 273#define get_current_user() ({                           \
 274        struct user_struct *__user = current->user;     \
 275        atomic_inc(&__user->__count);                   \
 276        __user; })
 277
 278extern struct user_struct root_user;
 279#define INIT_USER (&root_user)
 280
 281struct task_struct {
 282        /*
 283         * offsets of these are hardcoded elsewhere - touch with care
 284         */
 285        volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
 286        unsigned long flags;    /* per process flags, defined below */
 287        int sigpending;
 288        mm_segment_t addr_limit;        /* thread address space:
 289                                                0-0xBFFFFFFF for user-thead
 290                                                0-0xFFFFFFFF for kernel-thread
 291                                         */
 292        struct exec_domain *exec_domain;
 293        volatile long need_resched;
 294        unsigned long ptrace;
 295
 296        int lock_depth;         /* Lock depth */
 297
 298/*
 299 * offset 32 begins here on 32-bit platforms. We keep
 300 * all fields in a single cacheline that are needed for
 301 * the goodness() loop in schedule().
 302 */
 303        long counter;
 304        long nice;
 305        unsigned long policy;
 306        struct mm_struct *mm;
 307        int processor;
 308        /*
 309         * cpus_runnable is ~0 if the process is not running on any
 310         * CPU. It's (1 << cpu) if it's running on a CPU. This mask
 311         * is updated under the runqueue lock.
 312         *
 313         * To determine whether a process might run on a CPU, this
 314         * mask is AND-ed with cpus_allowed.
 315         */
 316        unsigned long cpus_runnable, cpus_allowed;
 317        /*
 318         * (only the 'next' pointer fits into the cacheline, but
 319         * that's just fine.)
 320         */
 321        struct list_head run_list;
 322        unsigned long sleep_time;
 323
 324        struct task_struct *next_task, *prev_task;
 325        struct mm_struct *active_mm;
 326        struct list_head local_pages;
 327        unsigned int allocation_order, nr_local_pages;
 328
 329/* task state */
 330        struct linux_binfmt *binfmt;
 331        int exit_code, exit_signal;
 332        int pdeath_signal;  /*  The signal sent when the parent dies  */
 333        /* ??? */
 334        unsigned long personality;
 335        int did_exec:1;
 336        pid_t pid;
 337        pid_t pgrp;
 338        pid_t tty_old_pgrp;
 339        pid_t session;
 340        pid_t tgid;
 341        /* boolean value for session group leader */
 342        int leader;
 343        /* 
 344         * pointers to (original) parent process, youngest child, younger sibling,
 345         * older sibling, respectively.  (p->father can be replaced with 
 346         * p->p_pptr->pid)
 347         */
 348        struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
 349        struct list_head thread_group;
 350
 351        /* PID hash table linkage. */
 352        struct task_struct *pidhash_next;
 353        struct task_struct **pidhash_pprev;
 354
 355        wait_queue_head_t wait_chldexit;        /* for wait4() */
 356        struct completion *vfork_done;          /* for vfork() */
 357        unsigned long rt_priority;
 358        unsigned long it_real_value, it_prof_value, it_virt_value;
 359        unsigned long it_real_incr, it_prof_incr, it_virt_incr;
 360        struct timer_list real_timer;
 361        struct tms times;
 362        unsigned long start_time;
 363        long per_cpu_utime[NR_CPUS], per_cpu_stime[NR_CPUS];
 364/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 365        unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
 366        int swappable:1;
 367/* process credentials */
 368        uid_t uid,euid,suid,fsuid;
 369        gid_t gid,egid,sgid,fsgid;
 370        int ngroups;
 371        gid_t   groups[NGROUPS];
 372        kernel_cap_t   cap_effective, cap_inheritable, cap_permitted;
 373        int keep_capabilities:1;
 374        struct user_struct *user;
 375/* limits */
 376        struct rlimit rlim[RLIM_NLIMITS];
 377        unsigned short used_math;
 378        char comm[16];
 379/* file system info */
 380        int link_count, total_link_count;
 381        struct tty_struct *tty; /* NULL if no tty */
 382        unsigned int locks; /* How many file locks are being held */
 383/* ipc stuff */
 384        struct sem_undo *semundo;
 385        struct sem_queue *semsleeping;
 386/* CPU-specific state of this task */
 387        struct thread_struct thread;
 388/* filesystem information */
 389        struct fs_struct *fs;
 390/* open file information */
 391        struct files_struct *files;
 392/* signal handlers */
 393        spinlock_t sigmask_lock;        /* Protects signal and blocked */
 394        struct signal_struct *sig;
 395
 396        sigset_t blocked;
 397        struct sigpending pending;
 398
 399        unsigned long sas_ss_sp;
 400        size_t sas_ss_size;
 401        int (*notifier)(void *priv);
 402        void *notifier_data;
 403        sigset_t *notifier_mask;
 404        
 405/* Thread group tracking */
 406        u32 parent_exec_id;
 407        u32 self_exec_id;
 408/* Protection of (de-)allocation: mm, files, fs, tty */
 409        spinlock_t alloc_lock;
 410
 411/* journalling filesystem info */
 412        void *journal_info;
 413};
 414
 415/*
 416 * Per process flags
 417 */
 418#define PF_ALIGNWARN    0x00000001      /* Print alignment warning msgs */
 419                                        /* Not implemented yet, only for 486*/
 420#define PF_STARTING     0x00000002      /* being created */
 421#define PF_EXITING      0x00000004      /* getting shut down */
 422#define PF_FORKNOEXEC   0x00000040      /* forked but didn't exec */
 423#define PF_SUPERPRIV    0x00000100      /* used super-user privileges */
 424#define PF_DUMPCORE     0x00000200      /* dumped core */
 425#define PF_SIGNALED     0x00000400      /* killed by a signal */
 426#define PF_MEMALLOC     0x00000800      /* Allocating memory */
 427#define PF_MEMDIE       0x00001000      /* Killed for out-of-memory */
 428#define PF_FREE_PAGES   0x00002000      /* per process page freeing */
 429#define PF_NOIO         0x00004000      /* avoid generating further I/O */
 430
 431#define PF_USEDFPU      0x00100000      /* task used FPU this quantum (SMP) */
 432
 433/*
 434 * Ptrace flags
 435 */
 436
 437#define PT_PTRACED      0x00000001
 438#define PT_TRACESYS     0x00000002
 439#define PT_DTRACE       0x00000004      /* delayed trace (used on m68k, i386) */
 440#define PT_TRACESYSGOOD 0x00000008
 441#define PT_PTRACE_CAP   0x00000010      /* ptracer can follow suid-exec */
 442
 443/*
 444 * Limit the stack by to some sane default: root can always
 445 * increase this limit if needed..  8MB seems reasonable.
 446 */
 447#define _STK_LIM        (8*1024*1024)
 448
 449#define DEF_COUNTER     (10*HZ/100)     /* 100 ms time slice */
 450#define MAX_COUNTER     (20*HZ/100)
 451#define DEF_NICE        (0)
 452
 453
 454/*
 455 * The default (Linux) execution domain.
 456 */
 457extern struct exec_domain       default_exec_domain;
 458
 459/*
 460 *  INIT_TASK is used to set up the first task table, touch at
 461 * your own risk!. Base=0, limit=0x1fffff (=2MB)
 462 */
 463#define INIT_TASK(tsk)  \
 464{                                                                       \
 465    state:              0,                                              \
 466    flags:              0,                                              \
 467    sigpending:         0,                                              \
 468    addr_limit:         KERNEL_DS,                                      \
 469    exec_domain:        &default_exec_domain,                           \
 470    lock_depth:         -1,                                             \
 471    counter:            DEF_COUNTER,                                    \
 472    nice:               DEF_NICE,                                       \
 473    policy:             SCHED_OTHER,                                    \
 474    mm:                 NULL,                                           \
 475    active_mm:          &init_mm,                                       \
 476    cpus_runnable:      -1,                                             \
 477    cpus_allowed:       -1,                                             \
 478    run_list:           LIST_HEAD_INIT(tsk.run_list),                   \
 479    next_task:          &tsk,                                           \
 480    prev_task:          &tsk,                                           \
 481    p_opptr:            &tsk,                                           \
 482    p_pptr:             &tsk,                                           \
 483    thread_group:       LIST_HEAD_INIT(tsk.thread_group),               \
 484    wait_chldexit:      __WAIT_QUEUE_HEAD_INITIALIZER(tsk.wait_chldexit),\
 485    real_timer:         {                                               \
 486        function:               it_real_fn                              \
 487    },                                                                  \
 488    cap_effective:      CAP_INIT_EFF_SET,                               \
 489    cap_inheritable:    CAP_INIT_INH_SET,                               \
 490    cap_permitted:      CAP_FULL_SET,                                   \
 491    keep_capabilities:  0,                                              \
 492    rlim:               INIT_RLIMITS,                                   \
 493    user:               INIT_USER,                                      \
 494    comm:               "swapper",                                      \
 495    thread:             INIT_THREAD,                                    \
 496    fs:                 &init_fs,                                       \
 497    files:              &init_files,                                    \
 498    sigmask_lock:       SPIN_LOCK_UNLOCKED,                             \
 499    sig:                &init_signals,                                  \
 500    pending:            { NULL, &tsk.pending.head, {{0}}},              \
 501    blocked:            {{0}},                                          \
 502    alloc_lock:         SPIN_LOCK_UNLOCKED,                             \
 503    journal_info:       NULL,                                           \
 504}
 505
 506
 507#ifndef INIT_TASK_SIZE
 508# define INIT_TASK_SIZE 2048*sizeof(long)
 509#endif
 510
 511union task_union {
 512        struct task_struct task;
 513        unsigned long stack[INIT_TASK_SIZE/sizeof(long)];
 514};
 515
 516extern union task_union init_task_union;
 517
 518extern struct   mm_struct init_mm;
 519extern struct task_struct *init_tasks[NR_CPUS];
 520
 521/* PID hashing. (shouldnt this be dynamic?) */
 522#define PIDHASH_SZ (4096 >> 2)
 523extern struct task_struct *pidhash[PIDHASH_SZ];
 524
 525#define pid_hashfn(x)   ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
 526
 527static inline void hash_pid(struct task_struct *p)
 528{
 529        struct task_struct **htable = &pidhash[pid_hashfn(p->pid)];
 530
 531        if((p->pidhash_next = *htable) != NULL)
 532                (*htable)->pidhash_pprev = &p->pidhash_next;
 533        *htable = p;
 534        p->pidhash_pprev = htable;
 535}
 536
 537static inline void unhash_pid(struct task_struct *p)
 538{
 539        if(p->pidhash_next)
 540                p->pidhash_next->pidhash_pprev = p->pidhash_pprev;
 541        *p->pidhash_pprev = p->pidhash_next;
 542}
 543
 544static inline struct task_struct *find_task_by_pid(int pid)
 545{
 546        struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];
 547
 548        for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
 549                ;
 550
 551        return p;
 552}
 553
 554#define task_has_cpu(tsk) ((tsk)->cpus_runnable != ~0UL)
 555
 556static inline void task_set_cpu(struct task_struct *tsk, unsigned int cpu)
 557{
 558        tsk->processor = cpu;
 559        tsk->cpus_runnable = 1UL << cpu;
 560}
 561
 562static inline void task_release_cpu(struct task_struct *tsk)
 563{
 564        tsk->cpus_runnable = ~0UL;
 565}
 566
 567/* per-UID process charging. */
 568extern struct user_struct * alloc_uid(uid_t);
 569extern void free_uid(struct user_struct *);
 570
 571#include <asm/current.h>
 572
 573extern unsigned long volatile jiffies;
 574extern unsigned long itimer_ticks;
 575extern unsigned long itimer_next;
 576extern struct timeval xtime;
 577extern void do_timer(struct pt_regs *);
 578
 579extern unsigned int * prof_buffer;
 580extern unsigned long prof_len;
 581extern unsigned long prof_shift;
 582
 583#define CURRENT_TIME (xtime.tv_sec)
 584
 585extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr));
 586extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr));
 587extern void FASTCALL(sleep_on(wait_queue_head_t *q));
 588extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q,
 589                                      signed long timeout));
 590extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
 591extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
 592                                                    signed long timeout));
 593extern int FASTCALL(wake_up_process(struct task_struct * tsk));
 594
 595#define wake_up(x)                      __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1)
 596#define wake_up_nr(x, nr)               __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)
 597#define wake_up_all(x)                  __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0)
 598#define wake_up_sync(x)                 __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1)
 599#define wake_up_sync_nr(x, nr)          __wake_up_sync((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)
 600#define wake_up_interruptible(x)        __wake_up((x),TASK_INTERRUPTIBLE, 1)
 601#define wake_up_interruptible_nr(x, nr) __wake_up((x),TASK_INTERRUPTIBLE, nr)
 602#define wake_up_interruptible_all(x)    __wake_up((x),TASK_INTERRUPTIBLE, 0)
 603#define wake_up_interruptible_sync(x)   __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
 604#define wake_up_interruptible_sync_nr(x) __wake_up_sync((x),TASK_INTERRUPTIBLE,  nr)
 605asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru);
 606
 607extern int in_group_p(gid_t);
 608extern int in_egroup_p(gid_t);
 609
 610extern void proc_caches_init(void);
 611extern void flush_signals(struct task_struct *);
 612extern void flush_signal_handlers(struct task_struct *);
 613extern int dequeue_signal(sigset_t *, siginfo_t *);
 614extern void block_all_signals(int (*notifier)(void *priv), void *priv,
 615                              sigset_t *mask);
 616extern void unblock_all_signals(void);
 617extern int send_sig_info(int, struct siginfo *, struct task_struct *);
 618extern int force_sig_info(int, struct siginfo *, struct task_struct *);
 619extern int kill_pg_info(int, struct siginfo *, pid_t);
 620extern int kill_sl_info(int, struct siginfo *, pid_t);
 621extern int kill_proc_info(int, struct siginfo *, pid_t);
 622extern void notify_parent(struct task_struct *, int);
 623extern void do_notify_parent(struct task_struct *, int);
 624extern void force_sig(int, struct task_struct *);
 625extern int send_sig(int, struct task_struct *, int);
 626extern int kill_pg(pid_t, int, int);
 627extern int kill_sl(pid_t, int, int);
 628extern int kill_proc(pid_t, int, int);
 629extern int do_sigaction(int, const struct k_sigaction *, struct k_sigaction *);
 630extern int do_sigaltstack(const stack_t *, stack_t *, unsigned long);
 631
 632static inline int signal_pending(struct task_struct *p)
 633{
 634        return (p->sigpending != 0);
 635}
 636
 637/*
 638 * Re-calculate pending state from the set of locally pending
 639 * signals, globally pending signals, and blocked signals.
 640 */
 641static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
 642{
 643        unsigned long ready;
 644        long i;
 645
 646        switch (_NSIG_WORDS) {
 647        default:
 648                for (i = _NSIG_WORDS, ready = 0; --i >= 0 ;)
 649                        ready |= signal->sig[i] &~ blocked->sig[i];
 650                break;
 651
 652        case 4: ready  = signal->sig[3] &~ blocked->sig[3];
 653                ready |= signal->sig[2] &~ blocked->sig[2];
 654                ready |= signal->sig[1] &~ blocked->sig[1];
 655                ready |= signal->sig[0] &~ blocked->sig[0];
 656                break;
 657
 658        case 2: ready  = signal->sig[1] &~ blocked->sig[1];
 659                ready |= signal->sig[0] &~ blocked->sig[0];
 660                break;
 661
 662        case 1: ready  = signal->sig[0] &~ blocked->sig[0];
 663        }
 664        return ready != 0;
 665}
 666
 667/* Reevaluate whether the task has signals pending delivery.
 668   This is required every time the blocked sigset_t changes.
 669   All callers should have t->sigmask_lock.  */
 670
 671static inline void recalc_sigpending(struct task_struct *t)
 672{
 673        t->sigpending = has_pending_signals(&t->pending.signal, &t->blocked);
 674}
 675
 676/* True if we are on the alternate signal stack.  */
 677
 678static inline int on_sig_stack(unsigned long sp)
 679{
 680        return (sp - current->sas_ss_sp < current->sas_ss_size);
 681}
 682
 683static inline int sas_ss_flags(unsigned long sp)
 684{
 685        return (current->sas_ss_size == 0 ? SS_DISABLE
 686                : on_sig_stack(sp) ? SS_ONSTACK : 0);
 687}
 688
 689extern int request_irq(unsigned int,
 690                       void (*handler)(int, void *, struct pt_regs *),
 691                       unsigned long, const char *, void *);
 692extern void free_irq(unsigned int, void *);
 693
 694/*
 695 * This has now become a routine instead of a macro, it sets a flag if
 696 * it returns true (to do BSD-style accounting where the process is flagged
 697 * if it uses root privs). The implication of this is that you should do
 698 * normal permissions checks first, and check suser() last.
 699 *
 700 * [Dec 1997 -- Chris Evans]
 701 * For correctness, the above considerations need to be extended to
 702 * fsuser(). This is done, along with moving fsuser() checks to be
 703 * last.
 704 *
 705 * These will be removed, but in the mean time, when the SECURE_NOROOT 
 706 * flag is set, uids don't grant privilege.
 707 */
 708static inline int suser(void)
 709{
 710        if (!issecure(SECURE_NOROOT) && current->euid == 0) { 
 711                current->flags |= PF_SUPERPRIV;
 712                return 1;
 713        }
 714        return 0;
 715}
 716
 717static inline int fsuser(void)
 718{
 719        if (!issecure(SECURE_NOROOT) && current->fsuid == 0) {
 720                current->flags |= PF_SUPERPRIV;
 721                return 1;
 722        }
 723        return 0;
 724}
 725
 726/*
 727 * capable() checks for a particular capability.  
 728 * New privilege checks should use this interface, rather than suser() or
 729 * fsuser(). See include/linux/capability.h for defined capabilities.
 730 */
 731
 732static inline int capable(int cap)
 733{
 734#if 1 /* ok now */
 735        if (cap_raised(current->cap_effective, cap))
 736#else
 737        if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
 738#endif
 739        {
 740                current->flags |= PF_SUPERPRIV;
 741                return 1;
 742        }
 743        return 0;
 744}
 745
 746/*
 747 * Routines for handling mm_structs
 748 */
 749extern struct mm_struct * mm_alloc(void);
 750
 751extern struct mm_struct * start_lazy_tlb(void);
 752extern void end_lazy_tlb(struct mm_struct *mm);
 753
 754/* mmdrop drops the mm and the page tables */
 755extern inline void FASTCALL(__mmdrop(struct mm_struct *));
 756static inline void mmdrop(struct mm_struct * mm)
 757{
 758        if (atomic_dec_and_test(&mm->mm_count))
 759                __mmdrop(mm);
 760}
 761
 762/* mmput gets rid of the mappings and all user-space */
 763extern void mmput(struct mm_struct *);
 764/* Remove the current tasks stale references to the old mm_struct */
 765extern void mm_release(void);
 766
 767/*
 768 * Routines for handling the fd arrays
 769 */
 770extern struct file ** alloc_fd_array(int);
 771extern int expand_fd_array(struct files_struct *, int nr);
 772extern void free_fd_array(struct file **, int);
 773
 774extern fd_set *alloc_fdset(int);
 775extern int expand_fdset(struct files_struct *, int nr);
 776extern void free_fdset(fd_set *, int);
 777
 778extern int  copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
 779extern void flush_thread(void);
 780extern void exit_thread(void);
 781
 782extern void exit_mm(struct task_struct *);
 783extern void exit_files(struct task_struct *);
 784extern void exit_sighand(struct task_struct *);
 785
 786extern void reparent_to_init(void);
 787extern void daemonize(void);
 788
 789extern int do_execve(char *, char **, char **, struct pt_regs *);
 790extern int do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long);
 791
 792extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
 793extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
 794extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
 795
 796#define __wait_event(wq, condition)                                     \
 797do {                                                                    \
 798        wait_queue_t __wait;                                            \
 799        init_waitqueue_entry(&__wait, current);                         \
 800                                                                        \
 801        add_wait_queue(&wq, &__wait);                                   \
 802        for (;;) {                                                      \
 803                set_current_state(TASK_UNINTERRUPTIBLE);                \
 804                if (condition)                                          \
 805                        break;                                          \
 806                schedule();                                             \
 807        }                                                               \
 808        current->state = TASK_RUNNING;                                  \
 809        remove_wait_queue(&wq, &__wait);                                \
 810} while (0)
 811
 812#define wait_event(wq, condition)                                       \
 813do {                                                                    \
 814        if (condition)                                                  \
 815                break;                                                  \
 816        __wait_event(wq, condition);                                    \
 817} while (0)
 818
 819#define __wait_event_interruptible(wq, condition, ret)                  \
 820do {                                                                    \
 821        wait_queue_t __wait;                                            \
 822        init_waitqueue_entry(&__wait, current);                         \
 823                                                                        \
 824        add_wait_queue(&wq, &__wait);                                   \
 825        for (;;) {                                                      \
 826                set_current_state(TASK_INTERRUPTIBLE);                  \
 827                if (condition)                                          \
 828                        break;                                          \
 829                if (!signal_pending(current)) {                         \
 830                        schedule();                                     \
 831                        continue;                                       \
 832                }                                                       \
 833                ret = -ERESTARTSYS;                                     \
 834                break;                                                  \
 835        }                                                               \
 836        current->state = TASK_RUNNING;                                  \
 837        remove_wait_queue(&wq, &__wait);                                \
 838} while (0)
 839        
 840#define wait_event_interruptible(wq, condition)                         \
 841({                                                                      \
 842        int __ret = 0;                                                  \
 843        if (!(condition))                                               \
 844                __wait_event_interruptible(wq, condition, __ret);       \
 845        __ret;                                                          \
 846})
 847
 848#define REMOVE_LINKS(p) do { \
 849        (p)->next_task->prev_task = (p)->prev_task; \
 850        (p)->prev_task->next_task = (p)->next_task; \
 851        if ((p)->p_osptr) \
 852                (p)->p_osptr->p_ysptr = (p)->p_ysptr; \
 853        if ((p)->p_ysptr) \
 854                (p)->p_ysptr->p_osptr = (p)->p_osptr; \
 855        else \
 856                (p)->p_pptr->p_cptr = (p)->p_osptr; \
 857        } while (0)
 858
 859#define SET_LINKS(p) do { \
 860        (p)->next_task = &init_task; \
 861        (p)->prev_task = init_task.prev_task; \
 862        init_task.prev_task->next_task = (p); \
 863        init_task.prev_task = (p); \
 864        (p)->p_ysptr = NULL; \
 865        if (((p)->p_osptr = (p)->p_pptr->p_cptr) != NULL) \
 866                (p)->p_osptr->p_ysptr = p; \
 867        (p)->p_pptr->p_cptr = p; \
 868        } while (0)
 869
 870#define for_each_task(p) \
 871        for (p = &init_task ; (p = p->next_task) != &init_task ; )
 872
 873#define next_thread(p) \
 874        list_entry((p)->thread_group.next, struct task_struct, thread_group)
 875
 876static inline void del_from_runqueue(struct task_struct * p)
 877{
 878        nr_running--;
 879        p->sleep_time = jiffies;
 880        list_del(&p->run_list);
 881        p->run_list.next = NULL;
 882}
 883
 884static inline int task_on_runqueue(struct task_struct *p)
 885{
 886        return (p->run_list.next != NULL);
 887}
 888
 889static inline void unhash_process(struct task_struct *p)
 890{
 891        if (task_on_runqueue(p)) BUG();
 892        write_lock_irq(&tasklist_lock);
 893        nr_threads--;
 894        unhash_pid(p);
 895        REMOVE_LINKS(p);
 896        list_del(&p->thread_group);
 897        write_unlock_irq(&tasklist_lock);
 898}
 899
 900/* Protects ->fs, ->files, ->mm, and synchronises with wait4().  Nests inside tasklist_lock */
 901static inline void task_lock(struct task_struct *p)
 902{
 903        spin_lock(&p->alloc_lock);
 904}
 905
 906static inline void task_unlock(struct task_struct *p)
 907{
 908        spin_unlock(&p->alloc_lock);
 909}
 910
 911/* write full pathname into buffer and return start of pathname */
 912static inline char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
 913                                char *buf, int buflen)
 914{
 915        char *res;
 916        struct vfsmount *rootmnt;
 917        struct dentry *root;
 918        read_lock(&current->fs->lock);
 919        rootmnt = mntget(current->fs->rootmnt);
 920        root = dget(current->fs->root);
 921        read_unlock(&current->fs->lock);
 922        spin_lock(&dcache_lock);
 923        res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
 924        spin_unlock(&dcache_lock);
 925        dput(root);
 926        mntput(rootmnt);
 927        return res;
 928}
 929
 930#endif /* __KERNEL__ */
 931
 932#endif
 933
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.