Skip to content

Linux:Kernel:Process

thread_info

참고로 arch/x86/include/asm/thread_info.h에 있는 thread_info구조체는 아래와 같이 정의되어 있다. 1

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
        unsigned int            sig_on_uaccess_error:1;
        unsigned int            uaccess_err:1;  /* uaccess failed */
};

Loop all task

전체 태스트 리스트를 열거하는 매크로 샘플은 아래와 같다.

#include <linux/kthread.h>
// ...
struct task_struct * task;
for_each_process(task) {
    printk("%s[%d]\n", task->comm, task->pid);
}

Kernel thread example

/**
 * @file   main.c
 * @brief  Create kernel trhead.
 * @author user
 * @date   2015-03-06
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/kthread.h>

#define _INIT_MESSAGE "Driver m03 init.\n"
#define _EXIT_MESSAGE "Driver m03 exit.\n"

struct task_struct * g_th_id = NULL;

static int test_kthread_entry(void * arg)
{
    int count = 0;

    printk(KERN_ALERT "@ %s() : called\n", __FUNCTION__);

    while (!kthread_should_stop()) {
        printk(KERN_ALERT "@ %s() : loop %d\n", __FUNCTION__, count);
        ssleep(1); 
        count++;
    }

    printk(KERN_ALERT "Virtual Runtime: %llu", g_th_id->se.vruntime);
    printk(KERN_ALERT "@ %s() : kthread_should_stop() called. Bye.\n", __FUNCTION__);

    return 0;
}

int __init init_test_module(void)
{
    printk(KERN_ALERT _INIT_MESSAGE);

    if (g_th_id == NULL) { 
        g_th_id = (struct task_struct *) kthread_run(test_kthread_entry
                , NULL, "kthread_test");
    }

    return 0;
}

void __exit exit_test_module(void)
{
    if (g_th_id) {
        kthread_stop(g_th_id);
        g_th_id = NULL;
    }

    printk(KERN_ALERT _EXIT_MESSAGE);
}

module_init(init_test_module);
module_exit(exit_test_module);

MODULE_LICENSE("GPL");

컴파일을 위한 Make파일은 아래와 같다.

## Device Driver build makefile.

KDIR  := $(KERN_DIR)
obj-m := main.o

all:
    @echo build.
    make -C $(KDIR) M=$(PWD) modules

clean:
    @echo clean.
    @rm -rf *.o
    @rm -rf *.ko
    @rm -rf *.mod.*
    @rm -rf .*.cmd
    @rm -rf *.order
    @rm -rf *.symvers
    @rm -rf .tmp_versions/

See also

Favorite site

References


  1. 확인한 커널 코드는 CentOS-3.10.0-123.20.1.el7.x86_64 이다.