00001 #ifndef _LINUX_SCHED_H
00002 #define _LINUX_SCHED_H
00003
00004 #include <asm/param.h>
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
00028
00029 #define CSIGNAL 0x000000ff
00030 #define CLONE_VM 0x00000100
00031 #define CLONE_FS 0x00000200
00032 #define CLONE_FILES 0x00000400
00033 #define CLONE_SIGHAND 0x00000800
00034 #define CLONE_PID 0x00001000
00035 #define CLONE_PTRACE 0x00002000
00036 #define CLONE_VFORK 0x00004000
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 extern unsigned long avenrun[];
00049
00050 #define FSHIFT 11
00051 #define FIXED_1 (1<<FSHIFT)
00052 #define LOAD_FREQ (5*HZ)
00053 #define EXP_1 1884
00054 #define EXP_5 2014
00055 #define EXP_15 2037
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
00086
00087 #define SCHED_OTHER 0
00088 #define SCHED_FIFO 1
00089 #define SCHED_RR 2
00090
00091
00092
00093
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
00107
00108
00109
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
00130
00131
00132 #define NR_OPEN_DEFAULT BITS_PER_LONG
00133
00134
00135
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;
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
00176 #define MAX_MAP_COUNT (65536)
00177
00178
00179 #define AVL_MIN_MAP_COUNT 32
00180
00181 struct mm_struct {
00182 struct vm_area_struct *mmap;
00183 struct vm_area_struct *mmap_avl;
00184 struct vm_area_struct *mmap_cache;
00185 pgd_t * pgd;
00186 atomic_t count;
00187 int map_count;
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;
00201 unsigned long swap_address;
00202
00203
00204
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
00241
00242
00243
00244 struct user_struct;
00245
00246 struct task_struct {
00247
00248 volatile long state;
00249 unsigned long flags;
00250 int sigpending;
00251 mm_segment_t addr_limit;
00252
00253
00254
00255 struct exec_domain *exec_domain;
00256 long need_resched;
00257 unsigned long ptrace;
00258
00259
00260 long counter;
00261 long priority;
00262 cycles_t avg_slice;
00263
00264 int has_cpu;
00265 int processor;
00266 int last_processor;
00267 int lock_depth;
00268 struct task_struct *next_task, *prev_task;
00269 struct task_struct *next_run, *prev_run;
00270
00271 unsigned int task_exclusive;
00272
00273 struct linux_binfmt *binfmt;
00274 int exit_code, exit_signal;
00275 int pdeath_signal;
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
00285 int leader;
00286
00287
00288
00289
00290
00291 struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
00292
00293
00294 struct task_struct *pidhash_next;
00295 struct task_struct **pidhash_pprev;
00296
00297
00298 struct task_struct **tarray_ptr;
00299
00300 struct wait_queue *wait_chldexit;
00301 struct semaphore *vfork_sem;
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
00310 unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
00311 int swappable:1;
00312
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
00321 struct rlimit rlim[RLIM_NLIMITS];
00322 unsigned short used_math;
00323 char comm[16];
00324
00325 int link_count;
00326 struct tty_struct *tty;
00327
00328 struct sem_undo *semundo;
00329 struct sem_queue *semsleeping;
00330
00331 struct thread_struct tss;
00332
00333 struct fs_struct *fs;
00334
00335 struct files_struct *files;
00336
00337 struct mm_struct *mm;
00338 struct list_head local_pages;
00339 int allocation_order, nr_local_pages;
00340 int fs_locks;
00341
00342
00343 spinlock_t sigmask_lock;
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
00351 u32 parent_exec_id;
00352 u32 self_exec_id;
00353
00354
00355 int oom_kill_try;
00356 };
00357
00358
00359
00360
00361 #define PF_ALIGNWARN 0x00000001
00362
00363 #define PF_STARTING 0x00000002
00364 #define PF_EXITING 0x00000004
00365 #define PF_FORKNOEXEC 0x00000040
00366 #define PF_SUPERPRIV 0x00000100
00367 #define PF_DUMPCORE 0x00000200
00368 #define PF_SIGNALED 0x00000400
00369 #define PF_MEMALLOC 0x00000800
00370 #define PF_VFORK 0x00001000
00371 #define PF_FREE_PAGES 0x00002000
00372
00373 #define PF_USEDFPU 0x00100000
00374
00375
00376
00377
00378 #define PT_PTRACED 0x00000001
00379 #define PT_TRACESYS 0x00000002
00380 #define PT_DTRACE 0x00000004
00381
00382
00383
00384
00385
00386
00387 #define _STK_LIM (8*1024*1024)
00388
00389 #define DEF_PRIORITY (20*HZ/100)
00390
00391
00392
00393
00394
00395 #define INIT_TASK \
00396 { 0,0,0,KERNEL_DS,&default_exec_domain,0,0, \
00397 DEF_PRIORITY,DEF_PRIORITY,0, \
00398 0,0,0,-1, \
00399 &init_task,&init_task, &init_task, &init_task, \
00400 0, \
00401 NULL, \
00402 0,0,0,0,0,0, \
00403 0,0,0,0,0, \
00404 &init_task,&init_task,NULL,NULL,NULL, \
00405 NULL, NULL, \
00406 &task[0], \
00407 NULL, NULL, \
00408 SCHED_OTHER,0,0,0,0,0,0,0, \
00409 { NULL, NULL, 0, 0, it_real_fn }, \
00410 {0,0,0,0},0, \
00411 {0, }, {0, }, \
00412 0,0,0,0,0,0, \
00413 0, \
00414 \
00415 0,0,0,0,0,0,0,0, \
00416 0, {0,}, \
00417 CAP_INIT_EFF_SET,CAP_INIT_INH_SET,CAP_FULL_SET, \
00418 0, \
00419 NULL, \
00420 INIT_RLIMITS, \
00421 0, \
00422 "swapper", \
00423 0,NULL, \
00424 NULL, NULL, \
00425 INIT_TSS, \
00426 &init_fs, \
00427 &init_files, \
00428 &init_mm, { &init_task.local_pages, &init_task.local_pages}, 0, 0, 0, \
00429 SPIN_LOCK_UNLOCKED, &init_signals, {{0}}, {{0}}, NULL, &init_task.sigqueue, 0, 0, \
00430 0,0, \
00431 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
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
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
00572
00573
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
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
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
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
00657
00658
00659
00660
00661 extern inline int capable(int cap)
00662 {
00663 #if 1
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
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
00685 extern void mm_release(void);
00686
00687
00688
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
00699
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
00742
00743
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
00863
00864 #endif