Ignore:
Timestamp:
Dec 20, 2017, 4:51:09 PM (6 years ago)
Author:
alain
Message:

Fix bugs in exec

File:
1 edited

Legend:

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

    r408 r409  
    112112/////////////////////////////////////////////////////////////////////////////////////
    113113// This static function initializes a thread descriptor (kernel or user).
    114 // It can be called by the four functions:
     114// It can be called by the three functions:
    115115// - thread_user_create()
    116116// - thread_user_fork()
     
    164164
    165165    thread->local_locks     = 0;
    166     list_root_init( &thread->locks_root );
    167 
    168166    thread->remote_locks    = 0;
     167
     168#if CONFIG_LOCKS_DEBUG
     169    list_root_init( &thread->locks_root ); 
    169170    xlist_root_init( XPTR( local_cxy , &thread->xlocks_root ) );
     171#endif
    170172
    171173    thread->u_stack_base    = u_stack_base;
     
    177179    thread->entry_args      = args;         // thread function arguments
    178180    thread->flags           = 0;            // all flags reset
    179     thread->signals         = 0;            // no pending signal
    180181    thread->errno           = 0;            // no error detected
    181182    thread->fork_user       = 0;            // no user defined placement for fork
    182183    thread->fork_cxy        = 0;            // user defined target cluster for fork
    183 
    184     // thread blocked
    185     thread->blocked = THREAD_BLOCKED_GLOBAL;
     184    thread->blocked         = THREAD_BLOCKED_GLOBAL;
    186185
    187186    // reset children list
     
    195194    // reset thread info
    196195    memset( &thread->info , 0 , sizeof(thread_info_t) );
     196
     197    // initializes join_lock
     198    remote_spinlock_init( XPTR( local_cxy , &thread->join_lock ) );
    197199
    198200    // initialise signature
     
    296298        return EINVAL;
    297299    }
    298 
    299     // set LOADABLE flag
    300     thread->flags = THREAD_FLAG_LOADABLE;
    301300
    302301    // set DETACHED flag if required
     
    593592        uint32_t     tm_start;
    594593        uint32_t     tm_end;
    595     reg_t        state;
     594    reg_t        save_sr;
    596595
    597596    process_t  * process    = thread->process;
     
    614613    // release memory allocated for CPU context and FPU context
    615614        hal_cpu_context_destroy( thread );
    616         hal_fpu_context_destroy( thread );
     615        if ( thread->type == THREAD_USER ) hal_fpu_context_destroy( thread );
    617616       
    618617    // release FPU if required
    619618    // TODO This should be done before calling thread_destroy()
    620         hal_disable_irq( &state );
     619        hal_disable_irq( &save_sr );
    621620        if( core->fpu_owner == thread )
    622621        {
     
    624623                hal_fpu_disable();
    625624        }
    626         hal_restore_irq( state );
     625        hal_restore_irq( save_sr );
    627626
    628627    // remove thread from process th_tbl[]
     
    668667    xlist_add_first( root , entry );
    669668    hal_remote_atomic_add( XPTR( parent_cxy , &parent_ptr->children_nr ) , 1 );
    670 }
     669
     670}  // end thread_child_parent_link()
    671671
    672672///////////////////////////////////////////////////
     
    693693    // release the lock
    694694    remote_spinlock_unlock( lock );
    695 }
     695
     696}  // thread_child_parent_unlink()
    696697
    697698/////////////////////////////////////////////////
    698699inline void thread_set_signal( thread_t * thread,
    699                                uint32_t   mask )
    700 {
    701     hal_atomic_or( &thread->signals , mask );
     700                               uint32_t * sig_rsp_count )
     701{
     702    reg_t    save_sr;   // for critical section
     703
     704    // get pointer on thread thread scheduler
     705    scheduler_t * thread_sched = &thread->core->scheduler;
     706
     707    // wait scheduler ready to handle a new signal
     708    while( thread_sched->sig_pending ) asm volatile( "nop" );
     709   
     710    // enter critical section
     711    hal_disable_irq( &save_sr );
     712     
     713    // set signal in thread scheduler
     714    thread_sched->sig_pending = true;
     715
     716    // set signal in thread thread "flags"
     717    hal_atomic_or( &thread->flags , THREAD_FLAG_SIGNAL );
     718
     719    // set pointer on responses counter in thread thread
     720    thread->sig_rsp_count = sig_rsp_count;
     721   
     722    // exit critical section
     723    hal_restore_irq( save_sr );
     724
    702725    hal_fence();
    703 }
    704 
    705 ///////////////////////////////////////////////////
    706 inline void thread_reset_signal( thread_t * thread,
    707                                  uint32_t   mask )
    708 {
    709     hal_atomic_and( &thread->signals , ~mask );
     726
     727}  // thread_set_signal()
     728
     729////////////////////////////////////////////////////
     730inline void thread_reset_signal( thread_t * thread )
     731{
     732    reg_t    save_sr;   // for critical section
     733
     734    // get pointer on target thread scheduler
     735    scheduler_t * sched = &thread->core->scheduler;
     736
     737    // check signal pending in scheduler
     738    assert( sched->sig_pending , __FUNCTION__ , "no pending signal" );
     739   
     740    // enter critical section
     741    hal_disable_irq( &save_sr );
     742     
     743    // reset signal in scheduler
     744    sched->sig_pending = false;
     745
     746    // reset signal in thread "flags"
     747    hal_atomic_and( &thread->flags , ~THREAD_FLAG_SIGNAL );
     748
     749    // reset pointer on responses counter
     750    thread->sig_rsp_count = NULL;
     751   
     752    // exit critical section
     753    hal_restore_irq( save_sr );
     754
    710755    hal_fence();
    711 }
     756
     757}  // thread_reset_signal()
    712758
    713759////////////////////////////////
     
    760806}  // end thread_unblock()
    761807
    762 /////////////////////
    763 error_t thread_exit()
    764 {
    765     reg_t      sr_save;
    766 
    767         thread_t * this = CURRENT_THREAD;
    768 
    769     // test if this thread can be descheduled
    770         if( !thread_can_yield() )
    771         {
    772         printk("ERROR in %s : locks not released for thread %x in process %x on core[%x,%d]\n",
    773         __FUNCTION__, this->trdid, this->process->pid, local_cxy, this->core->lid );
    774         return EINVAL;
    775     }
    776 
    777     if( this->flags & THREAD_FLAG_DETACHED )
    778     {
    779         // if detached set signal and set blocking cause atomically
    780         hal_disable_irq( &sr_save );
    781         thread_set_signal( this , THREAD_SIG_KILL );
    782         thread_block( this , THREAD_BLOCKED_EXIT );
    783         hal_restore_irq( sr_save );
    784     }
    785     else
    786     {
    787         // if attached, set blocking cause
    788         thread_block( this , THREAD_BLOCKED_EXIT );
    789     }
    790 
    791     // deschedule
    792     sched_yield( "exit" );
    793     return 0;
    794 
    795 }  // end thread_exit()
    796 
    797808/////////////////////////////////////
    798809void thread_kill( thread_t * target )
    799810{
    800     // set SIG_KILL signal in target thread descriptor
    801     thread_set_signal( target , THREAD_SIG_KILL );
     811    volatile uint32_t  sig_rsp_count = 1;     // responses counter
     812
     813    thread_t * killer = CURRENT_THREAD;
     814
     815kill_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n",
     816__FUNCTION__, local_cxy, killer->trdid , target trdid );
    802817
    803818    // set the global blocked bit in target thread descriptor.
    804819    thread_block( target , THREAD_BLOCKED_GLOBAL );
    805820
    806     // send an IPI to schedule the target thread core.
    807     dev_pic_send_ipi( local_cxy , target->core->lid );
     821    // request target scheduler to deschedule the target thread
     822    // when killer thread is not running on same core as target thread
     823    if( killer->core->lid != target->core->lid )
     824    {
     825        // set signal in target thread descriptor and in target scheduler
     826        thread_set_signal( target , (uint32_t *)(&sig_rsp_count) );
     827
     828        // send an IPI to the target thread core.
     829        dev_pic_send_ipi( local_cxy , target->core->lid );
     830
     831        // poll the response
     832        while( 1 )
     833        {
     834            // exit when response received from scheduler
     835            if( sig_rsp_count == 0 )  break;
     836
     837            // deschedule without blocking
     838            hal_fixed_delay( 1000 );
     839        }
     840    }
     841
     842        // release FPU if required
     843        if( target->core->fpu_owner == target )  target->core->fpu_owner = NULL;
     844
     845    // detach thread from parent if attached
     846    if( (target->flags & THREAD_FLAG_DETACHED) == 0 )
     847    thread_child_parent_unlink( target->parent , XPTR( local_cxy , target ) );
     848
     849    // detach thread from process
     850    process_remove_thread( target );
     851
     852    // remove thread from scheduler
     853    sched_remove_thread( target );
     854
     855    // release memory allocated to target thread
     856    thread_destroy( target );
     857
     858kill_dmsg("\n[DBG] %s : killer thread %x enter for target thread %x\n",
     859__FUNCTION__, local_cxy, killer->trdid , target trdid );
    808860
    809861}  // end thread_kill()
Note: See TracChangeset for help on using the changeset viewer.