| 7.3 Data Structures Used by the Scheduler | ||||||||
| · The runqueue Data Structure | ||||||||
| //kernel/sched.c | ||||||||
| /* | ||||||||
| * This is the main, per-CPU runqueue data structure. | ||||||||
| * | ||||||||
| * Locking rule: those places that want to lock multiple runqueues | ||||||||
| * (such as the load balancing or the thread migration code), lock | ||||||||
| * acquire operations must be ordered by ascending &runqueue. | ||||||||
| */ | ||||||||
| struct runqueue { | ||||||||
| spinlock_t lock; | ||||||||
| /* | ||||||||
| * nr_running and cpu_load should be in the same cacheline because | ||||||||
| * remote CPUs use both these fields when doing load calculation. | ||||||||
| */ | ||||||||
| unsigned long nr_running; | ||||||||
| #ifdef CONFIG_SMP | ||||||||
| unsigned long cpu_load; | ||||||||
| #endif | ||||||||
| unsigned long long nr_switches; | ||||||||
| /* | ||||||||
| * This is part of a global counter where only the total sum | ||||||||
| * over all CPUs matters. A task can increase this counter on | ||||||||
| * one CPU and if it got migrated afterwards it may decrease | ||||||||
| * it on another CPU. Always updated under the runqueue lock: | ||||||||
| */ | ||||||||
| unsigned long nr_uninterruptible; | ||||||||
| unsigned long expired_timestamp; | ||||||||
| unsigned long long timestamp_last_tick; | ||||||||
| task_t *curr, *idle; | ||||||||
| struct mm_struct *prev_mm; | ||||||||
| prio_array_t *active, *expired, arrays[2]; | ||||||||
| int best_expired_prio; | ||||||||
| atomic_t nr_iowait; | ||||||||
| #ifdef CONFIG_SMP | ||||||||
| struct sched_domain *sd; | ||||||||
| /* For active balancing */ | ||||||||
| int active_balance; | ||||||||
| int push_cpu; | ||||||||
| task_t *migration_thread; | ||||||||
| struct list_head migration_queue; | ||||||||
| #endif | ||||||||
| #ifdef CONFIG_SCHEDSTATS | ||||||||
| …… | ||||||||
| #endif | ||||||||
| }; | ||||||||
| · fields of task_struct Data Structure | ||||||||
| …… | ||||||||
| static DEFINE_PER_CPU(struct runqueue, runqueues); | ||||||||
| #define for_each_domain(cpu, domain) / | ||||||||
| for (domain = cpu_rq(cpu)->sd; domain; domain = domain->parent) | ||||||||
| #define cpu_rq(cpu) | (&per_cpu(runqueues, (cpu))) | |||||||
| #define this_rq() | (&__get_cpu_var(runqueues)) | |||||||
| #define task_rq(p) | cpu_rq(task_cpu(p)) | |||||||
| #define cpu_curr(cpu) | (cpu_rq(cpu)->curr) | |||||||
| When a new process is created, sched_fork( ), invoked by copy_process( ), | ||||||||
| sets the time_slice field of both current (the parent) and p (the child) | ||||||||
| processes in the following way: | ||||||||
| p->time_slice = (current->time_slice + 1) >> 1; | ||||||||
| current->time_slice >>= 1; | ||||||||
| 7.4. Functions Used by the Scheduler | ||||||||
| The scheduler relies on several functions in order to do its work; the most important are: | ||||||||
| scheduler_tick( ) | ||||||||
| Keeps the time_slice counter of current up-to-date | ||||||||
| try_to_wake_up( ) | ||||||||
| Awakens a sleeping process | ||||||||
| recalc_task_prio( ) | ||||||||
| Updates the dynamic priority of a process | ||||||||
| schedule( ) | ||||||||
| Selects a new process to be executed | ||||||||
| load_balance() | ||||||||
| Keeps the runqueues of a multiprocessor system balanced | ||||||||
Understanding the linux kernel-ch7-Process Scheduling
最新推荐文章于 2023-09-19 09:55:36 发布
本文介绍Linux内核中调度器使用的数据结构,包括runqueue及其字段说明,并概述了关键调度函数的作用。
3305

被折叠的 条评论
为什么被折叠?



