Ignore:
Timestamp:
Mar 7, 2018, 9:02:03 AM (6 years ago)
Author:
alain
Message:

1) improve the threads and process destruction mechanism.
2) introduce FIFOs in the soclib_tty driver.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/kern/thread.c

    r433 r436  
    799799}  // end thread_check_sched()
    800800
    801 /////////////////////////////////////
    802 void thread_block( thread_t * thread,
    803                    uint32_t   cause )
    804 {
     801//////////////////////////////////////
     802void thread_block( xptr_t   thread_xp,
     803                   uint32_t cause )
     804{
     805    // get thread cluster and local pointer
     806    cxy_t      cxy = GET_CXY( thread_xp );
     807    thread_t * ptr = GET_PTR( thread_xp );
     808
    805809    // set blocking cause
    806     hal_atomic_or( &thread->blocked , cause );
     810    hal_remote_atomic_or( XPTR( cxy , &ptr->blocked ) , cause );
    807811    hal_fence();
    808812
     
    810814uint32_t cycle = (uint32_t)hal_get_cycles();
    811815if( CONFIG_DEBUG_THREAD_BLOCK < cycle )
    812 printk("\n[DBG] %s : thread %x blocked thread %x / cause %x / state %x / cycle %d\n",
    813 __FUNCTION__ , CURRENT_THREAD , thread , cause , thread->blocked , cycle );
     816printk("\n[DBG] %s : thread %x blocked thread %x / cause %x / cycle %d\n",
     817__FUNCTION__ , CURRENT_THREAD , ptr , cause , cycle );
     818#endif
     819
     820#if (CONFIG_DEBUG_THREAD_BLOCK & 1)
     821if( CONFIG_DEBUG_THREAD_BLOCK < cycle )
     822sched_display( ptr->core->lid );
    814823#endif
    815824
     
    831840uint32_t cycle = (uint32_t)hal_get_cycles();
    832841if( CONFIG_DEBUG_THREAD_BLOCK < cycle )
    833 printk("\n[DBG] %s : thread %x unblocked thread %x / cause %x / state %x / cycle %d\n",
    834 __FUNCTION__ , CURRENT_THREAD , ptr , cause , ptr->blocked , cycle );
     842printk("\n[DBG] %s : thread %x unblocked thread %x / cause %x / cycle %d\n",
     843__FUNCTION__ , CURRENT_THREAD , ptr , cause , cycle );
     844#endif
     845
     846#if (CONFIG_DEBUG_THREAD_BLOCK & 1)
     847if( CONFIG_DEBUG_THREAD_BLOCK < cycle )
     848sched_display( ptr->core->lid );
    835849#endif
    836850
     
    840854}  // end thread_unblock()
    841855
    842 /////////////////////////////////////
    843 void thread_kill( thread_t * target )
    844 {
    845     volatile uint32_t  rsp_count = 1;     // responses counter
    846 
    847     thread_t * killer = CURRENT_THREAD;
     856////////////////////////////////////
     857void thread_kill( xptr_t  target_xp,
     858                  bool_t  is_exit,
     859                  bool_t  is_forced )
     860{
     861    reg_t       save_sr;                // for critical section
     862    bool_t      attached;               // target thread in attached mode
     863    bool_t      join_done;              // joining thread arrived first
     864    xptr_t      killer_xp;              // extended pointer on killer thread (this)
     865    thread_t  * killer_ptr;             // pointer on killer thread (this)
     866    cxy_t       target_cxy;             // target thread cluster     
     867    thread_t  * target_ptr;             // pointer on target thread
     868    xptr_t      joining_xp;             // extended pointer on joining thread
     869    thread_t  * joining_ptr;            // pointer on joining thread
     870    cxy_t       joining_cxy;            // joining thread cluster
     871    pid_t       target_pid;             // target process PID
     872    cxy_t       owner_cxy;              // target process owner cluster
     873    trdid_t     target_trdid;           // target thread identifier
     874    ltid_t      target_ltid;            // target thread local index
     875    xptr_t      process_state_xp;       // extended pointer on <term_state> in process
     876
     877    xptr_t      target_flags_xp;        // extended pointer on target thread <flags>
     878    xptr_t      target_join_lock_xp;    // extended pointer on target thread <join_lock>
     879    xptr_t      target_join_xp_xp;      // extended pointer on target thread <join_xp>
     880    xptr_t      target_process_xp;      // extended pointer on target thread <process>
     881
     882    process_t * target_process;         // pointer on target thread process
     883
     884    // get target thread cluster and pointer
     885    target_cxy = GET_CXY( target_xp );
     886    target_ptr = GET_PTR( target_xp );
     887
     888    // get killer thread pointers
     889    killer_ptr = CURRENT_THREAD;
     890    killer_xp  = XPTR( local_cxy , killer_ptr );
    848891
    849892#if CONFIG_DEBUG_THREAD_KILL
     
    851894if( CONFIG_DEBUG_THREAD_KILL < cycle )
    852895printk("\n[DBG] %s : thread %x enter for target thread %x / cycle %d\n",
    853 __FUNCTION__, killer, target, cycle );
    854 #endif
    855 
    856     // set the global blocked bit in target thread descriptor.
    857     thread_block( target , THREAD_BLOCKED_GLOBAL );
    858 
    859     // request target scheduler to deschedule the target thread
    860     // when killer thread is not running on same core as target thread
    861     if( killer->core->lid != target->core->lid )
    862     {
    863         // set signal in target thread descriptor and in target scheduler
    864         thread_set_req_ack( target , (void *)(&rsp_count) );
    865 
    866         // send an IPI to the target thread core.
    867         dev_pic_send_ipi( local_cxy , target->core->lid );
    868 
    869         // poll the response
    870         while( 1 )
     896__FUNCTION__, killer_ptr, target_ptr, cycle );
     897#endif
     898
     899    // block the target thread
     900    thread_block( target_xp , THREAD_BLOCKED_GLOBAL );
     901
     902    // get target thread attached mode
     903    target_flags_xp = XPTR( target_cxy , &target_ptr->flags );
     904    attached = ((hal_remote_lw( target_flags_xp ) & THREAD_FLAG_DETACHED) == 0);
     905
     906    // synchronize with the joining thread
     907    // if the target thread is attached && not forced
     908
     909    if( attached  && (is_forced == false) )
     910    {
     911        // build extended pointers on target thread join fields
     912        target_join_lock_xp  = XPTR( target_cxy , &target_ptr->join_lock );
     913        target_join_xp_xp    = XPTR( target_cxy , &target_ptr->join_xp );
     914
     915        // enter critical section
     916        hal_disable_irq( &save_sr );
     917
     918        // take the join_lock in target thread descriptor
     919        remote_spinlock_lock( target_join_lock_xp );
     920
     921        // get join_done from target thread descriptor
     922        join_done = ((hal_remote_lw( target_flags_xp ) & THREAD_FLAG_JOIN_DONE) != 0);
     923   
     924        if( join_done )     // joining thread arrived first
    871925        {
    872             // exit when response received from scheduler
    873             if( rsp_count == 0 )  break;
    874 
    875             // deschedule without blocking
    876             hal_fixed_delay( 1000 );
     926            // get extended pointer on joining thread
     927            joining_xp  = (xptr_t)hal_remote_lwd( target_join_xp_xp );
     928            joining_ptr = GET_PTR( joining_xp );
     929            joining_cxy = GET_CXY( joining_xp );
     930           
     931            // reset the join_done flag in target thread
     932            hal_remote_atomic_and( target_flags_xp , ~THREAD_FLAG_JOIN_DONE );
     933
     934            // unblock the joining thread
     935            thread_unblock( joining_xp , THREAD_BLOCKED_JOIN );
     936
     937            // release the join_lock in target thread descriptor
     938            remote_spinlock_unlock( target_join_lock_xp );
     939
     940            // restore IRQs
     941            hal_restore_irq( save_sr );
    877942        }
    878     }
    879 
    880         // set REQ_DELETE flag
    881         hal_atomic_or( &target->flags , THREAD_FLAG_REQ_DELETE );
     943        else                // this thread arrived first
     944        {
     945            // set the kill_done flag in target thread
     946            hal_remote_atomic_or( target_flags_xp , THREAD_FLAG_KILL_DONE );
     947
     948            // block this thread on BLOCKED_JOIN
     949            thread_block( killer_xp , THREAD_BLOCKED_JOIN );
     950
     951            // set extended pointer on killer thread in target thread
     952            hal_remote_swd( target_join_xp_xp , killer_xp );
     953
     954            // release the join_lock in target thread descriptor
     955            remote_spinlock_unlock( target_join_lock_xp );
     956
     957            // deschedule
     958            sched_yield( "killer thread wait joining thread" );
     959
     960            // restore IRQs
     961            hal_restore_irq( save_sr );
     962        }
     963    }  // end if attached
     964
     965    // - if the target thread is the main thread
     966    //   => synchronize with the parent process main thread
     967    // - if the target thread is not the main thread
     968    //   => simply mark the target thread for delete
     969
     970    // get pointer on target thread process
     971    target_process_xp  = XPTR( target_cxy , &target_ptr->process );
     972    target_process     = (process_t *)hal_remote_lpt( target_process_xp );
     973
     974        // get target process owner cluster
     975        target_pid = hal_remote_lw( XPTR( target_cxy , &target_process->pid ) );
     976    owner_cxy = CXY_FROM_PID( target_pid );
     977
     978    // get target thread local index
     979    target_trdid = hal_remote_lw( XPTR( target_cxy , &target_ptr->trdid ) );
     980    target_ltid  = LTID_FROM_TRDID( target_trdid );
     981
     982    if( (owner_cxy == target_cxy) && (target_ltid == 0) )     // main thread
     983    {
     984        // get extended pointer on term_state in target process owner cluster
     985        process_state_xp = XPTR( owner_cxy , &target_process->term_state );
     986
     987        // set termination info in target process owner 
     988        if( is_exit ) hal_remote_atomic_or( process_state_xp , PROCESS_TERM_EXIT );
     989        else          hal_remote_atomic_or( process_state_xp , PROCESS_TERM_KILL );
    882990
    883991#if CONFIG_DEBUG_THREAD_KILL
    884992cycle  = (uint32_t)hal_get_cycles;
    885993if( CONFIG_DEBUG_THREAD_KILL < cycle )
    886 printk("\n[DBG] %s : thread %x exit for target thread %x / cycle %d\n",
    887 __FUNCTION__, killer, target, cycle );
    888 #endif
     994printk("\n[DBG] %s : thread %x exit for thread %x / main thread / cycle %d\n",
     995__FUNCTION__, killer_ptr, target_ptr, cycle );
     996#endif
     997
     998    }
     999    else                                                      // main thread
     1000    {
     1001        // set the REQ_DELETE flag in target thread descriptor
     1002        hal_remote_atomic_or( target_flags_xp , THREAD_FLAG_REQ_DELETE );
     1003
     1004#if CONFIG_DEBUG_THREAD_KILL
     1005cycle  = (uint32_t)hal_get_cycles;
     1006if( CONFIG_DEBUG_THREAD_KILL < cycle )
     1007printk("\n[DBG] %s : thread %x exit for thread %x / not the main thread / cycle %d\n",
     1008__FUNCTION__, killer_ptr, target_ptr, cycle );
     1009#endif
     1010
     1011    }
    8891012
    8901013}  // end thread_kill()
     
    9581081    target_thread_ltid = LTID_FROM_TRDID( trdid );
    9591082
     1083    // check trdid argument
     1084        if( (target_thread_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) ||
     1085        cluster_is_undefined( target_cxy ) )         return XPTR_NULL;
     1086
    9601087    // get root of list of process descriptors in target cluster
    9611088    hal_remote_memcpy( XPTR( local_cxy  , &root ),
     
    9871114    remote_spinlock_unlock( lock_xp );
    9881115
    989     // check target thread found
    990     if( found == false )
    991     {
    992         return XPTR_NULL;
    993     }
     1116    // check PID found
     1117    if( found == false ) return XPTR_NULL;
    9941118
    9951119    // get target thread local pointer
     
    9971121    target_thread_ptr = (thread_t *)hal_remote_lpt( xp );
    9981122
    999     if( target_thread_ptr == NULL )
    1000     {
    1001         return XPTR_NULL;
    1002     }
     1123    if( target_thread_ptr == NULL )  return XPTR_NULL;
    10031124
    10041125    return XPTR( target_cxy , target_thread_ptr );
Note: See TracChangeset for help on using the changeset viewer.