Starting from:
$25

$19

Project 1 Task 1

Preliminary knowledge
CPU-Bound task design
Loop root sign : It does not need to access disk and memory, and is a computationally intensive task.
long count=__LONG_MAX__;
for (long i = 0; i < count; i++)
{
    if(i%10000==0)
        printf("%ld\n", i);
    sqrt(100000000001.0);
}
printf("Done.\n");
return 0;
Set process priority
On startup: nice
nice -n <Priority> <Command>
CPU bound
    1. View the CPUs that can run a process
taskset -c -p <PID>
    2. Bind a process to a (set of) CPUs at startup
taskset -c <CPU_List_,_Sep> <Command>
Experimental process and results
The first part of task 1 uses the following script to start ten processes: set the nice value of 5 processes to 0, and the nice value of 5 processes to 4, and these 10 processes are all bound to logical cores 11.
#!/bin/bash
gcc -o task1 task1.c
if [ $? -eq 0 ]; then
        for i in {1..5}
        do
                nice -n 0 taskset -c 11 ./task1 &
        done    
        for i in {6..10}
        do      
                nice -n 4 taskset -c 11 ./task1 &
        done
fi
Use htop -s Commandthe command to get the following results

It can be seen that the five processes with a nice value of 0 occupy about 70% of the CPU, and the five processes with a nice value of 4 occupy about 30% of the CPU.
Create a real-time process using the following command
nice -n -20 taskset -c 11 ./task1 &
The result is as follows:

It can be seen that the real-time process occupies most of the CPU resources.
Task 2
process management
The kernel stores the list of processes in the bidirectional circular linked list of the task queue. The type of each node of the linked list is a process descriptor task_struct structure, which is defined in linux/sched.hthe file. The process descriptor contains all the information of the process, so ctxthe attributes to be implemented in task 2 should be added in task_struct.

User-defined content is best added task_structin the recommended area of ​​the page .
process creation
The process creation of Linux is decomposed into fork()two exec()functions- fork()creating a child process by copying the current process, exec()reading the executable file and loading it into the address space to start running. Linux clone()is implemented through system calls fork(), clone()and the call copy_process()completes the work of copying the parent process and creating a child process. copy_process()It is called when the process is created and is defined in kernel/fork.c. Task 2 needs to be initialized in this function ctx.

process scheduling
Functions in Linux schedule()are responsible for process scheduling. schedule()The function execution pick_next_task()function selects the process that should be scheduled most. In other words, when a process is pick_next_task()selected by a function, it will be scheduled, so it needs to pick_next_task()be executed before the function returns ctx++. schedule()and pick_next_task()are both defined in kernel/sched/core.c.

File system directory creation
Directory entries for the file system are fs/proc/base.c"registered" in, specifically in an array tgid_base_stuff[], the type of the array elements is pid_entry. The "registration" method is shown in the figure, ONEwhich is a macro defined by Linux, which means that the file to be registered ( DIRrepresents a folder). ctxIs the file name, S_IRUGOindicating that it can be read by all users, but the file permissions cannot be changed, proc_tgid_ctxand it is the corresponding function, which ctxis executed when it is read.

Compile the kernel
Kernel compilation mainly refers to How To Compile And Install Kernel On Ubuntu , and the problems encountered are detailed in the experience section.
Result analysis
The calculation-intensive application defined in Task 1 is executed in the test.

Access the process /proc/<PID>/ctxfile to see the number of times the process was scheduled.
experience
My biggest experience through this project is that my understanding of the design and implementation of Linux has been greatly improved. This is the first time I have read such a huge underlying code project. Compared with the design ideas learned in class, the complexity of the code made me confused at first.
For this reason, I read the corresponding chapters of the book "Linux Kernel Design and Implementation" in detail, and combined with the kernel source code to understand. This project allowed me to master all kinds of abstract content learned in the "Operating System" course, which is a rare and valuable project experience.
In fact, the biggest difficulty for me in this practice is the compilation and installation of the Linux kernel. Since I directly tried to install on the host Linux system, the host system faced direct interaction with various device drivers, and I may have made many changes to the kernel module later in my long-term use, so the kernel compilation encountered many problems.
The problem during the compilation process is mainly CONFIG_X86_X32and CONFIG_DEBUG_INFO_BTFthe lack of corresponding support, which must be set n. The bigger problem occurred during the installation phase, because the new kernel could not read the SSD due to the lack of corresponding modules.

After struggling with the ash shell, changing the uuid of the linux boot hard disk, and changing the SATA compatibility of the BIOS, the practice was completed on the newly created virtual machine. But this process greatly increased my understanding of the machine startup process.


More products