Changes between Version 83 and Version 84 of processus_thread


Ignore:
Timestamp:
Mar 1, 2018, 12:57:57 PM (6 years ago)
Author:
alain
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • processus_thread

    v83 v84  
    120120== __5) Thread destruction__ ==
    121121
    122 The destruction of an user thread T can be caused by another thread C, executing  the ''pthread_cancel()'' sys call requesting the target thread to stop execution. It can also be caused by the thread T itself, executing the ''pthread_exit()'' sys call to suicide. Finally, it can also be caused by the ''exit()'' or ''kill()'' syscalsl requesting the destruction of all threads of a given process.   
    123 
    124 TODO : handle the special case of the main thread...
     122The destruction of an user thread T can be caused by another thread C, executing  the ''pthread_cancel()'' sys call requesting the target thread to stop execution. It can be caused by the thread T itself, executing the ''pthread_exit()'' sys call to suicide. Finally, it can be caused by the ''exit()'' or ''kill()'' syscalsl requesting the destruction of all threads of a given process.   
     123
     124The unique method to destroy a thread is to set the THREAD_FLAG_REQ_KILL or THREAD_FLAG_REQ_EXIT flags in the ''flags'' field of the thread descriptor. The thread will be asynchronously deleted by the scheduler at the next scheduling point.
     125It detach the thread from the scheduler, detach the thread from the local process descriptor, and releases the memory allocated to the thread descriptor. The destruction request can be done by the ''target'' thread itself (for an exit), or it can be done by another  ''killer'' thread (for a kill).
     126
     127The main thread (i.e. the thread 0 in the process owner cluster) is a special case, because the main thread of a given process can only be deleted (i.e. marked for delete) by the parent process main thread executing the sys_wait() scale (see section [6] below).   
    125128
    126129=== 5.1) thread running in DETACHED mode ===
    127130
    128131The scenario is rather simple when the target thread is not running in ATTACHED mode.
    129 The '''thread_kill()''' kernel function is executed by a killer thread. This killer thread can the target thread itself (for a pthread_exit() sys call), or can be another thread running in any cluster. The killer thread requires the target thread scheduler to do the work at the next scheduling point, by writing in the target thread descriptor :
     132The killer thread (that can be the target thread itself for an exit) call the thread_kill() function that does the following actions:
    130133 * the killer thread  sets the BLOCKED_GLOBAL bit in the target thread ''blocked'' field,
    131  * for an exit, the calling thread sets the THREAD_FLAG_REQ_EXIT bit in the target thread ''flags'' field,
    132  * for a cancel, the calling thread sets the THREAD_FLAG_REQ_KILL bit in the target thread ''flags'' field,
    133  * at the next scheduling point, the target scheduler, detecting the SIG_SUICIDE bit, detach the thread from the scheduler, detach the thread from the local process descriptor, and releases the memory allocated to the thread descriptor.
    134 At the next scheduling point,
    135 
    136 
    137 
    138 
     134 * for an exit, the killer thread sets the THREAD_FLAG_REQ_EXIT bit in the target thread ''flags'' field,
     135 * for a kill, the killer thread sets the THREAD_FLAG_REQ_KILL bit in the target thread ''flags'' field,
     136 * the killer thread returns without waiting the actual deletion.
     137
     138
     139
     140#######
    139141and registers in the target thread ''ack_rsp_count'' field a pointer on the location where the acknowledge must be written.
    140142 * If the target thread is running on another core than the killer thread, the killer thread send an IPI to the core running the target thread, to ask the target scheduler to handle the request. If the target is running on the same thread as the killer, the killer thread calls directly the sched_handle_signal() function.
    141143 * In both cases, the sched_handle_signals() function - detecting the SIG_KILL signal - detach the target thread from the scheduler, detach the target thread from the local process descriptor, detach the target thread from the parent thread if it is attached, release the memory allocated to the target thread descriptor, and atomically decrement the response counter in the killer thread to signal completion.
     144#######
    142145
    143146=== 5.2) thread running in ATTACHED mode ===
    144147
    145 
    146  * The sys_thread_exit() function  sets the SIG_SUICIDE bit in the thread "signals" bit_vector, sets the BLOCKED_GLOBAL bit in the thread "blocked" bit_vector, and de-schedule.
    147 
    148 
    149 === 5.3) thread running in ATTACHED mode ===
    150 
    151 The thread termination is more complex if the thread T is running in ATTACHED mode, because another - possibly remote - PT thread, executing the ''pthread_join'' system call, must be informed of the termination of thread T. As the '''sys_thread_exit()''' (or ''sys_thread_cancel()'') function on one hand, and the '''sys_thread_join()''' on the other hand,  can be executed in any order, this requires a "rendez-vous": The first arrived thread block and deschedule, and must be reactivated by the other thread. This synchronisation uses three specific fields in the thread descriptor: the "join_lock" field is a remote_spin_lock; the "join_value" field contains the exit value returned by the finishing thread T; the "join_xp"field contains an extended pointer on the PT thread that wants to join. It uses one specific JOIN_DONE flag in the thread descriptor "flags" field. The scenario is not symmetrical, because the PT thread can access the T thread descriptor at any time, but the T thread cannot access the PT thread descriptor before the pthread_join execution:
    152 
    153  * Both the T thread (executing the sys_thread_exit() function), and the PT thread (executing the sys_thread_join() function) try to take the "join_lock" implemented in the T thread descriptor (the "join_lock" in the PT thread is not used).
    154  * The T thread registers its exit value in the T thread "join_value" field, and test the JOIN_DONE flag in the T thread "flags" field:
    155    * If the JOIN_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.
    156    * 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.
    157  * The PT thread test the BLOCKED_JOIN bit in T thread:
    158    * 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.
    159    * 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.
     148The thread destruction is more complex if the target thread T is running in ATTACHED mode, because another - possibly remote - J thread, executing the ''pthread_join'' system call, must be informed of the termination of thread T. As the ''thread_kill()'' function, executed by the killer thread K, and the ''sys_thread_join()'', executed by the joining thread J,  can be executed in any order, this requires a "rendez-vous": The first arrived thread blocks and deschedules. It will be unblocked by the other thread.
     149
     150Therefore, the destruction mechanism can involve three threads: the target thread T, the killer thread K, and the joining thread J:
     151
     152It uses three specific fields in the thread descriptor: the ''join_lock'' field is a remote_spin_lock; the ''join_value'' field contains the exit value returned by the T thread (only used for an exit); the ''join_xp'' field contains an extended pointer on the first arrived thread. It uses also two specific THREAD_FLAG_JOIN_DONE and THREAD_FLAG_KILL_DONE flags in the thread descriptor ''flags'' field, and one specific blocking bit THREAD_BLOCKED_JOIN, in the ''blocked'' field.
     153
     154 * Both the killer thread K, executing the thread_kill() function), and the joining thread J, executing the sys_thread_join() function, try to take the ''join_lock'' implemented in the T thread descriptor (the ''join_lock'' in the J thread is not used).
     155 * The K thread test the FLAG_JOIN_DONE in the T thread descriptor:
     156   * If the FLAG_JOIN_DONE is set, the J thread arrived first and is blocked: the K thread reset the  BLOCKED_JOIN bit in the J thread (using the extended pointer stored in the ''join_xp'' field), reset the JOIN_DONE flag, releases the ''join_lock'' in T thread, and completes the T thread destruction as described in the detached case and return.
     157   * If the FLAG_JOIN_DONE is not set, the K thread arrived first: the K thread set the BLOCKED_JOIN bit in the K thread, set the FLAG_KILL_DONE in the T thread, register its extended pointer in the T thread ''join_xp'' field, releases the ''join_lock'' in the T thread, and deschedules. It will complete the T thread destruction as described in the detached case and return when it resume.
     158 * The J thread test the FLAG_KILL_DONE in the T thread descriptor:s
     159   * If the FLAG_KILL_DONE is set, the K thread arrived first and is blocked: the J thread reset the BLOCKED_JOIN bit in the K thread, get the exit value from the T thread "join_value" field, releases the "join_lock" in T thread, and return.
     160   * If the FLAG_KILL_DONE is not set, the J thread arrived first: the J thread register its extended pointer in the T thread "join_xp" field, set the FLAG_JOIN_DONE in the T thread, sets the BLOCKED_EXIT bit in the J thread, releases the "join_lock" in the T thread, and deschedules. It will get the exit value  from the T thread "join_value" field and return when it resumes.
    160161
    161162== __6) Process destruction__ ==