⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 进程.txt

📁 讲解linux内核 进程调度 部分经典讲义
💻 TXT
📖 第 1 页 / 共 5 页
字号:
continue;
if ((*p)->state == TASK_RUNNING && (*p)->counter > c)
c = (*p)->counter, next = i;
}
if (c) break; @@记数大于零
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p)
if (*p)
(*p)->counter = ((*p)->counter >> 1) +
(*p)->priority;
}
switch_to(next);
}
int sys_pause(void)
{
current->state = TASK_INTERRUPTIBLE; @@任务可中断
schedule();
return 0;
}
void sleep_on(struct task_struct **p)
{
struct task_struct *tmp;
if (!p)
return;
if (current == &(init_task.task))
panic("task[0] trying to sleep");
tmp = *p;
*p = current;
current->state = TASK_UNINTERRUPTIBLE;
schedule();
if (tmp) @@激活p,什么时候回来?唤醒上次睡眠的进程
tmp->state=0;
}
void interruptible_sleep_on(struct task_struct **p)
{
struct task_struct *tmp;
if (!p)
return;
if (current == &(init_task.task))
panic("task[0] trying to sleep");
tmp=*p;
*p=current;
repeat: current->state = TASK_INTERRUPTIBLE;
schedule();
if (*p && *p != current) {
(**p).state=0;
goto repeat;
}
@@好象下不来
*p=NULL;
if (tmp)
tmp->state=0;
}
void wake_up(struct task_struct **p)
{
if (p && *p) {
(**p).state=0; @@唤醒该进程running
*p=NULL; @@睡眠栈为0
}
}
void do_timer(long cpl) @@定时调度
{
if (cpl)
current->utime++; @@用户态时间加一
else
current->stime++; @@系统态时间加一
if ((--current->counter)>0) return; @@当前记数减一
current->counter=0;
if (!cpl) return;
schedule();
}
int sys_alarm(long seconds)
{
current->alarm = (seconds>0)?(jiffies+HZ*seconds):0;
return seconds;
}
int sys_getpid(void)
{
return current->pid;
}
int sys_getppid(void)
{
return current->father;
}
int sys_getuid(void)
{
return current->uid;
}
int sys_geteuid(void)
{
return current->euid;
}
int sys_getgid(void)
{
return current->gid;
}
int sys_getegid(void)
{
return current->egid;
}
int sys_nice(long increment)
{
if (current->priority-increment>0)
current->priority -= increment;
return 0;
}
int sys_signal(long signal,long addr,long restorer)
{
long i;
switch (signal) {
case SIGHUP: case SIGINT: case SIGQUIT: case SIGILL:
case SIGTRAP: case SIGABRT: case SIGFPE: case SIGUSR1:
case SIGSEGV: case SIGUSR2: case SIGPIPE: case SIGALRM:
case SIGCHLD:
i=(long) current->sig_fn[signal-1];
current->sig_fn[signal-1] = (fn_ptr) addr;
current->sig_restorer = (fn_ptr) restorer;
return i;
default: return -1;
}
}
void sched_init(void)
{
int i;
struct desc_struct * p;
set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));@@init task tss
set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));@@init ldt
p = gdt+2+FIRST_TSS_ENTRY;
for(i=1;i task[i] = NULL;
p->a=p->b=0;
p++;
p->a=p->b=0;
p++;
}
ltr(0); @@调入task 0的tss
lldt(0); @@调入task 0的ldt
outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */
outb_p(LATCH & 0xff , 0x40); /* LSB */
outb(LATCH >> 8 , 0x40); /* MSB */
set_intr_gate(0x20,&timer_interrupt); @@irq 0 时钟中断
outb(inb_p(0x21)&~0x01,0x21);
set_system_gate(0x80,&system_call);
}


[目录]




进程信号队列

    
每个进程具有一个sigpending结构所描述的信号队列,它有3个成员,head指向第一个sigqueue成员,tail指向最末的sigqueue成员的next指针,signal描述了此队列中的信号集.
static int
send_signal(int sig, struct siginfo *info, struct sigpending *signals);
将信号sig和对应的消息结构info添加到信号队列signal中.
static int
collect_signal(int sig, struct sigpending *list, siginfo_t *info);
返回信号sig在队列list中的信息info.

struct task_struct {
        ...
        struct sigpending pending;
        ...
};
struct sigpending {
       struct sigqueue *head, **tail;
       sigset_t signal;
};
struct sigqueue {
       struct sigqueue *next;
       siginfo_t info;
       };
// kernel/signal.c
static int
send_signal(int sig, struct siginfo *info, struct sigpending *signals)
{
     struct sigqueue * q = NULL;
     /* Real-time signals must be queued if sent by sigqueue, or
       some other real-time mechanism.  It is implementation
      defined whether kill() does so.  We attempt to do so, on
      the principle of least surprise, but since kill is not
     allowed to fail with EAGAIN when low on memory we just
     make sure at least one signal gets delivered and don't
     pass on the info struct.  */
    if (atomic_read(&nr_queued_signals) < max_queued_signals) {
       q = kmem_cache_alloc(sigqueue_cachep, GFP_ATOMIC);
    }
    // nr_queued_signals和max_queued_signals用来限制全局sigqueue成员的数目
    if (q) {
        atomic_inc(&nr_queued_signals);
        q->next = NULL;
        *signals->tail = q;
        signals->tail = &q->next; tail总是指向最末的信号成员的next指针                switch 
((unsign
ed long) info)
         {
        case 0:
          // info参数如果为0,表示信号来源于当前用户进程                                  
q->info.si_signo =
sig;
            q->info.si_errno = 0;
            q->info.si_code = SI_USER;
          q->info.si_pid = current->pid;
            q->info.si_uid = current->uid;
          break;
        case 1:
          // info参数如果为1,表示信号来源于内核本身                                  
q->info.si_signo = sig;
          q->info.si_errno = 0;
          q->info.si_code = SI_KERNEL;
           q->info.si_pid = 0;
          q->info.si_uid = 0;
           break;
        default:
           // 否则从info指针中拷贝信号
           copy_siginfo(&q->info, info);
          break;
        }
      }
      else if (sig >= SIGRTMIN && info && (unsigned long)info != 1               
    && info->
si_code != SI_USER)
      {
        ; 如果该信号是内核发出的实时信号,就返回错误码
        /*
         * Queue overflow, abort.  We may abort if the signal was rt
         * and sent by user using something other than kill().
       */
        return -EAGAIN;
      }
      sigaddset(&signals->signal, sig); 将sig号标记在队列的信号集上
      return 0;
}
static int
collect_signal(int sig, struct sigpending *list, siginfo_t *info)
{
      if (sigismember(&list->signal, sig)) {
        /* Collect the siginfo appropriate to this signal.  */                
struct sigqueue *q, **
pp;
         pp = &list->head; pp指向第一个信号成员的next指针
        while ((q = *pp) != NULL) {
                if (q->info.si_signo == sig)                                     
       goto found_it;
                pp = &q->next;
         }
        /* Ok, it wasn't in the queue.  We must have
           been out of queue space.  So zero out the
          info.
         */
        sigdelset(&list->signal, sig);
        info->si_signo = sig;
        info->si_errno = 0;
        info->si_code = 0;
        info->si_pid = 0;
        info->si_uid = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -