Minix Memory Management
System call EXIT analysis
First, the system calls EXIT
The system call EXIT (STATUS) Sending an exit type through the process to perform the EXIT type message, which is a general means of terminating a process, all files of the EXIT close the process, and notify the Patient process if its parent process executes Wait. This call cannot be returned.
See the 38504 row of LIB for Exit (Status).
38504 public void _exit (status)
38505 int stat;
38506 {
38507 Message M;
38508
38509 m.m1_i1 = status;
38510 _syscall (mm, exit, & m);
38511}
The termination process of calling EXIT (STATUS) is sent to the MM type EXIT message and then waits for the answer to the MM and blocks (never receive the corresponding response).
Free space or other Program Stack Segment (Process 2) Variance Data Section (Process 2) Text Segment (Process 2) Free Space or Division Stack Section (Process 1) Varius Data Section (Process 1) Text Segment (Process 1) 1) Free space or other procedure
Figure 1 Combined I and D Space Memory Distribution
The process will be completely terminated in the following two events: (1) The process has exited (or has been killed by a signal), (2) Its parent process has executed WAIT system tuning to observe the occurrence What is it. It has been exited or killed and its parent process has not yet implemented WAIT's process will enter some state, sometimes referred to as a zombie. This process is no longer involved in scheduling, and its alarm clock is to be turned off, but it will remain in the process table. Its memory is released. Death is a temporary state, rarely lasting, when the parent process is finally executed, the process entries will be released and the file system and kernel are notified.
EXIT is processed by the memory manager. Process DO_MM_EXIT (16912 row) Receive this call, but most of the work is to call MM_EXIT (16927 rows), so that the partition work is because MM_EXIT is also used to process the process of signal termination, but the two works, but parameters different. After the MM receives the EXIT type message, perform DO_MM_EXIT (), and it calls mm_exit () to complete the work of the termination process. MM does not need to answer the termination process after performing DO_MM_EXIT (). The work of mm_exit () is as follows:
1. Turn off the timer of the termination process.
2. Work related to the files when the FS processing process () is notified by TELL_FS ().
3. Work related to the kernel by notifying the SYSTASK processing process exit () via sys_xit ().
4. Release the memory space of the termination process. This is divided into two cases: a, memory allocation adopts the combined I and D space, as shown in Figure 1; B, with separate I and D space, as shown in Figure 2.
Free space or other Program Stack Section (Process 2) Variance Data Section (Procedure 2) Free Space Or Other Program Stack Section (Processes 1) Various Volume Data Section (Process 1) Delination (Process 1, 2 Sharing) Free Space or other program
Figure 2 Independent I and D Space Memory Allocation
5. If there is a parent process Wait to terminate the process, inform the parent process and release the MPROC of the termination process. Otherwise, enter the zombie state, wait for the parent process to release MPROC. 6. Change all child processes into initial child processes.
After the above work, the process is normally terminated, and its Proc, MPROC is free, which is available for creating new processes.
Second, and the system calls EXIT related header files and data structures
The memory manager has a master file mm.h (15800 row), and it is used for each file to compile it. It contains the header file and other system range of each memory target module. Some headers. Const.h (15900 row) defines the variables used by the memory manager, some of which are set in the 16-bit machine.
The global variable of the memory manager is in Glo.h (16200 line), where MP is a pointer to an MPROC structure. It is the MM portion of a process table, and the system call of the process is being processed. DONT_REPLY, in each new request is initialized to false, but if there is no response message if the response message should be sent during the execution of the call, it is set to True. For example, successful EXEC does not respond. PROC_IN_USE Tracks how many processes currently use so that it is very simple to determine if the Fork is very simple. Message buffers MM_IN and MM_OUT are used for request and answer messages, respectively. The WHO is the index of the current process. Its relationship with the MP is MP = & MPROC [WHO]; when a message arrives, the system call number is drawn out in MM_CALL. Three variable err_code, result2 and res_ptr are used to hold the value returned to the caller in the reply message. The most important variable is ERR_CODE, which is set to OK at the end of the call without errors. The last two variables are used in the problem. When the process is abnormal end, Minix writes the process's image to a Core file, Core_Name defines the name of this file. Core_sset is a bitmap that defines which signals should produce a Core dump file.
The memory manager section of the process table is in the file mProc.h (16300 rows), which defines all domains and some additional information related to the process memory allocation. The most important domain is an MP_SEG array, which has three entries, which are used for text, data, and stack segments. Each entry is a structure consisting of virtual address, physical address, and segment length. They are all blocks instead of words. The day is measured, mainly to map the virtual address into a physical address. MPROC also saves the process number (PID), and the user number (UID), and group number (GID) of the process number, user number (UID), and group number (GID). Several domains and signal processing related, MP_IGNORE, MP_CATCH, MP_SIGNORE, MP_SIGMASK2 and MP_SIGPENDING are bitmaps, each bit represents a signal that can be sent to the process. Type SIGSET_T is 32-bit integers. An array MP_SIGACT is very important to the processing signal. There is an array element for each signal type, each element is a sigAction structure (00769_00773 row), each of which consists of three domains: 1, the SA_HANDLER domain defines the processing mode of the signal, is default or specialized; 2, the type of SA_MSAK is SIGSET_T to define the signal processing, which signals will be blocked. 3, the SA_FLAGS domain is a sign for some signal processing. The MP_FLAGS domain is an unsigned integer that saves some bits, 32 digits on the CPU of 386 and above, 16 bits on the low-end CPU. The last domain of the process table is MP_Procargs. When a new process is started, a stack similar to Figure 4_39 will be created, pointing to the new process args array start address, which is used by the PS command. Param.h (16400 rows) contains many macros for requesting information in request information, and 4 macros for answering messages.
Compilation of Table.c (16500 rows) will be a variety of Extern variables and structures in glo.H and mProc.h. There is an important array call_vec (16515 row) in this file. When a request message arrives, the system call number will be taken out as the index of Call_Vec to find the process of processing the system call, not a system call for legal calls. The number will cause no NO_SYS to return an error code.
Third, the system calls the function involved in EXIT
1, set_Alarm () (18067 row), this function is used by do_Alarm () to set the timer, which is also used to close the running timer that is exiting the process.
2, TELL_FS () (19192 row), this function is only used by the memory manager to send messages to the file system. For Exit calls, its format is as follows: TELL_FS (Exit, Proc, 0, 0).
3, SYS_XIT (), in fact, this is a system call system call, which is done by the function DO_XIT () (15027 line). Because in Minix, the process table is divided into three parts, kernel, memory manager, file system each accounts for one, a process of exiting requires three process table status while updating. The main function of do_xit () is to report the memory manager in an exit status by finding the kernel process table, which will not be operated, so that it will not be scheduled.
4, find_share () (17535 row), this function looks for the process of shared body in the memory manager by comparing I nodes, devices and modifications to execute files, devices, and modifications to existing processes. 5, Free_MEM () (18879 row), the main function of this function is to release the memory block and add it to the empty table. This should be processed. If the release of the memory block and the neighboring memory block in the empty table are continuous, the merge is performed. Otherwise, you can insert it directly into the memory empty table.
6, cleanup () (17061 line), the main function of this function is to complete the exit process of the process, the release process entry, and wake up the Parent process.
7, check_sig () (18265 line), this function is activated when the system calls Kill or kernel capture DEL. Its main function is to see if the signal can be sent, and this signal is often sent to a set of processes.
Fourth, memory management EXIT system call code analysis
16909 / * =============================================== ====== *
16910 * DO_MM_EXIT *
16911 * ============================================================================00 ===== * /
16912 Public INT DO_MM_EXIT ()
16913 {
16914 / * Perform The EXIT (STATUS) System Call. The Real Work Is Done by mm_exit (),
. --...
16916 * /
/ * Execute the EXIT system call, the work of the real termination process is completed by mm_exit (), mm_exit () is also used to process the process of signal termination running * /
16917
16918 mm_exit (MP, STATUS);
/ * Call function mm_exit execute exit function, termination of the process is completed by this function * /
16919 DONT_REPLY = True; / * don't reply to newly terminated process * /
/ * Do not send a response to the processes that have just terminated, Dont_Reply If you find that there is no response information to send during the execution process, it is set to true. * / 16920 Return (OK); / * Pro Forma Return Code * /
/ * EXIT procedure is smooth, return to OK * /
16921}
16924 / * ==============================================================================★ ==== *
16925 * mm_exit *
16926 * ========================================================================== === * /
16927 public void mm_exit (RMP, EXIT_STATUS)
16928 Register Struct MPROC * RMP; / * Pointer to The Process To Be Terminated * /
/ * Pointer to the pointer to the termination process, structure MPROC definition at 16307 line * /
16929 int exit_status; / * The process' exit status (for parent) * /
/ * Variable EXIT_STATUS is used to record the exit status of the process * /
16930 {
16931 / * a Process Is Done. Release Most of The Process' Possessions. If ITS
16932 * Parent is Waiting, Release The Rest, Else Hang.
16933 * /
/ * This function is used to terminate the process of the process, release the memory and process entry * /
16934
16935 Register INT Proc_nr;
16936 INT PARENT_WAITING, RIGHT_CHILD;
16937 PID_T PIDARG, PROCGRP;
/ * PID_T definition at 01655 line * /
16938 Phys_Clicks Base, Size, S; / * Base and size used on 68000 only * /
/ * Phys_clicks defined at 03108 line * /
16939
16940 proc_nr = (int) (RMP - MPROC); / * get process slot number * /
/ * Get the index number of the process in the process table * /
16941
16942 / * Remember a session leader's process group. * / 16943 procgrp = (RMP-> MP_PID == MP-> MP_PROCGRP) MP-> MP_PROCGRP: 0;
/ * Determine if there is a process group, and the process group is used to store messages. If there is a process group, write down the process group number, used to receive the message returned by the will * /
16944
16945 / * if The Exited Process Has A Timer Pending, Kill It. * /
16946 IF (RMP-> MP_FLAGS & ALARM_ON) SET_ALARM (Proc_nr, (unsigned) 0);
/ * If the process has a timer running, stop it * /
16947
16948 / * Tell The Kernel and Fs That The Process Is No longer runnable. * /
/ * Notification core and file system this process is no longer running * /
16949 TELL_FS (exit, proc_nr, 0, 0); / * file system can free the proc slot * /
/ * Send a message to the file system tells it that this process is already exit, you can release process entries in the file system * /
16950 SYS_XIT (RMP-> MP_PARENT, PROC_NR, & BASE, & SIZE);
/ * Send a message to the system task via the system to tell the system task to mark that the process is not running, making it will not be scheduled * /
16951
16952 / * Release the memory occupied by the child. * /
/ * Release memory * /
16953 if (Find_Share (RMP, RMP-> MP_INO, RMP-> MP_DEV, RMP-> MP_CTIME) == NULL) {
16954 / * No Other Process Sharees The text segment, so free it. * /
16955 Free_MEM (RMP-> MP_SEG [T] .MEM_PHYS, RMP-> MP_SEG [T] .MEM_LEN);
16956}
/ * Search Process Table, determine if a text segment is sharing with another process, as some systems use the combined I and D space, as shown in Figure 1. In this case, the occupied memory can be directly released. But the program with independent I and D space can share the body, as shown in Figure 2. If there is no other process to share a text segment, release it * /
16957 / * free the data and stack segments. * /
16958 Free_MEM (RMP-> MP_SEG [D] .MEM_PHYS,
16959 RMP-> MP_SEG [S] .MEM_VIR RMP-> MP_SEG [S] .MEM_LEN - RMP-> MP_SEG [D] .MEM_VIR);
/ * In a separate I and D space program, due to the data segment and the stack segment independent of the text segment, the two are in different spaces (can be discontinuous), so this can be released regardless of whether or not a text is shared. Process data segment and stack segment * /
16960
16961 / * The Process Slot Can Only Be FREED IF The Parent Has Done A Wait. * /
/ * The process will be completely terminated in the case where the following two events have occurred: (1) The process has exited it (or has been killed by a signal), (2) Its parent process has executed WAIT system tuning What happened. Therefore, only the process entry entry entry of the sub-process only when the parent process is waiting state * / 16962 rmp-> mp_exitstatus = (char) exit_status;
/ * Store the process exit, assign the exit_status mp_exitstatus * /
16963 pidarg = mProc [RMP-> MP_PARENT] .mp_wpid; / * WHO'S Being waited for? * /
/ * Get the PID of the process that is waiting for the process, stored in the variable pIDARG * /
16964 PARENT_WAITING = MPROC [RMP-> MP_PARENT] .mp_flags & waiting;
/ * Whether the flag bit MP_FLAGS of the Parent process is set to waiting * /
16965 if (pidarg == -1 || pidarg == RMP-> MP_PID || -pidarg == RMP-> MP_PROCGRP)
16966 Right_Child = True; / * Child Meets One of the 3 Tests * /
/ * pIDARG = -1 indicates that the waitPid system call causes the call process to block any of the sub-process; PIDARG = RMP-> MP_PID (PIDARG> 0) indicates a process pointing to a particular waiting process; -pidarg = rmp-> MP_PROCGRP means that the child process waits for any process group number = -pidarg, pidarg is set to Waitpid in the system.
16967 else
16968 Right_Child = false; / * Child Fails All 3 Tests * /
/ * Can't get the parent process of the PID that is waiting for the process, that is, the parent process is not in the waiting state * /
16969 IF (Parent_Waiting && Right_Child)
16970 Cleanup (RMP); / * Tell Parent and Release Child Slot * /
/ * The parent process is waiting, call the Cleanup () release sub-process processes * /
16971 ELSE
16972 RMP-> MP_FLAGS | = HANGING; / * PARENT NOT WAITING, SUSPEND CHILD * /
/ * Otherwise, let the process enters a zombie status * /
16973
16974 / * if the process has children, disinherit theme. IS the new parent. * /
/ * Search the process table, find the child process that just ends the process, turn them into init's child process * /
16975 for (RMP = & MPROC [0]; RMP <& mProc [NR_PROCS]; RMP ) {
16976 IF (RMP-> MP_FLAGS & IN_USE && RMP-> MP_PARENT == Proc_nr) {16977 / * 'RMP' Now Points to a child to be dispherited. * /
/ * RMP points to the child process that has just been terminated * /
16978 RMP-> MP_PARENT = init_proc_nr;
/ * Take it into init's child process * /
16979 PARENT_WAITING = MPROC [init_proc_nr] .mp_flags & waiting;
/ * See if INIT is in a waiting state * /
16980 IF (Parent_Waiting && (RMP-> MP_FLAGS & HANGING) CLEANUP (RMP);
/ * If INIT is waiting and the child process enters the HANGING state, call cleanup () to process this child process * /
16981}
16982}
16983
16984 / * Send a hangup to the process' process group if it is a session leader. * /
16985 IF (Procgrp! = 0) Check_sig (-Procgrp, SIGHUP);
/ * If the process group exists, send a signal SIGHUP to the process group, so that the system call WaitPID can process this process * /
16986}