프로세스 디스패처

 

 가장 적절한 프로세스에 실행권한을 주기위해, CPU동작을 중단하고 새로운 프로세스를 수행한다.

프로세스 전환(Process Switch, 프로세스 관리(Process Dispatch), Process Dispatcher 라고 한다.

 

 

 static inline void context_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next)
{
    struct mm_struct *mm, *oldmm;

    prepare_task_switch(rq, prev, next);
    trace_sched_switch(rq, prev, next);
    mm = next->mm;
    oldmm = prev->active_mm;
    /*
     * For paravirt, this is coupled with an exit in switch_to to
     * combine the page table reload and the switch backend into
     * one hypercall.
     */

    arch_start_context_switch(prev);

    if (unlikely(!mm)) {
        next->active_mm = oldmm;
        atomic_inc(&oldmm->mm_count);
        enter_lazy_tlb(oldmm, next);
    } else
        switch_mm(oldmm, mm, next);    // 프로세스 공간의 전환처리

    if (unlikely(!prev->mm)) {
        prev->active_mm = NULL;
        rq->prev_mm = oldmm;
    }
    /*
     * Since the runqueue lock will be released by the next
     * task (which is an invalid locking op but in the case
     * of the scheduler it's an obvious special-case), so we
     * do an early lockdep release here:
     */

#ifndef __ARCH_WANT_UNLOCKED_CTXSW
    spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
#endif

    /* Here we just switch the register state and the stack. */
    switch_to(prev, next, prev);         // 각종 레지스터의 전환처리

    barrier();
    /*
     * this_rq must be evaluated again because prev may have moved
     * CPUs since it called schedule(), thus the 'rq' on its stack
     * frame will be invalid.
     */

    finish_task_switch(this_rq(), prev);
}

 

'리눅스커널' 카테고리의 다른 글

systemcall  (0) 2015.04.15
스와퍼(Swapper)프로세스  (0) 2015.04.15
schedule()함수  (0) 2015.04.15
프로세스1-1(프로세스디스크립터, 상태전이)  (0) 2015.04.14
불연속메모리할당  (1) 2015.04.10

프로세스란 무엇인가 ..공부해보자.

 

Process Descriptor : 한 프로세스와 관련된 모든 정보를 담고 있는 task_struct 자료구조?

                             리스트의 각 task task_struct를 프로세스 디스크립터라한다.

 

 ?? 커널은 task_t 데이터 타입을 struct task_struct 와 같은 것으로 정의?

 

   Figure 3.1. The process descriptor and task list.

 

 

 

 

Figure 3.3 Flow chart of process states

 

 

0 :TASK_RUNNIG

1 :TASK_INTERUPTIBLE

2: TASK_UNINTERRUPTIBLE

4: TASK_STOPPED

   - 프로세스 실행 중단.  SIGSTOP  , SIGTSTP, SIGTTIN, SIGTTOU 일 경우

8: TASK_TRACED

16: EXIT_ZOMBIE

  - 프로세스가 종료되었지만 부모프로세스가 wait4() , waitpid() 시스템 콜을 호출하여 종료 프로세스의 정보를 반환하지 않은 경우         -----------보충

32: EXIT_DEAD

  -  보충----------------

64: TASK_DEAD

128 : TASK_WAKEKILL

256 : TASK_WAKING

커널에서는 set_task_state    ,   set_current_state 매크로를 사용하여 프로세스의 상태를 설정

 

같은 그룹에 있는 스레드의 PID 가 같은가?  표준을 위해 리눅스는(Thread Group) 도입. 스레드들이 공유하는 식별자는 스레드 그룹의 리더, 즉 그룹 내 첫 번째 경량 프로세스의PID이며 프로세스 디스크립터의 tgid 필드에 저장된다. getpid() 시스템콜은 pid값 대신 tgid 값을 반환하므로 멀티스레드 애플리케이션의 모든 스레드는 같은 식별자를 공유한다. 대부분의 프로세스는 구성원이 1개인 스레드 그룹에 속하므로 tgid 필드는 pid 필드와 값이 같다..QQ~~.....?????????????????????????????

다시정리하자. 모르겠다.

 

thread_info 구조체(arch/x86/include/asm/thread_info.h)프로세스의 저수준(Low-level) 정보

 104P 이해불가.

 struct thread_info {
    struct task_struct  *task;                   /* main task structure */
    struct exec_domain  *exec_domain;   /* execution domain */
    __u32           flags;                          /* low level flags */
    __u32           status;                       /* thread synchronous flags */
    __u32           cpu;                         /* current CPU */
    int         preempt_count;               /* 0 => preemptable,
                           <0 => BUG */
    mm_segment_t        addr_limit;
    struct restart_block    restart_block;
    void __user     *sysenter_return;
#ifdef CONFIG_X86_32
    unsigned long           previous_esp;   /* ESP of the previous stack in case of nested (IRQ) stacks */       
    __u8            supervisor_stack[0];
#endif
    int         uaccess_err;
};

 

--------------arm-----------

/*
 * low level task data that entry.S needs immediate access to.
 * __switch_to() assumes cpu_context follows immediately after cpu_domain.
 */
struct thread_info {
    unsigned long       flags;             /* low level flags */                           8
    int         preempt_count;              /* 0 => preemptable, <0 => bug */       4
    mm_segment_t        addr_limit;     /* address limit */                            
    struct task_struct  *task;             /* main task structure */                     4
    struct exec_domain  *exec_domain;   /* execution domain */                 4
    __u32           cpu;                           /* cpu */                                     4
    __u32           cpu_domain;               /* cpu domain */                           4
    struct cpu_context_save cpu_context;    /* cpu context */
    __u32           syscall;                          /* syscall number */                  4
    __u8            used_cp[16];                  /* thread used copro */              1
    unsigned long       tp_value;                                                                8
    struct crunch_state crunchstate;              
    union fp_state      fpstate __attribute__((aligned(8)));
    union vfp_state     vfpstate;
#ifdef CONFIG_ARM_THUMBEE
    unsigned long       thumbee_state;  /* ThumbEE Handler Base register */
#endif
    struct restart_block    restart_block;
};

        

http://m.blog.daum.net/english_100/71     참고이해하도록

 

 

 

프로세스 디스크립터 포인터(Process Descriptor Pointer)를 통해 프로세스를 참조한다.

 

참고 : 그림및 내용 http://www.makelinux.net/books/lkd2/ch03lev1sec1

         리눅스 커널의 이해(개정 3판)

         커널 최초의 스택은 어떻게 설정하나요?

         http://forum.falinux.com/zbxe/index.php?document_srl=551428&mid=lecture_tip

 

'리눅스커널' 카테고리의 다른 글

systemcall  (0) 2015.04.15
스와퍼(Swapper)프로세스  (0) 2015.04.15
schedule()함수  (0) 2015.04.15
프로세스1-3  (0) 2015.04.14
불연속메모리할당  (1) 2015.04.10

커널 V. 2.6.32.65

참고 링크

페이지 테이블에 주소 변환 정보가  채워지는 원리  http://www.iamroot.org/xe/Kernel_8_ARM/54103

초보자를 위한 리눅스 커널의 메모리 관리 http://dojeun.egloos.com/317480

 

/linux/vmalloc.h

 27 struct vm_struct {
 28     struct vm_struct    *next;   
 29     void            *addr;
 30     unsigned long       size;
 31     unsigned long       flags;
 32     struct page     **pages;
 33     unsigned int        nr_pages;
 34     unsigned long       phys_addr;
 35     void            *caller;
 36 };

 54 extern void *vmalloc(unsigned long size); 

/usr/src/linux-2.6.32.65/mm/vmalloc.c

 

1630  *  vmalloc  -  allocate virtually contiguous memory
1631  *  @size:      allocation size
1632  *  Allocate enough pages to cover @size from the page level
1633  *  allocator and map them into contiguous kernel virtual space.
1634  *
1635  *  For tight control over page level allocator and protection flags
1636  *  use __vmalloc() instead.
1637  */ 

1638 void *vmalloc(unsigned long size)
1639 { 
1640     return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL,
1641                     -1, __builtin_return_address(0));
1642 }       

1572 /**
1573  *  __vmalloc_node  -  allocate virtually contiguous memory
1574  *  @size:      allocation size
1575  *  @align:     desired alignment
1576  *  @gfp_mask:  flags for the page level allocator
1577  *  @prot:      protection mask for the allocated pages
1578  *  @node:      node to use for allocation or -1
1579  *  @caller:    caller's return address
1580  *
1581  *  Allocate enough pages to cover @size from the page level
1582  *  allocator with @gfp_mask flags.  Map them into contiguous
1583  *  kernel virtual space, using a pagetable protection of @prot.
1584  */

1585 static void *__vmalloc_node(unsigned long size, unsigned long align,
1586                 gfp_t gfp_mask, pgprot_t prot,
1587                 int node, void *caller)
1588 {
1589     struct vm_struct *area;
1590     void *addr;
1591     unsigned long real_size = size;
1592
1593     size = PAGE_ALIGN(size);
1594     if (!size || (size >> PAGE_SHIFT) > totalram_pages)
1595         return NULL;
1596
1597     area = __get_vm_area_node(size, align, VM_ALLOC | VM_UNLIST,
1598                   VMALLOC_START, VMALLOC_END, node,
1599                   gfp_mask, caller);
1600
1601     if (!area)
1602         return NULL;
1603
1604     addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller);
1605
1606     /*
1607      * In this function, newly allocated vm_struct is not added
1608      * to vmlist at __get_vm_area_node(). so, it is added here.
1609      */
1610     insert_vmalloc_vmlist(area);
1611
1612     /*
1613      * A ref_count = 3 is needed because the vm_struct and vmap_area
1614      * structures allocated in the __get_vm_area_node() function contain
1615      * references to the virtual address of the vmalloc'ed block.
1616      */
1617     kmemleak_alloc(addr, real_size, 3, gfp_mask);
1618
1619     return addr;
1620 }

세그먼트 페이지

http://snowwiki.fuzewire.com/wiki/applied_sciences/computer_science/infor_science/read.html?psno=*D30ACDF27AEAFC44D3AF426EF24F0DA54E784B89

 

'리눅스커널' 카테고리의 다른 글

systemcall  (0) 2015.04.15
스와퍼(Swapper)프로세스  (0) 2015.04.15
schedule()함수  (0) 2015.04.15
프로세스1-3  (0) 2015.04.14
프로세스1-1(프로세스디스크립터, 상태전이)  (0) 2015.04.14

+ Recent posts