Changeset 409 for trunk/kernel/syscalls/sys_thread_exit.c
- Timestamp:
- Dec 20, 2017, 4:51:09 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_thread_exit.c
r408 r409 1 1 /* 2 * sys_thread_exit.c - terminates the execution of c urrentthread2 * sys_thread_exit.c - terminates the execution of calling thread 3 3 * 4 * Authors Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Alain Greiner (2016,2017) 4 * Authors Alain Greiner (2016,2017) 6 5 * 7 6 * Copyright (c) UPMC Sorbonne Universites … … 24 23 25 24 #include <hal_types.h> 26 #include <hal_irqmask.h>27 25 #include <thread.h> 28 26 #include <core.h> 27 #include <vmm.h> 29 28 #include <scheduler.h> 30 29 #include <printk.h> 31 32 30 33 31 //////////////////////////////////////// 34 32 int sys_thread_exit( void * exit_value ) 35 33 { 36 thread_t * this = CURRENT_THREAD; 37 core_t * core = this->core; 38 reg_t irq_state; 34 paddr_t paddr; 35 error_t error; 39 36 40 // register the exit_value pointer in thread descriptor 41 this->exit_value = exit_value; 37 #if CONFIG_SYSCALL_DEBUG 38 uint32_t tm_start; 39 uint32_t tm_end; 40 tm_start = hal_get_cycles(); 41 #endif 42 42 43 // enter the join loop to wait the join if thread is joinable 44 if( (this->flags & THREAD_FLAG_DETACHED) == 0 ) 43 thread_t * this = CURRENT_THREAD; 44 process_t * process = this->process; 45 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 ); 51 this->errno = EINVAL; 52 return -1; 53 } 54 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 45 59 { 46 while( 1 ) 47 { 48 // take the lock protecting the flags 49 remote_spinlock_lock( XPTR( local_cxy, &this->flags_lock ) ); 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 } 50 69 51 // check the JOIN flag 52 if( this->flags & THREAD_FLAG_JOIN ) // parent made a join 53 { 54 // unblock the parent thread 55 thread_unblock( this->parent , THREAD_BLOCKED_JOIN ); 70 // take the lock protecting the join 71 remote_spinlock_lock( XPTR( local_cxy, &this->join_lock ) ); 56 72 57 // release the lock protecting the flags 58 remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) ); 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 ); 59 77 60 // exit while 61 break; 62 } 63 else // no join done by parent thread 64 { 65 // set the EXIT flag 66 this->flags |= THREAD_FLAG_EXIT; 78 // reset the JOIN_DONE flag in this thread 79 this->flags &= ~THREAD_FLAG_JOIN_DONE; 67 80 68 // block this thread 69 thread_block( this , THREAD_BLOCKED_EXIT ); 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 ); 70 88 71 72 remote_spinlock_unlock( XPTR( local_cxy, &this->flags_lock ) );89 // release the lock protecting the flags 90 remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) ); 73 91 74 // deschedule 75 sched_yield("waiting parent join"); 76 } 77 } 78 } 92 // deschedule 93 sched_yield( "WAITING JOIN" ); 94 } 95 } 79 96 80 // Release FPU if required 81 hal_disable_irq( &irq_state ); 82 if( core->fpu_owner == this ) core->fpu_owner = NULL; 83 hal_restore_irq( irq_state ); 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) ); 103 #endif 84 104 85 // suicide 86 thread_kill( this ); 87 return 0; 105 // suicide using a rpc because a thread cannot kill itself 106 rpc_thread_kill_client( local_cxy , this ); 88 107 89 } // end sys_thread_exit() 108 return 0; // never executed but required by compiler 109 110 } // end sys_thread exit
Note: See TracChangeset
for help on using the changeset viewer.