In this lecture, we will talk about the general process of program exit. In our system,
we use function exit and wait to do that.
When a program exits,
the function exit is called
and the system call function sys exit in this case receives the request,
then it will append the process in the killed list and then switch to other processes.
When the init process gets to run, it will call function wait to do the cleanup.
In this system, the init process is the process responsible for cleaning up other processes when they exit.
Ok, let’s see it in the process file.
As you see, we retrieved the process control and get the current process, then we change the state to
proc killed and append it in the killed list. So we add a new list
In the structure here.
Then we call wake up function. The reason we call wake up function is that the init process
which is the first process in this system is constantly calling wait function to do the cleaning up.
And it could be in sleep state,
so we wake it up before we switch process. The argument we pass
is 1 which means we will wake up the process with pid 1.
Remember the first process is assigned with pid 1.
Ok then we jump to scheduler and we are done.
Next, we move to the wait function.
The first thing we are going to do is we are going to get the killed list. And after that, we will be running in the infinite loop
to constantly find exit process and do the cleanup.
So we check the killed list to see if it is empty, if it is, we just sleep and pass 1 to it.
Here 1 is the pid of this process.
Just as we talked about in the exit function, it will wake up the process when a process exits
.
If we have elements in the list, we get the elements and do the cleanup, such as free the kernel stack page
and free vm for that process. Then we clear the process structure so that it becomes unused in the process table
.
OK, that's it for the process module.
The Next thing we are going to do is we are going to do add the system calls in the syscall file.
You can see we add sysexit and syswait here.
In the functions, we simply exit or wait functions.
And also, at this point, the checks should allow more values passing in for the index number.
Alright, with kernel module prepared, let’s rebuild the library since we need two more functions.
In the syscall file,
we write exitu,
the index number is 2.
Because it passes 0 arguments, we don’t allocate space on the stack.
So we save 0 to rdi which means no arguments. Then we int 80.
After we return from kernel, we can return to caller. Normally we will never return from sys exit
as we have seen in the exit function.
Ok next function is waitu.
The index number is 3 and it doesn’t have arguments either. So we move rdi 0.
And int 80
After returning from the kernel, we simply return.
And don't forget to global exitu
and waitu
now let’s build the library.
OK.
Also, we add the declaration of the functions in lib.h
Next we test the exit function in the user2 program, since the first program calls wait function
to do the cleanup for exit programs.
Exit out a process is simple, in the start.asm of user2, all we need to do is add exitu
after we return from main function.
Since exitu is not defined here, we add keyword extern.
In the main.c file,
we get rid of loop
and it will return from main function and exit. Ok let’s move to user1.
Since the library and start.o are the same as in the user1. We copy and paste it here.
And in the main function,
we call waitu function in a loop. The user1 program is used to call the wait function to do the cleanup in the system.
Let's build the user program.
In this example, we also need one more program, because both user1 and user2 could call function sleep,
if that happens, we will have no process to run.
And you see, the assertion in the schedule will fail. So we add user3 in the system
which will be the only process available if no other processes to run.
I have copied one in the last lecture.
The only change we make in this file
is the message process 3. Let’s build the project.
Now we can copy the 3 programs in the boot folder.
In the build script, we write the user3 from sector 126. In the loader file,
we load the user3 into address for example, 40000 from sector 126.
So in the process,
we add one more element in the array the address 40000
and change the count to 3.
OK, let's test it out.
As you see, the only process is message printed from process3.
That's it for this lecture.
See you in the next video.