153 | | The destruction of process P can be caused by a sys_exit() system call executed by any thread of process P, or by a signal send by another process executing the sys_kill() system call. In both case, the work must be done by a thread running in the owner cluster, because all process copies must be involved, and the list of copies is rooted in the owner cluster. If the sys_kill() - or sys_exit() - function is not called in the owner cluster, an RPC is sent to the owner cluster. |
| 153 | The destruction of process P can be caused by a sys_exit() system call executed by any thread of process P, or by another process executing the sys_kill() system call. It can also be caused by a CtrlC signal typed on the process terminal. In all cases, the work must be done by a thread running in the owner cluster, because all process copies must be involved, and the list of copies is rooted in the owner cluster. It must also be done by a RPC thread, because a thread cannot delete itself. |
159 | | * Both the thread executing the sys_exit() / sys_kill() function, and the thread executing the sys_wait() function)try to take the "wait_lock" implemented in the child process descriptor (the "wait_lock" in the parent process is not used. |
160 | | * The child registers its exit value in the T thread "join_value" field, and test the JOIN_DONE flag in the T thread "flags" field: |
161 | | * If the ''wait_done'' flag is set, the PT thread arrived first and is blocked: the T thread reset the BLOCKED_EXIT bit in the PT thread (using the extended pointer stored in the "join_xp" field), reset the JOIN_DONE flag, releases the "join_lock" in T thread, and exit as described in the DETACHED case. |
162 | | * If the JOIN_DONE flag is not set, the T thread T arrived first: the T thread set the BLOCKED_JOIN bit in the T thread "blocked" field, releases the "join"lock", and deschedules. |
163 | | * The PT thread test the BLOCKED_JOIN bit in T thread: |
164 | | * If the BLOCKED_JOIN bit is set, the T thread arrived first and is blocked: the PT thread reset the BLOCKED_JOIN bit in the T thread, get the exit value from the T thread i "join_value" field, releases the "join_lock" in T thread, and continue. |
165 | | * If the BLOCKED_JOIN bit is not set, the PT thread arrived first: the PT thread register its extended pointer in the T thread "join_xp" field, set the JOIN_DONE flag in the T thread, sets the BLOCKED_EXIT bit in the PT thread "blocked" field, releases the "join_lock" in the T thread, and deschedules. |
166 | | === 6.1) process exit === |
| 159 | But the reference process destruction is more complex, because the child process destruction must be reported to the parent process when the parent process executes the blocking sys_wait() system call. Therefore, the child process destruction cannot be done before the parent calls the sys_wait() function. As the '''sys_wait()''' function, and the '''sys_kill() / sys_exit()''' function are executed by different threads running in different clusters, this requires a parent/child synchronization. |
| 160 | |
| 161 | After a sys-kill() or sys_exit(), all child process threads and all process copies are immediately destroyed, but the reference child process must be kept in ''zombi'' state if the sys_wait() syscall has not been executed. The synchronization uses three specific flags in the reference child process descriptor : the PROCESS_FLAG_KILL flag indicates that a ''kill'' request has been received by the child; the PROCESS_FLAG_EXIT flag indicates that an ''exit'' request has been received by the child; the PROCESS_FLAG_WAIT flag indicates that a ''wait'' request has been received. Moreover the sys_exit() argument of is registered in the ''exit_status'' field of the process descriptor. |
168 | | To handle the exit( value ) system call, the client thread, executing the sys_exit() function, send the RPC_PROCESS_EXIT to the owner cluster of the client process. |
| 163 | The actual deletion of the reference process is always caused by the sys_wait() function, using generally a RPC: |
| 164 | * If the sys_wait() arrives first, the corresponding flag is atomically set in the child reference process, and the parent main thread executing the sys_wait() is blocked. This parent thread will be unblocked when a ''kill'' or ''exit'' is received by the child, and delete the child reference process. |
| 165 | * If the sys_kill() or sys_exit() arrive first, the corresponding flag is atomically set in the child reference process. When these flags are detected by the parent main thread executing the sys_wait(), it deletes the reference process descriptor. |
172 | | To handle the kill( pid ) system call, the client thread, executing the sys_kill() function, send the RPC_PROCESS_KILL to the owner cluster of the process identified by the "pid" argument. We use a RPC even if the thread executing the kill() is running in the owner cluster, because a process can kill itself, and the killer thread cannot be the client thread. From this point all the work is done by the RPC in owner cluster. |
173 | | |
174 | | === 6.3) destruction scenario === |
175 | | |
176 | | 1. The RPC thread in owner cluster send a multicast and parallel RPC_PROCESS_BLOCK to all clusters containing a copy of the process. In each cluster, this RPC_PROCESS_BLOCK set the BLOCKED_GLOBAL bit and the KILL or EXIT signal, for all threads of the process. It returns only when all threads are blocked and descheduled. |
177 | | 1. When the RPC thread in owner cluster has received all expected responses to the multi-cast RPC_PROCESS_BLOCK, it send another multicast and parallel RPC_PROCESS_REMOVE to all clusters containing a copy of the process. In each cluster, this RPC releases all memory allocated to the local threads and process. |
178 | | 1. When the RPC thread in owner cluster has received all expected responses to the multi-cast RPC_PROCESS_REMOVE, it updates the owner cluster manager to remove the process from the set of owned processes, and this complete the process destruction. |
| 169 | 1. To handle the sys_kill() or sys_exit() system call, the client thread calls directly the process_make_kill() or process_make_exit() function, or use the relevant RPC if it is not running in the owner cluster. |
| 170 | 1. The process_make_kill() function in owner cluster send a multicast and parallel RPC to all clusters containing a copy of the process. In each cluster, the process_block_threads() function set the BLOCKED_GLOBAL bit for all threads of the process. It returns only when all threads are blocked and descheduled. |
| 171 | 1. When the process_make_kill() function in owner cluster has received all expected responses to the first multicast RPC, it send another multicast and parallel RPC to all clusters containing a copy of the process. In each cluster, the process_delete_threads() function releases the memory allocated to the local threads. The local process descriptor |
| 172 | is also destroyed, if it is not the reference process descriptor. |
| 173 | 1. When the process_make_kill() function in owner cluster has received all expected responses to the second multi-cast RPC, it updates the owner cluster manager |
| 174 | to remove the process from the set of owned processes. |
| 175 | 1. Finally, the process_make_kill() function synchronizes with the parent process, and the parent sys_wait() function delete the reference process descriptor. |