linux内核源码实战_3.1理解进程管理和内存管理

img

linux内核源码实战_理解进程管理和内存管理

前面的博客我只是对知识点的整理, 没有对知识点进行理解, 准备从实战方面入手去理解进程管理和内存管理。

体验课(Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈)学习视频链接地址 
正课学习视频链接地址
第二个链接是我学习的链接,如果你有兴趣学习,我可以为你推荐,老学员推荐新学员会有相应的折扣 我的QQ号码: 852897652.

以前学习整理的
整理知识点 进程管理和内存管理 链接1
整理知识点 设备驱动和文件系统 链接2
整理知识点 中断和网络 链接3
整理知识点 内核实战 链接3

理解进程管理和内存管理列表

1-内存管理4-获取系统内存数据信息
2-内存管理4-分配内存模式机制
3-内存管理4-Slab块分配器内存实现
4-内存管理4-进程地址空间在内核(VMA实现)
5-内存管理4-设计per-cpu变量应用
第019讲 Linux内核内存池
第008讲 内存映射原理及系统调用
vma

6-同步管理-RCU实现
第004讲 2进程优先级与调度策略实战

理解进程管理和内存管理列表详解

1-内存管理4-获取系统内存数据信息
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>

#define ARCH_PFN_OFFSET (0UL)

#define PRT(a, b) pr_info("%-15s=%10d %10ld %8ld\n", a, b, (PAGE_SIZE * b) / 10                                               24, (PAGE_SIZE * b) / 1024 / 1024)

static int __init my_init(void)
{
    struct page *p;
    unsigned long i, pfn, valid = 0;
    int free = 0, locked = 0, reserved = 0, swapcache = 0,referenced = 0, slab                                                = 0, private = 0, uptodate = 0,dirty = 0, active = 0, writeback = 0, mappedtodi                                               sk = 0;

    unsigned long num_physpages;

    num_physpages = get_num_physpages();
    for (i = 0; i < num_physpages; i++)
    {
        /* Most of ARM systems have ARCH_PFN_OFFSET */
        pfn = i + ARCH_PFN_OFFSET;
        /* may be holes due to remapping */
        if (!pfn_valid(pfn))
            continue;
        valid++;
        p = pfn_to_page(pfn);
        if (!p)
            continue;
        if (!page_count(p))
        {
            free++;
            continue;
        }
        if (PageLocked(p))
            locked++;
        if (PageReserved(p))
            reserved++;
        if (PageSwapCache(p))
            swapcache++;
        if (PageReferenced(p))
            referenced++;
        if (PageSlab(p))
            slab++;
        if (PagePrivate(p))
        private
        ++;
        if (PageUptodate(p))
            uptodate++;
        if (PageDirty(p))
            dirty++;
        if (PageActive(p))
            active++;
        if (PageWriteback(p))
            writeback++;
        if (PageMappedToDisk(p))
            mappedtodisk++;
    }

    pr_info("\nExamining %ld pages (num_phys_pages) = %ld MB\n",num_physpages,                                                num_physpages * PAGE_SIZE / 1024 / 1024);
    pr_info("Pages with valid PFN's=%ld, = %ld MB\n", valid,valid * PAGE_SIZE /                                                1024 / 1024);
    pr_info("\n Pages KB MB\n\n");

    PRT("free", free);
    PRT("locked", locked);
    PRT("reserved", reserved);
    PRT("swapcache", swapcache);
    PRT("referenced", referenced);
    PRT("slab", slab);
    PRT("private", private);
    PRT("uptodate", uptodate);
    PRT("dirty", dirty);
    PRT("active", active);
    PRT("writeback", writeback);
    PRT("mappedtodisk", mappedtodisk);

    return 0;
}

static void __exit my_exit(void)
{
    pr_info("Module exit\n");
}

module_init(my_init);
module_exit(my_exit);

MODULE_AUTHOR("VicoTeacher");
MODULE_LICENSE("GPL");

分析

原理不了解,没法分析,先整理在这里吧 。

2-内存管理4-分配内存模式机制
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/vmalloc.h>

static int mem = 1024;
#define MB (1024 * 1024)

static int __init my_init(void)
{
    char *kbuf;
    unsigned long order;
    unsigned long size;
    char *vm_buff;

    /* try __get_free_pages__ */
    for (size = PAGE_SIZE, order = 0; order < MAX_ORDER; order++, size *= 2)
    {
        pr_info(" order=%2lu, pages=%5lu, size=%8lu ", order,size / PAGE_SIZE, size);
        kbuf = (char *)__get_free_pages(GFP_ATOMIC, order);
        if (!kbuf)
        {
            pr_err("Testing Function:__get_free_pages failed\n");
            break;
        }
        pr_info("test --> __get_free_pages OK\n");
        free_pages((unsigned long)kbuf, order);
    }

    /* try kmalloc */
    pr_info("\n");
    for (size = PAGE_SIZE, order = 0; order < MAX_ORDER;order++, size *= 2)
    {
        pr_info(" order=%2lu, pages=%5lu, size=%8lu ", order,size / PAGE_SIZE, size);
        kbuf = kmalloc((size_t)size, GFP_ATOMIC);
        if (!kbuf)
        {
            pr_err("Testing Function:kmalloc failed\n");
            break;
        }
        pr_info("test --> kmalloc OK\n");
        kfree(kbuf);
    }

    /* try vmalloc */
    pr_info("\n");
    for (size = 20 * MB; size <= mem * MB; size += 20 * MB)
    {
        pr_info(" pages=%6lu, size=%8lu ", size / PAGE_SIZE, size / MB);
        vm_buff = vmalloc(size);
        if (!vm_buff)
        {
            pr_err("Testing Function:vmalloc failed\n");
            break;
        }
        pr_info("test --> vmalloc OK\n");
        vfree(vm_buff);
    }

    return 0;
}

static void __exit my_exit(void)
{
    pr_info("Module Exit OK \n");
}

module_init(my_init);
module_exit(my_exit);

MODULE_AUTHOR("vico 2021/09/02");
MODULE_LICENSE("GPL");

3-内存管理4-Slab块分配器内存实现

#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/init.h>

static char *kbuf;

static int sizes=40;

static struct kmem_cache *my_caches;
module_param(sizes, int, 0644);

static int __init myslab_init(void)
{
    if(sizes>KMALLOC_MAX_SIZE)
    {
        pr_err(" Size=%d is too big , You can't have more than %lu.\n",sizes,KMALLOC_MAX_SIZE);
        return -1;
    }

    my_caches=kmem_cache_create("mycaches",sizes,0,SLAB_HWCACHE_ALIGN,NULL);
    if(!my_caches)
    {
        pr_err(" kmem_cache_create() Failed.\n");
        return -ENOMEM;
    }
    pr_info(" Create mycaches CORRECT.\n");

    kbuf=kmem_cache_alloc(my_caches,GFP_ATOMIC);
    if(!kbuf)
    {
        pr_err(" Create a cache object Failed.\n");
        (void)kmem_cache_destroy(my_caches);
        return -1;
    }
    pr_info(" Create a object Successfully,kbuf_address=0x%p\n",kbuf);


    return 0;
}

static void __exit myslab_exit(void)
{
    kmem_cache_free(my_caches,kbuf);
    pr_info(" Destroy a cache object.\n");

    kmem_cache_destroy(my_caches);
    pr_info(" Destroy mycaches.\n");

}

module_init(myslab_init);
module_exit(myslab_exit);

MODULE_AUTHOR("vico");
MODULE_LICENSE("GPL");


4-内存管理4-进程地址空间在内核(VMA实现)

NO.

5-内存管理4-设计per-cpu变量应用

#include <linux/module.h>
#include <linux/init.h>
#include <linux/percpu.h>
#include <linux/cpumask.h>
static DEFINE_PER_CPU(long, cpuvar) = 5;
static long __percpu *cpualloc;

static int __init my_init(void)
{
    int cpu;
    pr_info("module loaded at 0x%p\n", my_init);
    /* modify the cpuvar value */
    for_each_possible_cpu(cpu)
    {
        per_cpu(cpuvar, cpu) = 10;
        pr_info("init: cpuvar on cpu%d = %ld\n",
                cpu, get_cpu_var(cpuvar));
        put_cpu_var(cpuvar);
    }
    __this_cpu_write(cpuvar, 10);
    /* alloc a percpu value */
    cpualloc = alloc_percpu(long);
    /* set all cpu for this value */
    for_each_possible_cpu(cpu)
    {
        *per_cpu_ptr(cpualloc, cpu) = 666;
        pr_info("init: cpu:%d cpualloc = %ld\n",
                cpu, *per_cpu_ptr(cpualloc, cpu));
    }
    return 0;
}
static void __exit my_exit(void)
{
    int cpu;
    pr_info("exit module...\n");
    for_each_possible_cpu(cpu)
    {
        pr_info("cpuvar cpu%d = %ld\n", cpu, per_cpu(cpuvar, cpu));
        pr_info("exit: cpualloc%d = %ld\n", cpu, *per_cpu_ptr(cpualloc, cpu));
    }
    free_percpu(cpualloc);
    pr_info("Bye: module unloaded from 0x%p\n", my_exit);
}
module_init(my_init);
module_exit(my_exit);
MODULE_AUTHOR("Vico");
MODULE_LICENSE("GPL");

第019讲 Linux内核内存池

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ALLOC_SIZE 8
#define LOOP 5
#define MAX_POOL_SIZE 1024*1024
#define BLOCK_SIZE 64

typedef struct memory_map_table
{
    char *p_block;
    int index;
    int used;
}Memory_Map_Table;

typedef struct memory_alloc_table
{
    char *p_start;
    int used;
    int block_start_index;
    int block_cnt;
}Memory_Alloc_Table;

typedef struct memory_pool
{
    char *memory_start;
    Memory_Alloc_Table *alloc_table;
    Memory_Map_Table *map_table;
    int total_size;
    int internal_total_size;
    int increment;
    int used_size;
    int block_size;
    int block_cnt;
    int alloc_cnt;
}Memory_Pool;

Memory_Map_Table *map_table_pos(Memory_Pool *pool)
{
        Memory_Map_Table *pm = (Memory_Map_Table *)(pool->memory_start + sizeof(Memory_Pool));
        return pm;
}

Memory_Alloc_Table *alloc_table_pos(Memory_Pool *pool)
{
    Memory_Alloc_Table *pm=(Memory_Alloc_Table*)(pool->memory_start+sizeof(Memory_Pool)+sizeof(Memory_Map_Table)*(pool->block_cnt));
    return pm;
}

char *memory_pos(Memory_Pool *pool)
{
        char *pm = (char *)(pool->memory_start + sizeof(Memory_Pool) +
                        (sizeof(Memory_Map_Table) + sizeof(Memory_Alloc_Table))* pool->block_cnt);
        return pm;
}

Memory_Pool *memory_pool_init(int size,int increment)
{
    char *p = NULL;
        char *p_memory = NULL;
        Memory_Pool *pool = NULL;
        Memory_Alloc_Table *alloc_table = NULL;
        Memory_Alloc_Table *p_alloc_table = NULL;
        Memory_Map_Table *map_table = NULL;
        Memory_Map_Table *p_map_table = NULL;
        int block_cnt = 0;
        int all_size = 0;
        int i = 0;

        if (size < 0 || size > MAX_POOL_SIZE) {
                printf("memory_pool_init(): Invalid size(%d)\n", size);
                return pool;
        }

        block_cnt = ((size + BLOCK_SIZE - 1) / BLOCK_SIZE);
        all_size = sizeof(Memory_Pool) + (sizeof(Memory_Map_Table) +
                        sizeof(Memory_Alloc_Table)) * block_cnt + size;
        p = (char *)malloc(all_size);
        if (p == NULL) {
                perror("Malloc failed\n");
                return pool;
        }

        memset(p, 0, all_size);

        pool = (Memory_Pool *)p;
        pool->block_cnt = block_cnt;
        pool->block_size = BLOCK_SIZE;
        pool->increment = increment;
        pool->internal_total_size = BLOCK_SIZE * block_cnt;
        pool->total_size = size;
        pool->used_size = 0;
        pool->alloc_cnt = 0;
        pool->memory_start = p;

        p_memory = memory_pos(pool);
        map_table = map_table_pos(pool);
        for (i = 0; i < block_cnt; i++) {
                p_map_table = (Memory_Map_Table *)((char *)map_table + i * sizeof(Memory_Map_Table));
                p_map_table->index = 0;
                p_map_table->p_block = p_memory + i * BLOCK_SIZE;
                p_map_table->used = 0;
        }

        alloc_table=alloc_table_pos(pool);
        for (i = 0; i < block_cnt; i++) {
                p_alloc_table = (Memory_Alloc_Table *)((char *)alloc_table + i * sizeof(Memory_Alloc_Table));
                p_alloc_table->block_cnt = 0;
                p_alloc_table->block_start_index = -1;
                p_alloc_table->p_start = NULL;
                p_alloc_table->used = 0;
        }

        printf("memory_pool_init: total size: %d, block cnt: %d, block size: %d\n",
                        pool->total_size, pool->block_cnt, BLOCK_SIZE);
        return pool;
}

void *Memory_malloc(Memory_Pool *pool,int size)
{
    char *p_start = NULL;
        int need_block_cnt = 0;
    Memory_Alloc_Table *alloc_table = NULL;
        Memory_Alloc_Table *p_alloc_table = NULL;
        Memory_Map_Table *map_table = NULL;
        Memory_Map_Table *p_map_table = NULL;

        int block_cnt = 0;
        int start_index = -1;
        int i = 0;

        if (size <= 0) {
                printf("Invalid size(%d)\n", size);
                return p_start;
        }

        if (size > pool->total_size) {
                printf("%d is more than total size\n", size);
                return p_start;
        }

        if (size > pool->total_size - pool->used_size) {
                printf("Free memory(%d) is less than allocate(%d)\n",
                pool->total_size - pool->used_size, size);
                return NULL;
        }

        need_block_cnt = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
        map_table = map_table_pos(pool);

        start_index = -1;
        for (i = 0; i < pool->block_cnt; i++) {
                p_map_table = (Memory_Map_Table *)((char *)map_table + i * sizeof(Memory_Map_Table));
                if (p_map_table->used) {
                        block_cnt = 0;
                        start_index = -1;
                        continue;
                }

                if (start_index == -1) {
                        start_index = i;
                }
                block_cnt++;

                if (block_cnt == need_block_cnt) {
                        break;
                }
        }

        if (start_index == -1) {
                printf("No available memory to used\n");
                return NULL;
        }

        alloc_table = alloc_table_pos(pool);

        for (i = 0; i < pool->block_cnt; i++) {
                p_alloc_table = (Memory_Alloc_Table *)((char *)alloc_table + i * sizeof(Memory_Alloc_Table));
                if (p_alloc_table->used == 0) {
                        break;
                }
                p_alloc_table = NULL;
        }

        if (p_alloc_table == NULL) {
                return NULL;
        }
        p_map_table = (Memory_Map_Table *)((char *)map_table + sizeof(Memory_Map_Table) * start_index);
        p_alloc_table->p_start = p_map_table->p_block;
        p_alloc_table->block_start_index = p_map_table->index;
        p_alloc_table->block_cnt = block_cnt;
        p_alloc_table->used = 1;

        for (i = start_index; i < start_index + block_cnt; i++) {
                p_map_table = (Memory_Map_Table *)((char *)map_table + i * sizeof(Memory_Map_Table));
                p_map_table->used = 1;
        }

        printf("Alloc size: %d, Block: (start: %d, end: %d, cnt: %d)\n", size,
                        start_index, start_index + block_cnt - 1, block_cnt);
        pool->alloc_cnt++;
        pool->used_size += size;
        return p_alloc_table->p_start;
}

void memory_free(Memory_Pool *pool,void *memory)
{
    Memory_Alloc_Table *alloc_table=NULL;
    Memory_Alloc_Table *p_alloc_table=NULL;
    Memory_Map_Table *map_table=NULL;
    Memory_Map_Table *p_map_table=NULL;

    int i=0;
    int block_start_index=0;
    int block_cnt=0;

    if(memory==NULL)
    {
        printf("memory_free():memory is NULL.\n");
        return ;
    }

    if(pool==NULL)
    {
        printf("Pool is NULL.\n");
        return ;
    }

    alloc_table=alloc_table_pos(pool);
    for(i=0;i<pool->alloc_cnt;i++)
    {
        p_alloc_table=(Memory_Alloc_Table*)((char*)alloc_table)+i*sizeof(Memory_Alloc_Table);
        if(p_alloc_table->p_start==memory)
        {
            block_start_index=p_alloc_table->block_start_index;
            block_cnt=p_alloc_table->block_cnt;
        }
    }

    if(block_cnt==0)
    {
        return ;
    }

    map_table=map_table_pos(pool);
    printf("Block:Free:start:%d,end:%d,cnt:%d\n",block_start_index,block_start_index+block_cnt-1,block_cnt);
    for(i=block_start_index;i<block_start_index+block_cnt;i++)
    {
        p_map_table=(Memory_Map_Table*)((char*)map_table+i*sizeof(Memory_Map_Table));
        p_map_table->used=0;
    }

    p_alloc_table->used=0;
    pool->used_size=block_cnt*BLOCK_SIZE;
}

void memory_pool_destroy(Memory_Pool *pool)
{
    if(pool==NULL)
    {
        printf("memory_pool_destroy:pool is NULL.\n");
        return;
    }

    free(pool);

    pool=NULL;
}


int main()
{
    Memory_Pool *pool=NULL;
    char *p1=NULL;
    char *p2=NULL;
    int i=0;

    pool=memory_pool_init(1024,512);
    if(pool==NULL)
    printf("Memory pool init Failed.\n");

    for(i=0;i<2;i++)
    {
        p1=(char*)Memory_malloc(pool,ALLOC_SIZE);
        if(p1==NULL)
        {
            printf("malloc Failed.\n");
        }
        else{
            printf("Malloc success.\n");
        }
        memory_free(pool,p1);
    }


    return 0;
}

第008讲 内存映射原理及系统调用

#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

typedef struct
{
    /* data */
    char name[4];
    int age;
}people;


void main(int argc,char**argv)
{
    int fd,i;
    people *p_map;
    char temp;
    fd=open(argv[1],O_CREAT|O_RDWR|O_TRUNC,00777);

    lseek(fd,sizeof(people)*5-1,SEEK_SET);
    write(fd,"",1);

    p_map=(people*)mmap(NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(p_map==(void*)-1)
    {
        fprintf(stderr,"mmap : %s \n",strerror(errno));
        return ;
    }
    close(fd);

    temp='A';
    for(i=0;i<10;i++)
    {
        temp=temp+1;
        (*(p_map+i)).name[1]='\0';
        memcpy((*(p_map+i)).name,&temp,1);
        (*(p_map+i)).age=30+i;
    }

    printf("Initialize.\n");

    sleep(15);

    munmap(p_map,sizeof(people)*10);

    printf("UMA OK.\n");

}



#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

typedef struct
{
    /* data */
    char name[4];
    int age;
}people;

void main(int argc,char**argv)
{
    int fd,i;
    people *p_map;

    fd=open(argv[1],O_CREAT|O_RDWR,00777);
    p_map=(people*)mmap(NULL,sizeof(people)*10,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    if(p_map==(void*)-1)
    {
        fprintf(stderr,"mmap : %s \n",strerror(errno));
        return ;
    }

    for(i=0;i<10;i++)
    {
        printf("name:%s age:%d\n",(*(p_map+i)).name,(*(p_map+i)).age);
    }

    munmap(p_map,sizeof(people)*10);

}

#include <unistd.h>
#include <signal.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>

#define handle_error(msg) do{ perror(msg); exit(EXIT_FAILURE);}while(0)

static char *buffer;

static void handler(int sig,siginfo_t *si,void *unused)
{
    printf("Get SIGSEGV at address : %p\n",si->si_addr);
    exit(EXIT_FAILURE);
}

int main(int argc,char *argv[])
{
    int pagesize;
    struct sigaction sa;

    sa.sa_flags=SA_SIGINFO;
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction=handler;

    if(sigaction(SIGSEGV,&sa,NULL)==-1)
        handle_error("siaction");

    pagesize=sysconf(_SC_PAGE_SIZE);
    if(pagesize==-1)
        handle_error("sysconf");

    buffer=memalign(pagesize,4*pagesize);
    if(buffer==NULL)
        handle_error("memalign");

    printf("start of region : %p\n",buffer);

    if(mprotect(buffer+pagesize*2,pagesize,PROT_READ)==-1)
        handle_error("mprotect");

        for(char *p=buffer;;)
        *(p++)='A';

        printf("for completed.\n");
        exit(EXIT_SUCCESS);

    return 0;
}
vma
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/sched.h>

static int pid;
module_param(pid,int,S_IRUGO);


static void PrintFunc(struct task_struct *task)
{
    struct mm_struct *mm;
    struct vm_area_struct *vma;

    int i=0;
    unsigned long start,end,length;

    mm=task->mm;
    pr_info(" mm=%p \n",mm);

    vma=mm->mmap;
    down_read(&mm->mmap_sem);

    pr_info("vmas:vma          start          end\t\tlength\n");

    while(vma)
    {
        i++;
        start=vma->vm_start;
        end=vma->vm_end;
        length=end-start;
        pr_info("%d:%p--%lx--%lx=%ld\n",i,vma,start,end,length);
        vma=vma->vm_next;
    }
    up_read(&mm->mmap_sem);

}

static int __init myvma_init(void)
{
    struct task_struct *task;
    if(pid==0)
    {
        task=current;
        pid=current->pid;
    }
    else
    {
        task=pid_task(find_vpid(pid),PIDTYPE_PID);
    }

    if(!task)
    {
        return -1;
    }
    pr_info("Exam vma's for pid=%d,command=%s\n",pid,task->comm);
    PrintFunc(task);

    return 0;
}

static void __exit myvma_exit(void)
{
    pr_info("\n Module uninstalled successfully.\n");
}

module_init(myvma_init);
module_exit(myvma_exit);

MODULE_AUTHOR("Vico");
MODULE_LICENSE("GPL");

6-同步管理-RCU实现
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <linux/kthread.h>
#include <linux/delay.h>

struct ftestrcu
{
    int a;
    struct rcu_head rcu;
};
static struct ftestrcu *g_ptr;

static int myrcu_reader_thread1(void *data)
{
    struct ftestrcu *p1 = NULL;
    while (1)
    {
        if (kthread_should_stop())
            break;
        msleep(10);

        rcu_read_lock();
        mdelay(100);
        p1 = rcu_dereference(g_ptr);
        if (p1)
            printk("%s: Read1 a1=%d\n", __func__, p1->a);
        rcu_read_unlock();
    }

    return 0;
}
static int myrcu_reader_thread2(void *data)
{
    struct ftestrcu *p2 = NULL;
    while (1)
    {
        if (kthread_should_stop())
            break;
        msleep(20);
        rcu_read_lock();
        mdelay(200);
        p2 = rcu_dereference(g_ptr);
        if (p2)
            printk("%s:Read2 a2=%d\n", __func__, p2->a);

        rcu_read_unlock();
    }

    return 0;
}

static void myrcu_del(struct rcu_head *rh)
{
    struct ftestrcu *p = container_of(rh, struct ftestrcu, rcu);
    printk("%s: a=%d\n", __func__, p->a);
    kfree(p);
}

static int myrcu_writer_thread(void *p)
{
    struct ftestrcu *old;
    struct ftestrcu *new_ptr;
    int value = (unsigned long)p;

    while (1)
    {
        if (kthread_should_stop())
            break;
        msleep(300);

        new_ptr = kmalloc(sizeof(struct ftestrcu), GFP_KERNEL);
        old = g_ptr;
        *new_ptr = *old;
        new_ptr->a = value;

        rcu_assign_pointer(g_ptr, new_ptr);
        call_rcu(&old->rcu, myrcu_del);
        printk("%s: Write to new %d\n", __func__, value);
        value++;
    }

    return 0;
}

static struct task_struct *reader_thread1;
static struct task_struct *reader_thread2;
static struct task_struct *writer_thread;

static int __init myrcu_init(void)
{
    int value = 5;
    printk("\n\nRCU Module Init OK.\n");
    g_ptr = kzalloc(sizeof(struct ftestrcu), GFP_KERNEL);
    reader_thread1 = kthread_run(myrcu_reader_thread1, NULL, "Rcu_reader1");
    reader_thread2 = kthread_run(myrcu_reader_thread2, NULL, "Rcu_reader2");
    writer_thread = kthread_run(myrcu_writer_thread, (void *)(unsigned long)value, "Rcu_Writer");

    return 0;
}

static void __exit myrcu_exit(void)
{
    printk("\nRCU Unloading Module Exit.\n\n");
    kthread_stop(reader_thread1);
    kthread_stop(reader_thread2);
    kthread_stop(writer_thread);
    if (g_ptr)
        kfree(g_ptr);
}

module_init(myrcu_init);
module_exit(myrcu_exit);

MODULE_AUTHOR("Vico");
MODULE_LICENSE("GPL");

第004讲 2进程优先级与调度策略实战
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <assert.h>

static int get_thread_policy(pthread_attr_t *attr)
{
    int plicy;
    int rs=pthread_attr_getschedpolicy(attr,&plicy);

    assert(rs==0);

    switch(plicy)
    {
        case SCHED_FIFO:
        printf("policy=SCHED_FIFO.\n");
        break;

        case SCHED_RR:
        printf("policy=SCHED_RR.\n");
        break;

        case SCHED_OTHER:
        printf("policy=SCHED_OTHER.\n");
        break;

        default:
        printf("policy=UNKNOWN.\n");
        break;
    }

    return plicy;
}

static void show_thread_priority(pthread_attr_t *attr,int policy)
{
    int priority=sched_get_priority_max(policy);
    assert(priority!=-1);
    printf("max_priority=%d\n",priority);

    priority=sched_get_priority_min(policy);
    assert(priority!=-1);
    printf("min_priority=%d\n",priority);
}


static int get_thread_priority(pthread_attr_t *attr)
{
    struct sched_param param;
    int rs=pthread_attr_getschedparam(attr,&param);
    assert(rs==0);

    printf("priority=%d",param.__sched_priority);


    return param.__sched_priority;
}


static void set_thread_policy(pthread_attr_t *attr,int policy)
{
    int rs=pthread_attr_setschedpolicy(attr,policy);

    assert(0==rs);

    get_thread_policy(attr);

}

int main()
{
    pthread_attr_t attr;
    struct sched_param sched;

    int rs=pthread_attr_init(&attr);
    assert(0==rs);

    int plicy=get_thread_policy(&attr);
    printf("output current configuration of priority.\n");
    show_thread_priority(&attr,plicy);

    printf("output SCHED_FIFO of priority.\n");
    show_thread_priority(&attr,SCHED_FIFO);

    printf("output SCHED_RR of priority.\n");
    show_thread_priority(&attr,SCHED_RR);
    printf("output priority of current thread.\n");

    int priority=get_thread_priority(&attr);
    printf("set thrad policy.\n");
    printf("set SCHED_FIFO polity.\n");
    set_thread_policy(&attr,SCHED_FIFO);

    printf("set SCHED_RR policy.\n");
    set_thread_policy(&attr,SCHED_RR);
    printf("restore current policy.\n");
    set_thread_policy(&attr,plicy);

    rs=pthread_attr_destroy(&attr);
    assert(0==rs);

    return 0;
}



#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>


void threadfunc1()
{
    sleep(1);
    int policy;
    struct sched_param praram;
    pthread_getschedparam(pthread_self(),&policy,&praram);

    if(policy==SCHED_OTHER)
    printf("SCHED_OTHER.\n");
    if(policy==SCHED_RR)
    ;
    printf("SCHED_RR 1.\n");
    if(policy==SCHED_FIFO)
    printf("SCHED_FIFO.\n");

    for(int i=1;i<=10;i++)
    {
        for(int j=1;j<4000000;j++){

        }
        printf("Threadfunc1.\n");
    }
    printf("pthreadfunc1 EXIT.\n");

}

void threadfunc2()
{
    sleep(1);
    int policy;
    struct sched_param praram;
    pthread_getschedparam(pthread_self(),&policy,&praram);

    if(policy==SCHED_OTHER)
    printf("SCHED_OTHER.\n");
    if(policy==SCHED_RR)
    ;
    printf("SCHED_RR 1.\n");
    if(policy==SCHED_FIFO)
    printf("SCHED_FIFO.\n");

    for(int i=1;i<=10;i++)
    {
        for(int j=1;j<4000000;j++){

        }
        printf("Threadfunc2.\n");
    }
    printf("pthreadfunc2 EXIT.\n");


}

void threadfunc3()
{
    sleep(1);
    int policy;
    struct sched_param praram;
    pthread_getschedparam(pthread_self(),&policy,&praram);

    if(policy==SCHED_OTHER)
    printf("SCHED_OTHER.\n");
    if(policy==SCHED_RR)
    ;
    printf("SCHED_RR 1.\n");
    if(policy==SCHED_FIFO)
    printf("SCHED_FIFO.\n");

    for(int i=1;i<=10;i++)
    {
        for(int j=1;j<4000000;j++){

        }
        printf("Threadfunc3.\n");
    }
    printf("pthreadfunc3 EXIT.\n");


}

int main()
{
    int i;
    i=getuid();

    if(i==0)
    printf("the current user is root.\n");
    else
    printf("the current user is not root.\n");

    pthread_t ppid1,ppid2,ppid3;
    struct sched_param param;

    pthread_attr_t attr1,attr2,attr3;

    pthread_attr_init(&attr2);
    pthread_attr_init(&attr1);
    pthread_attr_init(&attr3);

    param.sched_priority=51;

    pthread_attr_setschedpolicy(&attr3,SCHED_RR);
    pthread_attr_setschedparam(&attr3,&param);
    pthread_attr_setinheritsched(&attr3,PTHREAD_EXPLICIT_SCHED);

    param.sched_priority=22;
    pthread_attr_setschedpolicy(&attr2,SCHED_RR);
    pthread_attr_setschedparam(&attr2,&param);
    pthread_attr_setinheritsched(&attr2,PTHREAD_EXPLICIT_SCHED);

    pthread_create(&ppid3,&attr1,(void*)threadfunc3,NULL);
    pthread_create(&ppid2,&attr2,(void*)threadfunc2,NULL);
    pthread_create(&ppid1,&attr3,(void*)threadfunc1,NULL);

    pthread_join(ppid3,NULL);
    pthread_join(ppid2,NULL);
    pthread_join(ppid1,NULL);

    pthread_attr_destroy(&attr3);
    pthread_attr_destroy(&attr2);
    pthread_attr_destroy(&attr1);

    return 0;
}

总结

太花时间,原谅我,留着后面理解------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值