Ignore:
Timestamp:
Mar 7, 2018, 9:02:03 AM (4 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/syscalls/sys_thread_exit.c

    r433 r436  
    3232int sys_thread_exit( void * exit_value )
    3333{
    34     paddr_t      paddr;
    35     error_t          error;
    36 
    37 #if CONFIG_SYSCALL_DEBUG
    38 uint32_t     tm_start;
    39 uint32_t     tm_end;
    40 tm_start = hal_get_cycles();
    41 #endif
    42 
    4334        thread_t  * this    = CURRENT_THREAD;
    4435    process_t * process = this->process;
    4536
    46     // check all locks released
    47         if( !thread_can_yield() )
    48         {
    49         printk("\n[ERROR] in %s : locks not released / thread %x in process %x\n",
    50         __FUNCTION__, this->trdid, process->pid );
     37    // check exit_value argument
     38    if( exit_value != NULL )
     39    {
     40
     41#if CONFIG_DEBUG_SYSCALLS_ERROR
     42printk("\n[ERROR] in %s : exit_value argument must be NULL for thread %x in process %x\n",
     43__FUNCTION__ , exit_value, this->trdid , process->pid );
     44#endif
    5145        this->errno = EINVAL;
    5246        return -1;
    5347    }
    5448
    55     // register the exit_value pointer in this thread descriptor
    56     this->join_value = exit_value;
    57 
    58     if( (this->flags & THREAD_FLAG_DETACHED) == 0 )    // this thread is joinable
    59     {
    60         // check exit_value in user space
    61         error = vmm_v2p_translate( false , exit_value , &paddr );
    62             if( error )
    63         {
    64             printk("\n[ERROR] in %s : illegal pointer = %x / thread %x in process %x\n",
    65             __FUNCTION__ , (intptr_t)exit_value, this->trdid , process->pid );
    66             this->errno = EINVAL;
    67             return -1;
    68         }
    69 
    70         // take the lock protecting the join
    71         remote_spinlock_lock( XPTR( local_cxy, &this->join_lock ) );
    72 
    73         if( this->flags & THREAD_FLAG_JOIN_DONE )       // parent thread arrived first
    74         {
    75             // unblock the parent thread
    76             thread_unblock( this->join_xp , THREAD_BLOCKED_EXIT );
    77 
    78             // reset the JOIN_DONE flag in this thread
    79             this->flags &= ~THREAD_FLAG_JOIN_DONE;
    80 
    81             // release the lock protecting the flags
    82                 remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) );
    83         }
    84         else                                           // this thread arrived first
    85         {
    86             // block this thread
    87             thread_block( this , THREAD_BLOCKED_JOIN );
    88 
    89             // release the lock protecting the join
    90                 remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) );
    91 
    92             // deschedule
    93             sched_yield( "WAITING JOIN" );
    94         }     
    95     }
    96 
    97 #if CONFIG_SYSCALL_DEBUG
    98 tm_end = hal_get_cycles();
    99 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n"
    100 "thread %x killed / cost = %d\n",
    101 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , tm_start ,
    102 this->trdid , (uint32_t)(tm_end - tm_start) );
     49#if CONFIG_DEBUG_SYS_THREAD_EXIT
     50uint64_t     tm_start;
     51uint64_t     tm_end;
     52tm_start = hal_get_cycles();
     53if( CONFIG_DEBUG_SYS_THREAD_EXIT < tm_start )
     54printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n",
     55__FUNCTION__ , this, process->pid , (uint32_t)tm_start );
    10356#endif
    10457
    105     // suicide using a rpc because  a thread cannot kill itself
    106     rpc_thread_kill_client( local_cxy , this );
     58    // cal the relevant kernel function
     59    thread_kill( XPTR( local_cxy , this ),
     60                 1,           // is_exit
     61                 0 );         // is forced
    10762
     63#if CONFIG_DEBUG_SYS_THREAD_EXIT
     64tm_end = hal_get_cycles();
     65if( CONFIG_DEBUG_SYS_THREAD_EXIT < tm_end )
     66printk("\n[DBG] %s : thread %x exit / process %x / cost %d / cycle %d\n",
     67__FUNCTION__, this, this->process->pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end );
     68#endif
     69
     70    // deschedule <=> suicide, because blocked by thread_kill()
     71    sched_yield( "suicide after thread_exit" );
     72   
    10873    return 0;   // never executed but required by compiler
    10974
Note: See TracChangeset for help on using the changeset viewer.