One of the most important tasks of the operating system is process scheduling, which involves three main aspects: when to schedule how to select the next active process how to implement process switching
Each operating system is very different, this paper makes some detailed analysis of the process scheduling mechanism of Uc/os. When to schedule
Uc/os is the embedded real-time operating system, the focus of the real-time operating system is given the shortest response time. Therefore, the timing of task scheduling is much more, including: When the operating system starts, scheduling occurs, after the high-priority task is established, the scheduling occurs, the task is executed immediately after a low-priority task is changed to the current highest-priority task by adjusting the priority, and the active suspended high-priority task is executed immediately after it is restored; When a high-priority task that calls the delay function expires, or is canceled, it executes immediately, and high-priority tasks that are suspended as a result of waiting for an event (semaphore, mailbox, event, queue, and so on) are executed immediately when the event arrives, and when the highest-priority task waits for an event to hang, The highest priority task of the current ready state is selected, the task executes immediately, and when the task scheduling function is locked, a dispatch occurs when the task is deleted;
Specifically, the details of these timing schedules are: When you start the operating system by calling Osstart (), Uc/os selects the current highest priority task, and then calls Osstarthighrdy () to switch to the task. When a task is established by calling Ostaskcreate () or Ostaskcreateex, os_sched () is called for task switching when the basic initialization of the TCB is completed. When the call to Ostaskchangeprio () changes a task priority, os_sched () is called for task switching when the priority change is completed and a certain condition is met. When a task calls Ostaskresume () to resume execution of a task, os_sched () is called to perform a task switch if certain conditions are met. The normal expiration of the delay function is triggered by a timed interrupt, which, during the recovery phase of the interrupt, calls OSINTCTXSW () to switch to the highest priority task. The non-normal expiration of the delay function is triggered by a call to Ostimedlyresume (), in which the os_sched () is actively invoked for task switching. In the post, Pendabort, and Del functions of various semaphores, mailboxes, events, and queues, os_sched () is called for task switching. In the Pend functions of various semaphores, mailboxes, events, and queues, if the current task is to be suspended, os_sched () is called for task switching. After the Osschedunlock () function unlocks the task schedule, if the Task Scheduler is enabled, then os_sched () is called for task switching. When you call Ostaskdel () to delete a task, os_sched () is called for task switching.
Visible scheduling timing Summary into a sentence is: to meet the scheduling conditions, do not hesitate to dispatch immediately, will not wait and hesitate. From here, we can show the important features of Uc/os as a real-time operating system. How to select the next active process
Uc/os is a real-time operating system that divides 64 priorities (UC/OS-II), each with a different priority, and always chooses the highest priority task in the ready state in the event of scheduling.
In order to quickly select a ready task in a limited time, UC/OS-II established a two-level readiness table, each task (i.e. each priority) occupies a bit in the first-level readiness table OSRDYTBL, and each 8 bits is formed into a osrdygrp. This first finds the group of the highest priority task from OSRDYGRP, and then finds the task from that group in OSRDYTBL.
To speed up, a priority decision table, OSUNMAPTBL, can be addressed directly to the bit at the highest priority level from the table.
================ os_core.c ================== int8u const osunmaptbl[256] = {0u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x00 to 0x0F */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 2 U, 0u, 1u, 0u,/* 0x10 to 0x1F */5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u,/* 0x20 to 0x2F */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x30 to 0x3F
*/6u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x40 to 0X4F */ 4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x50 to 0x5f */5u, 0u, 1u, 0U, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x60 to 0x6F */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0 U, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x70 to 0x7F */7u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u , 2u, 0u, 1u, 0u,/* 0x80 to 0x8F */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0x90 to 0x9F
*/5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0xA0 to 0xAF */ 4u, 0u, 1u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u,/* 0xb0 to 1u */0u, 0xBF, 6u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0xC0 to 0xCF */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3 U, 0u, 1u, 0u, 2u, 0u, 1u, 0u,/* 0xD0 to 0xDF */5u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u , 0u, 1u, 0u,/* 0xE0 to 0xEF */4u, 0u, 1u, 0u, 2u, 0u, 1u, 0u, 3u, 0u, 1u, 0u, 2u/* 0xF0 to 0xFF */};
In this way, Uc/os chooses a task that requires only O (1) time, regardless of the current number of tasks, with a simple two-line code:
================ os_core.c 1678 1679 ==================
y = osunmaptbl[osrdygrp];
Ospriohighrdy = (int8u) ((y << 3u) + osunmaptbl[osrdytbl[y]);
The specific principle can be seen in "embedded real-time operating system Uc/os-ii" in 3.04 chapters of the introduction. comparison with Linux
Linux is a non-real-time operating system, there is a delay between process readiness and process scheduling, and the time of the delay is uncertain. This is the most important sign of a non-real-time system.
Linux is also a priority-based task Scheduler, with a task priority of 140 levels from 0~139, where 0~99 belongs to a real-time task with SCHED_FIFO or SCHED_RR attributes, 100~140 as a normal priority, Sched_normal, Sched_ Batch or Sched_idle property. The scheduling algorithm of real-time task and ordinary task is different, and the general task scheduling mechanism changes several, and from the earliest complexity to O (n) traversal scan, it develops to 2.6.23 before the O (1) scheduler, and developed to 2.6.23 after the O (Logn) based on the red black tree of the complete Fair scheduler.
Now Linux has developed a more abstract concept of the Scheduler class, making the scheduling algorithm flexible, but also developed the concept of scheduling entities, so that scheduling not only process-oriented, but also for process groups, user groups and so on. This makes it difficult to describe its scheduling algorithm in its entirety. The Interpretation of O (1) algorithm is more thorough understanding of the seventh chapter of the Linux kernel, while the scheduler class and the complete fair scheduling algorithm is more clear is "Deep Linux kernel Architecture" in the second half of chapter. Specific content will be expressed in the future.
It can be seen that the difference between Linux and Uc/os is in the requirement and complexity of real-time. The real-time operating system requires Uc/os to use a relatively simple and rude approach, limiting the maximum number of tasks and not allowing priority reuse, resulting in extremely high efficiency. Linux to multi-user, multi-tasking, each task to the response time requirements are different, destined for its high complexity, and high scalability.
The last topic of process switching is how to implement the process switching, and the topic can also be fully unfolded to separate into the chapter, we analyze the other.