进程调度
天麓
很懒的码农
展开
-
慢慢欣赏linux X86中如何使用TSS
以linux 2.6.34版本为例, 以X86_64为例声明:DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss);初始化:void __cpuinit cpu_init(void){ struct tss_struct *t; cpu = stack_smp_processor_id(); t = &per_cpu(init_tss, cpu); me = current; * * I原创 2021-04-18 18:44:24 · 495 阅读 · 0 评论 -
慢慢欣赏linux init_task进程
linux初始化的时候使用 init_task 进程, 该进程是静态创建的, 别的进程都是通过该进程克隆出来的。静态创建的含义是 current 指向 init_task 进程, 并且内核堆栈使用的是 init_task 的堆栈.下文以linux4.16.3为例描述 init_task current 如何撑起这个艰难的任务的。current_task定义如下,都是每个cpu一个:DEFINE_PER_CPU(struct task_struct *, current_task) = &am原创 2021-04-09 08:31:33 · 976 阅读 · 0 评论 -
慢慢欣赏linux 获取进程组id即tgid
#define __NR_getpid 172__SYSCALL(__NR_getpid, sys_getpid) =>SYSCALL_DEFINE0(getpid) // sys_getpid - return the thread group id of the current process { return task_tgid_vnr(current); =>pid_t task_tgid_vnr(struct task_struct *tsk) { retur.原创 2021-04-03 07:57:56 · 750 阅读 · 0 评论 -
慢慢欣赏linux 进程组的终止
voiddo_group_exit(int exit_code){ struct signal_struct *sig = current->signal; if (signal_group_exit(sig)) exit_code = sig->group_exit_code; else if (!thread_group_empty(current)) { struct sighand_struct *const sighand = current->sigha.原创 2021-03-20 23:29:00 · 118 阅读 · 0 评论 -
微视linux 进程和线程地址空间的深入理解
深入理解linux内核p86谈到:从0x0000 0000到0xbfff ffff的线性地址,无论进程运行在用户态还是内核态都可以寻址;从0xc000 0000到0xffff ffff的线性地址,只有内核态的进程才能寻址。如何理解这段话呢?进程的虚拟地址空间是0~4G-1。通过两段页表映射。进程创建后在用户空间运行,通过系统调用进入内核态,内核态存在访问用户态空间的场景,例如读取或者写用...原创 2019-05-15 07:06:11 · 245 阅读 · 0 评论 -
进程调度之时间片以及时间相关的概念
一些基本宏定义和基础概念基础时间片:DEF_TIMESLICE (100 * HZ / 1000) == 100MSCONFIG_HZ表示每秒定时器发生中断的次数。内核可以配置。JFFIY:表示1个时钟滴答。时间间隔是由CONFIG_HZ决定的,如果CONFIG_HZ配置为250,表示周期为4ms;也就是说每4ms增加一个时钟嘀嗒,即jffies++。下面几篇文章写得都不错 参考原创 2017-08-11 07:04:10 · 2299 阅读 · 0 评论 -
信号学习心得 如何模拟发信号给进程
系统调用SYSCALL_DEFINE4(rt_sigprocmask, int, how, sigset_t __user *, nset, sigset_t __user *, oset, size_t, sigsetsize) //堵塞或者撤销堵塞某些信号 =>sigprocmask SYSCALL_DEFINE3(sigprocmask, int, how,...原创 2017-07-08 22:07:01 · 519 阅读 · 0 评论 -
慢慢欣赏linux 进程创建的时候堆栈的建立
慢慢欣赏linux 进程创建的时候堆栈的建立long _do_fork(unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size, int __user *parent_tidptr, int __user *child_tidptr, unsigned long tls){ p = copy_process(clone_flags.原创 2021-03-20 23:09:32 · 205 阅读 · 0 评论 -
进程调度之创建进程
do_fork =>struct pid *pid = alloc_pid(); =>struct pid *pid = kmem_cache_alloc(pid_cachep, GFP_KERNEL);//分配pid结构体空间 =>nr = alloc_pidmap(current->nsproxy->pid_ns);//分配PID进程号 =>...原创 2018-05-12 23:52:57 · 533 阅读 · 0 评论 -
慢慢欣赏linux switch_to
以linux 4.16.3为例A->B->CA进程切换到B进程,B进程切换到C进程。在A进程的栈看来, prev为A, next为B在B进程的栈看来, prev为B, next为Cstatic __always_inline struct rq *context_switch(struct rq *rq, struct task_struct *prev, struct task_struct *next, struct rq_flags *rf){ struct mm_st原创 2021-03-12 22:57:52 · 553 阅读 · 0 评论 -
慢慢欣赏linux 用户栈与内核栈
int copy_thread_tls(unsigned long clone_flags, unsigned long sp, unsigned long arg, struct task_struct *p, unsigned long tls){ struct pt_regs *childregs = task_pt_regs(p); =>#define task_pt_regs(task) \ ({ \ unsigned long __ptr = (unsign.原创 2021-02-26 22:53:00 · 172 阅读 · 0 评论 -
进程调度之thread_info和thread_struct
对于thread_struct内核还需要存储每个进程的PCB信息, linux内核是支持不同体系的的, 但是不同的体系结构可能进程需要存储的信息不尽相同, 这就需要我们实现一种通用的方式, 我们将体系结构相关的部分和无关的部门进行分离对于PPC来说,结构体如下struct thread_struct { unsigned long ksp; /* Kernel stack poin...原创 2017-06-12 06:49:57 · 3541 阅读 · 1 评论 -
进程调度之进程切换
对于switch_to的理解:push+jmp相当于call指令。差别是call将下一条指令自动压栈。但是进程调度结束时需要执行的下一条指令并不一定是是call的下一条指令。所以需要用push和jmp细分。struct task_struct * FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next)...原创 2018-05-03 07:37:27 · 652 阅读 · 0 评论 -
慢慢欣赏linux 进程哈希表
初始化static struct hlist_head *pid_hash;static unsigned int pidhash_shift = 4;void __init pidhash_init(void){ int i, pidhash_size; pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18, HASH_EARLY | HASH_SMALL, &pid原创 2021-02-13 19:41:23 · 256 阅读 · 0 评论