Changeset 436 for trunk/kernel/syscalls
- Timestamp:
- Mar 7, 2018, 9:02:03 AM (7 years ago)
- Location:
- trunk/kernel/syscalls
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_display.c
r435 r436 37 37 reg_t arg1 ) 38 38 { 39 // get thread, process and core40 thread_t * this = CURRENT_THREAD;41 process_t * process = this->process;42 core_t * core = this->core;43 39 44 40 #if CONFIG_DEBUG_SYS_DISPLAY 45 41 uint64_t tm_start; 46 42 uint64_t tm_end; 43 thread_t * this; 44 this = CURRENT_THREAD; 47 45 tm_start = hal_get_cycles(); 48 46 if( CONFIG_DEBUG_SYS_DISPLAY < tm_start ) 49 printk("\n[DBG] %s : thread %d enter / process %x / cycle = %d\n",50 __FUNCTION__, this, process->pid, (uint32_t)tm_start );47 printk("\n[DBG] %s : thread %d enter / process %x / type %d / cycle = %d\n", 48 __FUNCTION__, this, this->process->pid, type, (uint32_t)tm_start ); 51 49 #endif 52 50 … … 80 78 81 79 // print message on TXT0 kernel terminal 82 printk("\n[USER] thread %x / process %x / core[%x,%d] / cycle %d\n %s", 83 this->trdid , process->pid , local_cxy, core->lid , 84 (uint32_t)hal_get_cycles() , kbuf ); 80 printk("\n[USER] %s / cycle %d\n", kbuf, (uint32_t)hal_get_cycles() ); 85 81 } 86 82 else if( type == DISPLAY_VMM ) … … 191 187 if( CONFIG_DEBUG_SYS_DISPLAY < tm_end ) 192 188 printk("\n[DBG] %s : thread %x exit / process %x / cost = %d / cycle %d\n", 193 __FUNCTION__, this, process->pid, (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end );189 __FUNCTION__, this, this->process->pid, (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end ); 194 190 #endif 195 191 -
trunk/kernel/syscalls/sys_exit.c
r435 r436 41 41 process_t * process = this->process; 42 42 pid_t pid = process->pid; 43 trdid_t trdid = this->trdid; 43 44 44 45 #if CONFIG_DEBUG_SYS_EXIT … … 55 56 56 57 // exit must be called by the main thread 57 if( (owner_cxy != local_cxy) || (LTID_FROM_TRDID( t his->trdid ) != 0) )58 if( (owner_cxy != local_cxy) || (LTID_FROM_TRDID( trdid ) != 0) ) 58 59 { 59 60 60 61 #if CONFIG_DEBUG_SYSCALLS_ERROR 61 printk("\n[ERROR] %s must be called by thread 0 in process owner cluster\n" 62 " trdid = %x / pid = %x / local_cxy = %x\n", 63 __FUNCTION__, this->trdid, pid, local_cxy ); 62 printk("\n[ERROR] in %s : calling thread %x is not thread 0 in owner cluster %x\n", 63 __FUNCTION__, trdid, owner_cxy ); 64 64 #endif 65 65 this->errno = EINVAL; … … 73 73 process->term_state = status; 74 74 75 // remove TXT ownership from owner process descriptor 76 process_txt_reset_ownership( XPTR( local_cxy , process ) ); 75 #if( CONFIG_DEBUG_SYS_EXIT & 1) 76 printk("\n[DBG] %s : set exit status in process term_state\n", __FUNCTION__); 77 #endif 77 78 78 // block all process threads in all clusters79 process_ sigaction( pid , BLOCK_ALL_THREADS);79 // remove process from TXT list 80 process_txt_detach( XPTR( local_cxy , process ) ); 80 81 81 // mark all process threads in all clusters for delete 82 #if( CONFIG_DEBUG_SYS_EXIT & 1) 83 printk("\n[DBG] %s : removed from TXT list\n", __FUNCTION__); 84 #endif 85 86 // mark for delete all process threads in all clusters (but the main) 82 87 process_sigaction( pid , DELETE_ALL_THREADS ); 88 89 #if( CONFIG_DEBUG_SYS_EXIT & 1) 90 printk("\n[DBG] %s : deleted all other threads than main\n", __FUNCTION__); 91 #endif 83 92 84 93 // restore IRQs 85 94 hal_restore_irq( save_sr ); 86 95 87 // atomically update owner process descriptor term_state 96 // block the main thread itself 97 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_GLOBAL ); 98 99 #if( CONFIG_DEBUG_SYS_EXIT & 1) 100 printk("\n[DBG] %s : blocked the main thread\n", __FUNCTION__); 101 #endif 102 103 // atomically update owner process descriptor term_state to ask 104 // the parent process sys_wait() function to delete this main thread 88 105 hal_remote_atomic_or( XPTR( local_cxy , &process->term_state ) , 89 106 PROCESS_TERM_EXIT ); 107 108 #if( CONFIG_DEBUG_SYS_EXIT & 1) 109 printk("\n[DBG] %s : set EXIT flag in process term_state\n", __FUNCTION__); 110 #endif 111 90 112 hal_fence(); 91 113 … … 97 119 #endif 98 120 121 // main thread deschedule 122 sched_yield( "process exit" ); 123 124 // this code should never be executed 125 assert( false , __FUNCTION__ , "this code should not be executed...\n" ); 99 126 return 0; 100 127 -
trunk/kernel/syscalls/sys_fg.c
r421 r436 45 45 thread_t * this = CURRENT_THREAD; 46 46 47 #if CONFIG_ SYSCALL_DEBUG47 #if CONFIG_DEBUG_SYS_FG 48 48 uint64_t tm_start; 49 49 uint64_t tm_end; 50 50 tm_start = hal_get_cycles(); 51 printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle %d\n", 52 __FUNCTION__ , local_cxy , this->core->lid , pid, (uint32_t)tm_start ); 51 if( CONFIG_DEBUG_SYS_FG < tm_start ) 52 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n", 53 __FUNCTION__ , CURRENT_THREAD , pid, (uint32_t)tm_start ); 53 54 #endif 54 55 … … 58 59 if( process_xp == XPTR_NULL ) 59 60 { 60 syscall_dmsg("\n[ERROR] in %s : process %x not found\n", 61 __FUNCTION__ , pid ); 61 62 #if CONFIG_DEBUG_SYSCALLS_ERROR 63 printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__ , pid ); 64 #endif 62 65 this->errno = EINVAL; 63 66 return -1; … … 72 75 73 76 // get chdev cluster and local pointer 74 chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );77 chdev_ptr = GET_PTR( chdev_xp ); 75 78 chdev_cxy = GET_CXY( chdev_xp ); 76 79 … … 80 83 hal_fence(); 81 84 82 #if CONFIG_ SYSCALL_DEBUG85 #if CONFIG_DEBUG_SYS_FG 83 86 tm_end = hal_get_cycles(); 84 printk("\n[DBG] %s : core[%x,%d] exit / process %x / cost = %d\n", 85 __FUNCTION__ , local_cxy , this->core->lid , pid, (uint32_t)(tm_end - tm_start) ); 87 if( CONFIG_DEBUG_SYS_FG < tm_end ) 88 printk("\n[DBG] %s : thread %x exit / process %x get TXT_%d ownership / cycle %d\n", 89 __FUNCTION__ , CURRENT_THREAD , pid, 90 hal_remote_lw( XPTR( chdev_cxy , &chdev_ptr->channel ) ) , (uint32_t)tm_end ); 86 91 #endif 87 92 88 93 return 0; 89 94 90 } // end sys_ kill()95 } // end sys_fg() 91 96 -
trunk/kernel/syscalls/sys_get_config.c
r435 r436 87 87 tm_end = hal_get_cycles(); 88 88 if( CONFIG_DEBUG_SYS_GET_CONFIG < tm_end ) 89 printk("\n[DBG] %s : thread %x exit / process %x / cost %d / tycle %d\n",89 printk("\n[DBG] %s : thread %x exit / process %x / cost %d / cycle %d\n", 90 90 __FUNCTION__, this, process->pid, (uint32_t)(tm_end-tm_start), (uint32_t)tm_end ); 91 91 #endif -
trunk/kernel/syscalls/sys_kill.c
r435 r436 37 37 uint32_t sig_id ) 38 38 { 39 uint32_t save_sr; // required to enable IRQs 40 xptr_t owner_xp; // extended pointer on target reference process 41 cxy_t owner_cxy; // target process cluster 42 process_t * owner_ptr; // local pointer on target process 39 xptr_t owner_xp; // extended pointer on target process in owner cluster 40 cxy_t owner_cxy; // target process owner cluster 41 process_t * owner_ptr; // local pointer on target process in owner cluster 43 42 xptr_t parent_xp; // extended pointer on parent process 44 43 cxy_t parent_cxy; // parent process cluster … … 49 48 thread_t * this = CURRENT_THREAD; 50 49 process_t * process = this->process; 50 trdid_t trdid = this->trdid; 51 51 52 52 #if CONFIG_DEBUG_SYS_KILL … … 59 59 #endif 60 60 61 // process cannot kill itself 62 if( pid == process->pid ) 61 // get pointers on process descriptor in owner cluster 62 owner_xp = cluster_get_owner_process_from_pid( pid ); 63 owner_cxy = GET_CXY( owner_xp ); 64 owner_ptr = GET_PTR( owner_xp ); 65 66 // check process found 67 if( owner_xp == XPTR_NULL) 63 68 { 64 69 65 70 #if CONFIG_DEBUG_SYSCALLS_ERROR 66 printk("\n[ERROR] in %s : process % d cannot kill itself\n", __FUNCTION__, pid );71 printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__, pid ); 67 72 #endif 68 73 this->errno = EINVAL; … … 70 75 } 71 76 72 // get cluster and pointers on owner target process descriptor 73 owner_xp = cluster_get_owner_process_from_pid( pid ); 74 owner_cxy = GET_CXY( owner_xp ); 75 owner_ptr = GET_PTR( owner_xp ); 76 77 // check process existence 78 if( owner_xp == XPTR_NULL ) 77 // process can kill itself only when calling thread is the main thread 78 if( (pid == process->pid) && ((owner_cxy != local_cxy) || (LTID_FROM_TRDID( trdid ))) ) 79 79 { 80 80 81 81 #if CONFIG_DEBUG_SYSCALLS_ERROR 82 printk("\n[ERROR] in %s : process %x not found\n", __FUNCTION__ , pid);82 printk("\n[ERROR] in %s : only main thread can kill itself\n", __FUNCTION__ ); 83 83 #endif 84 84 this->errno = EINVAL; 85 85 return -1; 86 86 } 87 87 88 88 // get parent process PID 89 89 parent_xp = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); … … 92 92 ppid = hal_remote_lw( XPTR( parent_cxy , &parent_ptr->pid ) ); 93 93 94 // processesINIT94 // check processe INIT 95 95 if( pid == 1 ) 96 96 { … … 103 103 } 104 104 105 // enable IRQs106 hal_enable_irq( &save_sr );107 108 105 // analyse signal type / supported values are : 0, SIGSTOP, SIGCONT, SIGKILL 109 106 switch( sig_id ) 110 107 { 111 case 0 : 108 case 0 : // does nothing 112 109 { 113 // does nothing114 110 retval = 0; 115 111 break; 116 112 } 117 case SIGSTOP: 113 case SIGSTOP: // block all target process threads 118 114 { 119 // remove TXT ownership from target process120 process_txt_ reset_ownership( owner_xp );115 // transfer TXT ownership 116 process_txt_transfer_ownership( owner_xp ); 121 117 122 // block all threads in all clusters 118 // block all threads in all clusters, but the main thread 123 119 process_sigaction( pid , BLOCK_ALL_THREADS ); 120 121 // get pointer on target process main thread 122 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 123 124 // block main thread 125 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 124 126 125 127 // atomically update owner process termination state 126 128 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 127 129 PROCESS_TERM_STOP ); 128 129 130 retval = 0; 130 131 break; 131 132 } 132 case SIGCONT: 133 case SIGCONT: // unblock all target process threads 133 134 { 134 135 // unblock all threads in all clusters 135 136 process_sigaction( pid , UNBLOCK_ALL_THREADS ); 136 137 137 // atomically update referenceprocess termination state138 // atomically update owner process termination state 138 139 hal_remote_atomic_and( XPTR( owner_cxy , &owner_ptr->term_state ) , 139 140 ~PROCESS_TERM_STOP ); … … 144 145 case SIGKILL: 145 146 { 146 // remove TXT ownership from owner process descriptor147 process_txt_ reset_ownership( owner_xp );147 // remove process from TXT list 148 process_txt_detach( owner_xp ); 148 149 149 // block all process threads in all clusters 150 process_sigaction( pid , BLOCK_ALL_THREADS ); 151 152 // mark all process threads in all clusters for delete 150 // mark for delete all process threads in all clusters, but the main 153 151 process_sigaction( pid , DELETE_ALL_THREADS ); 154 152 155 // atomically update owner process descriptor flags 153 // get pointer on target process main thread 154 xptr_t main_xp = XPTR( owner_cxy , &owner_ptr->th_tbl[0] ); 155 156 // block main thread 157 thread_block( main_xp , THREAD_BLOCKED_GLOBAL ); 158 159 // atomically update owner process descriptor term_state to ask 160 // the parent process sys_wait() function to delete this main thread 156 161 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 157 162 PROCESS_TERM_KILL ); 158 159 163 retval = 0; 160 164 break; … … 172 176 } 173 177 174 // restore IRQs175 hal_restore_irq( save_sr );176 177 178 hal_fence(); 178 179 … … 180 181 tm_end = hal_get_cycles(); 181 182 if( CONFIG_DEBUG_SYS_KILL < tm_end ) 182 printk("\n[DBG] %s : thread %x e nter/ process %x / sig %d / cost = %d / cycle %d\n",183 printk("\n[DBG] %s : thread %x exit / process %x / sig %d / cost = %d / cycle %d\n", 183 184 __FUNCTION__ , this, pid, sig_id, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 184 185 #endif -
trunk/kernel/syscalls/sys_read.c
r435 r436 37 37 38 38 extern uint32_t enter_sys_read; 39 extern uint32_t enter_devfs_ move;39 extern uint32_t enter_devfs_read; 40 40 extern uint32_t enter_txt_read; 41 extern uint32_t enter_chdev_cmd ;42 extern uint32_t enter_chdev_server ;43 extern uint32_t enter_tty_cmd ;44 extern uint32_t enter_tty_isr ;45 extern uint32_t exit_tty_isr ;46 extern uint32_t exit_tty_cmd ;47 extern uint32_t exit_chdev_server ;48 extern uint32_t exit_chdev_cmd ;41 extern uint32_t enter_chdev_cmd_read; 42 extern uint32_t enter_chdev_server_read; 43 extern uint32_t enter_tty_cmd_read; 44 extern uint32_t enter_tty_isr_read; 45 extern uint32_t exit_tty_isr_read; 46 extern uint32_t exit_tty_cmd_read; 47 extern uint32_t exit_chdev_server_read; 48 extern uint32_t exit_chdev_cmd_read; 49 49 extern uint32_t exit_txt_read; 50 extern uint32_t exit_devfs_ move;50 extern uint32_t exit_devfs_read; 51 51 extern uint32_t exit_sys_read; 52 52 … … 63 63 reg_t save_sr; // required to enable IRQs during syscall 64 64 65 #if (CONFIG_DEBUG_SYS_READ & 1)66 enter_sys_read = (uint32_t)tm_start;67 #endif68 69 65 thread_t * this = CURRENT_THREAD; 70 66 process_t * process = this->process; … … 79 75 #endif 80 76 77 #if (CONFIG_DEBUG_SYS_READ & 1) 78 enter_sys_read = (uint32_t)tm_start; 79 #endif 80 81 81 // check file_id argument 82 82 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) … … 122 122 123 123 // get file descriptor cluster and local pointer 124 vfs_file_t * file_ptr = (vfs_file_t *)GET_PTR( file_xp );124 vfs_file_t * file_ptr = GET_PTR( file_xp ); 125 125 cxy_t file_cxy = GET_CXY( file_xp ); 126 126 … … 165 165 else if( type == INODE_TYPE_DEV ) // check ownership & read from from device 166 166 { 167 // get cluster and pointers on TXT_RX chdev 168 xptr_t chdev_xp = chdev_from_file( file_xp ); 169 cxy_t chdev_cxy = GET_CXY( chdev_xp ); 170 chdev_t * chdev_ptr = GET_PTR( chdev_xp ); 171 172 volatile xptr_t owner_xp; 173 174 while( 1 ) 175 { 176 // extended pointer on owner process 177 owner_xp = hal_remote_lwd( XPTR( chdev_cxy , &chdev_ptr->ext.txt.owner_xp ) ); 178 179 // check TXT_RX ownership 180 if ( XPTR( local_cxy , process ) != owner_xp ) 181 { 182 // deschedule without blocking 183 sched_yield( "wait TXT ownership" ); 184 } 185 else 186 { 187 break; 188 } 189 } 190 167 191 // move count bytes from device 168 192 nbytes = devfs_user_move( true, // from device to buffer … … 171 195 count ); 172 196 173 // check ownership174 xptr_t chdev_xp = chdev_from_file( file_xp );175 cxy_t chdev_cxy = GET_CXY( chdev_xp );176 chdev_t * chdev_ptr = (chdev_t *)GET_PTR( chdev_xp );177 xptr_t owner_xp = hal_remote_lwd( XPTR( chdev_cxy , &chdev_ptr->ext.txt.owner_xp ) );178 179 if( XPTR( local_cxy , process ) != owner_xp )180 {181 182 #if CONFIG_DEBUG_SYSCALLS_ERROR183 printk("\n[ERROR] in %s : process %x not in foreground for TXT%d\n",184 __FUNCTION__, process->pid, hal_remote_lw( XPTR(chdev_cxy,&chdev_ptr->channel) ) );185 #endif186 this->errno = EBADFD;187 return -1;188 }189 197 } 190 198 else … … 215 223 printk("\n[DBG] %s : thread %x exit / process %x / cycle %d\n" 216 224 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n", 217 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid,225 __FUNCTION__ , this, process->pid, 218 226 (uint32_t)tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id , 219 227 (uint32_t)(tm_end - tm_start) ); -
trunk/kernel/syscalls/sys_thread_cancel.c
r410 r436 1 1 /* 2 * sys_thread_cancel.c - terminate execution of a targetthread.2 * sys_thread_cancel.c - terminate execution of an user thread. 3 3 * 4 * Authors Alain Greiner (2016,2017 )4 * Authors Alain Greiner (2016,2017, 2018) 5 5 * 6 * Copyright (c) 2011,2012UPMC Sorbonne Universites6 * Copyright (c) UPMC Sorbonne Universites 7 7 * 8 8 * This file is part of ALMOS-MKH. … … 33 33 { 34 34 xptr_t target_xp; // target thread extended pointer 35 thread_t * target_ptr; // target thread local pointer36 cxy_t target_cxy; // target thread cluster37 ltid_t target_ltid; // target thread local index38 35 39 #if CONFIG_SYSCALL_DEBUG 40 uint32_t tm_start; 41 uint32_t tm_end; 42 tm_start = hal_get_cycles(); 43 #endif 44 36 // get killer thread pointers 45 37 thread_t * this = CURRENT_THREAD; 46 38 process_t * process = this->process; 47 48 // check kernel stack overflow49 assert( (this->signature == THREAD_SIGNATURE), __FUNCTION__, "kernel stack overflow\n" );50 51 // get target thread ltid and cxy52 target_ltid = LTID_FROM_TRDID( trdid );53 target_cxy = CXY_FROM_TRDID( trdid );54 55 // check trdid argument56 if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) )57 {58 printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ );59 this->errno = EINVAL;60 return -1;61 }62 39 63 40 // get extended pointer on target thread 64 41 target_xp = thread_get_xptr( process->pid , trdid ); 65 42 43 // check target_xp 66 44 if( target_xp == XPTR_NULL ) 67 45 { 68 printk("\n[ERROR] in %s : target thread not found\n", __FUNCTION__ ); 46 47 #if CONFIG_DEBUG_SYSCALLS_ERROR 48 printk("\n[ERROR] in %s : target thread %x not found\n", __FUNCTION__, trdid ); 49 #endif 69 50 this->errno = EINVAL; 70 51 return -1; 71 52 } 72 53 73 // get target thread local pointer 74 target_ptr = (thread_t *)GET_PTR( target_xp ); 54 #if CONFIG_DEBUG_SYS_THREAD_CANCEL 55 uint64_t tm_start; 56 uint64_t tm_end; 57 tm_start = hal_get_cycles(); 58 if( CONFIG_DEBUG_SYS_THREAD_CANCEL < tm_start ) 59 printk("\n[DBG] %s : thread %x enter to kill thread %x / cycle %d\n", 60 __FUCTION__, this, GET_PTR( target_xp ), (uint32_t)tm_start ); 61 #endif 75 62 76 63 // cal the relevant kernel function 77 if( target_cxy == local_cxy ) // target thread is local 78 { 79 thread_kill( target_ptr ); 80 } 81 else 82 { 83 rpc_thread_kill_client( target_cxy , target_ptr ); 84 } 64 thread_kill( target_xp, 65 0, // is_exit 66 0 ); // is forced 85 67 86 #if CONFIG_ SYSCALL_DEBUG68 #if CONFIG_DEBUG_SYS_THREAD_CANCEL 87 69 tm_end = hal_get_cycles(); 88 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 89 "thread %x killed / cost = %d\n", 90 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , tm_start , 91 trdid , (uint32_t)(tm_end - tm_start) ); 70 if( CONFIG_DEBUG_SYS_THREAD_CANCEL < tm_end ) 71 printk("\n[DBG] %s : thread %x exit after kill thread %x / cycle %d\n", 72 __FUCTION__, this, GET_PTR( target_xp ), (uint32_t)tm_end ); 92 73 #endif 93 74 -
trunk/kernel/syscalls/sys_thread_exit.c
r433 r436 32 32 int sys_thread_exit( void * exit_value ) 33 33 { 34 paddr_t paddr;35 error_t error;36 37 #if CONFIG_SYSCALL_DEBUG38 uint32_t tm_start;39 uint32_t tm_end;40 tm_start = hal_get_cycles();41 #endif42 43 34 thread_t * this = CURRENT_THREAD; 44 35 process_t * process = this->process; 45 36 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 42 printk("\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 51 45 this->errno = EINVAL; 52 46 return -1; 53 47 } 54 48 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 50 uint64_t tm_start; 51 uint64_t tm_end; 52 tm_start = hal_get_cycles(); 53 if( CONFIG_DEBUG_SYS_THREAD_EXIT < tm_start ) 54 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n", 55 __FUNCTION__ , this, process->pid , (uint32_t)tm_start ); 103 56 #endif 104 57 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 107 62 63 #if CONFIG_DEBUG_SYS_THREAD_EXIT 64 tm_end = hal_get_cycles(); 65 if( CONFIG_DEBUG_SYS_THREAD_EXIT < tm_end ) 66 printk("\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 108 73 return 0; // never executed but required by compiler 109 74 -
trunk/kernel/syscalls/sys_thread_join.c
r421 r436 25 25 #include <hal_remote.h> 26 26 #include <hal_special.h> 27 #include <hal_irqmask.h> 27 28 #include <thread.h> 28 29 #include <vmm.h> … … 36 37 void ** exit_value ) 37 38 { 39 reg_t save_sr; 38 40 xptr_t target_xp; 39 41 thread_t * target_ptr; 40 42 cxy_t target_cxy; 41 43 ltid_t target_ltid; 42 uint32_t target_blocked; // target thread blocked bit-vector 43 uint32_t target_flags; // target thread flags bit-bector 44 paddr_t paddr; // required for vmm_v2p_translate() 44 xptr_t target_join_lock_xp; 45 xptr_t target_flags_xp; 46 xptr_t target_blocked_xp; 47 xptr_t target_join_xp_xp; 48 xptr_t killer_xp; 49 xptr_t joining_xp; 50 thread_t * joining_ptr; 51 process_t * process; 45 52 46 thread_t * this = CURRENT_THREAD; 47 process_t * process = this->process; 53 // get joining thread pointers 54 joining_ptr = CURRENT_THREAD; 55 joining_xp = XPTR( local_cxy , joining_ptr ); 56 process = joining_ptr->process; 48 57 49 58 // get target thread ltid and cxy … … 51 60 target_cxy = CXY_FROM_TRDID( trdid ); 52 61 62 #if CONFIG_DEBUG_SYS_THREAD_JOIN 63 uint64_t tm_start; 64 uint64_t tm_end; 65 tm_start = hal_get_cycles(); 66 if( CONFIG_DEBUG_SYS_THREAD_JOIN < tm_start ) 67 printk("\n[DBG] %s : parent thread %x enter / process %x / target trdid %x / cycle %d\n", 68 __FUNCTION__ , joining_ptr , process->pid , trdid , (uint32_t)tm_start ); 69 #endif 70 53 71 // check trdid argument 54 72 if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 55 73 { 56 printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ ); 57 this->errno = EINVAL; 74 75 #if CONFIG_DEBUG_SYSCALLS_ERROR 76 printk("\n[ERROR] in %s : illegal trdid argument %x\n", __FUNCTION__, trdid ); 77 #endif 78 joining_ptr->errno = EINVAL; 58 79 return -1; 59 80 } 60 81 61 82 // check exit_value argument 62 if( (exit_value != NULL) && (vmm_v2p_translate( false , exit_value , &paddr ) != 0 ))83 if( exit_value != NULL ) 63 84 { 64 printk("\n[ERROR] in %s : illegal exit_value argument\n", __FUNCTION__ ); 65 this->errno = EINVAL; 85 86 #if CONFIG_DEBUG_SYSCALLS_ERROR 87 printk("\n[ERROR] in %s : exit_value argument must be NULL\n", __FUNCTION__ ); 88 #endif 89 joining_ptr->errno = EINVAL; 66 90 return -1; 67 91 } 68 92 69 93 // check target thread != this thread 70 if( this->trdid == trdid )94 if( joining_ptr->trdid == trdid ) 71 95 { 72 printk("\n[ERROR] in %s : this thread == target thread\n", __FUNCTION__ ); 73 this->errno = EDEADLK; 96 97 #if CONFIG_DEBUG_SYSCALLS_ERROR 98 printk("\n[ERROR] in %s : this thread == target thread\n", __FUNCTION__ ); 99 #endif 100 joining_ptr->errno = EDEADLK; 74 101 return -1; 75 102 } 76 103 77 // get extended pointeron target thread104 // get pointers on target thread 78 105 target_xp = thread_get_xptr( process->pid , trdid ); 106 target_ptr = GET_PTR( target_xp ); 79 107 80 108 if( target_xp == XPTR_NULL ) 81 109 { 82 printk("\n[ERROR] in %s : target thread not found\n", __FUNCTION__ ); 83 this->errno = ESRCH; 110 111 #if CONFIG_DEBUG_SYSCALLS_ERROR 112 printk("\n[ERROR] in %s : target thread %x not found\n", __FUNCTION__, trdid ); 113 #endif 114 joining_ptr->errno = ESRCH; 84 115 return -1; 85 116 } 86 117 87 // get cluster and local pointer on target thread 88 target_ptr = (thread_t *)GET_PTR( target_xp ); 118 // get extended pointers on various fields in target thread 119 target_join_lock_xp = XPTR( target_cxy , &target_ptr->join_lock ); 120 target_flags_xp = XPTR( target_cxy , &target_ptr->flags ); 121 target_blocked_xp = XPTR( target_cxy , &target_ptr->blocked ); 122 target_join_xp_xp = XPTR( target_cxy , &target_ptr->join_xp ); 89 123 90 124 // check target thread joinable 91 target_flags = hal_remote_lw( XPTR( target_cxy , &target_ptr->flags ) ); 92 if( target_flags & THREAD_FLAG_DETACHED ) 125 if( (hal_remote_lw( target_flags_xp ) & THREAD_FLAG_DETACHED) == 0 ) 93 126 { 94 printk("\n[ERROR] in %s : target thread not joinable\n", __FUNCTION__ ); 95 this->errno = EINVAL; 127 128 #if CONFIG_DEBUG_SYSCALLS_ERROR 129 printk("\n[ERROR] in %s : target thread %x not joinable\n", __FUNCTION__, trdid ); 130 #endif 131 joining_ptr->errno = EINVAL; 96 132 return -1; 97 133 } 98 134 99 // check kernel stack overflow 100 if( target_ptr->signature != THREAD_SIGNATURE ) 135 // mask IRQs 136 hal_disable_irq( &save_sr ); 137 138 // get the lock protecting the join in target thread 139 remote_spinlock_lock( target_join_lock_xp ); 140 141 // test the kill_done flag from the target thread 142 if( hal_remote_lw( target_flags_xp ) & THREAD_FLAG_KILL_DONE ) // killer thread is first 101 143 { 102 assert( false , __FUNCTION__ , "kernel stack overflow\n" ); 144 // get pointers on killer thread 145 killer_xp = (xptr_t)hal_remote_lwd( target_join_xp_xp ); 146 147 // reset the kill_done flag in target thread 148 hal_remote_atomic_and( target_flags_xp , ~THREAD_FLAG_KILL_DONE ); 149 150 // unblock the killer thread 151 thread_unblock( killer_xp , THREAD_BLOCKED_JOIN ); 152 153 // release the lock protecting join 154 remote_spinlock_unlock( target_join_lock_xp ); 155 156 // restore IRQs 157 hal_restore_irq( save_sr ); 158 } 159 else // joining thread is first 160 { 161 // set the join_done flag in target thread 162 hal_remote_atomic_or( target_flags_xp , THREAD_FLAG_JOIN_DONE ); 163 164 // block joining thread on BLOCKED_JOIN 165 thread_block( joining_xp , THREAD_BLOCKED_JOIN ); 166 167 // register the joining thread extended pointer in target thread 168 hal_remote_swd( target_join_xp_xp , joining_xp ); 169 170 // release the lock protecting the join 171 remote_spinlock_unlock( target_join_lock_xp ); 172 173 // deschedule 174 sched_yield( "joining thread waiting killer thread" ); 175 176 // restore IRQs 177 hal_restore_irq( save_sr ); 103 178 } 104 179 105 // get the lock protecting the join in target thread 106 remote_spinlock_lock( XPTR( target_cxy , &target_ptr->join_lock ) ); 107 108 // get the blocked bit_vector from the target thread 109 target_blocked = hal_remote_lw( XPTR( target_cxy , &target_ptr->blocked ) ); 110 111 if( target_blocked & THREAD_BLOCKED_JOIN ) // target thread arrived first 112 { 113 // unblock the target thread 114 thread_unblock( target_xp , THREAD_BLOCKED_JOIN ); 115 116 // release the lock protecting flags 117 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) ); 118 119 // get the exit value from target thread 120 *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) ); 121 } 122 else // this thread arrived first 123 { 124 // register this thread extended pointer in target thread 125 hal_remote_swd( XPTR( target_cxy , &target_ptr->join_xp ) , 126 XPTR( local_cxy , this ) ); 127 128 // set the JOIN_DONE flag in target thread 129 hal_remote_atomic_or( XPTR( target_cxy , &target_ptr->flags ) , 130 THREAD_FLAG_JOIN_DONE ); 131 132 // block this thread on BLOCKED_EXIT 133 thread_block( this , THREAD_BLOCKED_EXIT ); 134 135 // release the lock protecting flags 136 remote_spinlock_unlock( XPTR( target_cxy , &target_ptr->join_lock ) ); 137 138 // deschedule 139 sched_yield( "WAITING_EXIT" ); 140 141 // get the exit value from target thread when resume 142 *exit_value = hal_remote_lpt( XPTR( target_cxy , &target_ptr->join_value ) ); 143 } 180 #if CONFIG_DEBUG_SYS_THREAD_JOIN 181 tm_end = hal_get_cycles(); 182 if( CONFIG_DEBUG_SYS_THREAD_JOIN < tm_end ) 183 printk("\n[DBG] %s : parent thread %x exit / process %x / target trdid %x / cycle %d\n", 184 __FUNCTION__, joining_ptr, process->pid, trdid, (uint32_t)tm_end ); 185 #endif 144 186 145 187 return 0; -
trunk/kernel/syscalls/sys_thread_sleep.c
r408 r436 30 30 int sys_thread_sleep() 31 31 { 32 32 33 thread_t * this = CURRENT_THREAD; 33 34 34 thread_dmsg("\n[DBG] %s : thread %x in process %x goes to sleep at cycle %d\n", 35 __FUNCTION__, this->trdid, this->process->pid, hal_get_cycles() ); 35 #if CONFIG_DEBUG_SYS_THREAD_SLEEP 36 uint64_t tm_start; 37 uint64_t tm_end; 38 tm_start = hal_get_cycles(); 39 if( CONFIG_DEBUG_SYS_THREAD_SLEEP < tm_start ) 40 printk("\n[DBG] %s : thread %x blocked / process %x / cycle %d\n", 41 __FUNCTION__ , this, this->process->pid , (uint32_t)tm_start ); 42 #endif 36 43 37 thread_block( this, THREAD_BLOCKED_GLOBAL );44 thread_block( XPTR( local_cxy , this ) , THREAD_BLOCKED_GLOBAL ); 38 45 sched_yield("blocked on sleep"); 39 46 40 thread_dmsg("\n[DBG] %s : thread %x in process %x resume at cycle\n", 41 __FUNCTION__, this->trdid, this->process->pid, hal_get_cycles() ); 47 #if CONFIG_DEBUG_SYS_THREAD_SLEEP 48 tm_end = hal_get_cycles(); 49 if( CONFIG_DEBUG_SYS_THREAD_SLEEP < tm_end ) 50 printk("\n[DBG] %s : thread %x resume / process %x / cycle %d\n", 51 __FUNCTION__ , this, this->process->pid , (uint32_t)tm_end ); 52 #endif 42 53 43 54 return 0; 55 44 56 } // end sys_thread_sleep() -
trunk/kernel/syscalls/sys_thread_wakeup.c
r23 r436 34 34 process_t * process = this->process; 35 35 36 #if CONFIG_DEBUG_SYS_THREAD_WAKEUP 37 uint64_t tm_start; 38 uint64_t tm_end; 39 tm_start = hal_get_cycles(); 40 if( CONFIG_DEBUG_SYS_THREAD_WAKEUP < tm_start ) 41 printk("\n[DBG] %s : thread %x enter / activate thread %x in process %x / cycle %d\n", 42 __FUNCTION__ , this, trdid, this->process->pid, (uint32_t)tm_start ); 43 #endif 44 36 45 // get target thread ltid and cxy 37 46 ltid_t target_ltid = LTID_FROM_TRDID( trdid ); … … 41 50 if( (target_ltid >= CONFIG_THREAD_MAX_PER_CLUSTER) || cluster_is_undefined( target_cxy ) ) 42 51 { 43 printk("\n[ERROR] in %s : illegal trdid argument\n", __FUNCTION__ ); 52 53 #if CONFIG_DEBUG_SISCALLS_ERROR 54 printk("\n[ERROR] in %s : illegal trdid argument %x\n", __FUNCTION__, trdid ); 55 #endif 44 56 this->errno = EINVAL; 45 57 return -1; … … 51 63 if( thread_xp == XPTR_NULL ) 52 64 { 53 printk("\n[ERROR] in %s : cannot find thread %x in process %x/n", 54 __FUNCTION__ , trdid , CURRENT_THREAD->process->pid ); 65 66 #if CONFIG_DEBUG_SISCALLS_ERROR 67 printk("\n[ERROR] in %s : cannot find thread %x in process %x/n", 68 __FUNCTION__ , trdid , this->process->pid ); 69 #endif 55 70 CURRENT_THREAD->errno = EINVAL; 56 71 return -1; … … 60 75 thread_unblock( thread_xp , THREAD_BLOCKED_GLOBAL ); 61 76 77 #if CONFIG_DEBUG_SYS_THREAD_WAKEUP 78 tm_end = hal_get_cycles(); 79 if( CONFIG_DEBUG_SYS_THREAD_WAKEUP < tm_end ) 80 printk("\n[DBG] %s : thread %x exit / thread %x in process %x activated / cycle %d\n", 81 __FUNCTION__ , this, trdid, this->process->pid, (uint32_t)tm_end ); 82 #endif 83 62 84 return 0; 85 63 86 } // end sys_thread_wakeup() -
trunk/kernel/syscalls/sys_wait.c
r435 r436 68 68 __FUNCTION__ , this->trdid , process->pid ); 69 69 #endif 70 this->errno = E FAULT;70 this->errno = EINVAL; 71 71 return -1; 72 72 } 73 73 74 // get process owner cluster 75 cxy_t owner_cxy = CXY_FROM_PID( pid ); 74 // get process owner cluster and calling thread trdid 75 cxy_t owner_cxy = CXY_FROM_PID( pid ); 76 trdid_t trdid = this->trdid; 76 77 77 // This function must be executed in owner cluster78 assert( (owner_cxy == local_cxy) , __FUNCTION__ ,79 "calling thread must execute in owner cluster" );78 // wait must be executed by the main thread 79 if( (owner_cxy != local_cxy) || (LTID_FROM_TRDID(trdid) != 0) ) 80 { 80 81 81 // This function must be executed by the main thread 82 assert( (process->th_tbl[0] == this) , __FUNCTION__ , 83 "this function must be executed by the main thread" ); 84 82 #if CONFIG_DEBUG_SYSCALL_ERROR 83 printk("\n[ERROR] in %s : calling thread %x is not thread 0 in owner cluster %x\n", 84 __FUNCTION__ , trdid , owner_cxy ); 85 #endif 86 this->errno = EINVAL; 87 return -1; 88 } 89 85 90 // get extended pointer on children list root and lock 86 91 xptr_t children_root_xp = XPTR( owner_cxy , &process->children_root ); … … 96 101 remote_spinlock_lock( children_lock_xp ); 97 102 98 // scan the list of ownerchild process103 // scan the list of child process 99 104 XLIST_FOREACH( children_root_xp , iter_xp ) 100 105 { … … 115 120 { 116 121 // get pointer on main thread and PID from child owner process 117 child_pid = (pid_t) hal_remote_lw ( XPTR(child_cxy,&child_ptr->pid)); 118 child_thread = (thread_t *)hal_remote_lpt( XPTR(child_cxy,&child_ptr->th_tbl[0])); 122 child_pid = (pid_t) hal_remote_lw (XPTR( child_cxy , &child_ptr->pid )); 123 child_thread = (thread_t *)hal_remote_lpt(XPTR( child_cxy , 124 &child_ptr->th_tbl[0] )); 119 125 120 126 // set the PROCESS_FLAG_WAIT in owner child descriptor … … 135 141 __FUNCTION__, this, process->pid, child_pid, (uint32_t)tm_end ); 136 142 #endif 137 // return relevant info to callingparent process143 // return child termination state to parent process 138 144 hal_copy_to_uspace( status , &child_state , sizeof(int) ); 139 145 return child_pid; 140 146 } 141 } 147 } // end loop on children 142 148 143 149 // release lock protecting children list -
trunk/kernel/syscalls/syscalls.h
r435 r436 100 100 /****************************************************************************************** 101 101 * [5] This function requests a target thread identified by its <trdid> argument 102 * to be cancelled. Depending on killer thread and target thread location, it calls 103 * the thread_kil() function or the rpc_thread_kill_client() function to do the work. 104 * It actually set the THREAD_SIG_KILL signal, set the THREAD_BLOCKED_GLOBAL bit in the 105 * target thread descriptor and return. 102 * to be cancelled. It calls the thread_kill() function to block the target thread 103 * on the THREAD_BLOCKED_GLOBAL condition, and to set the THREAD_FLAG_REQ_DELETE. 106 104 * The thread will be detached from its process, and the memory allocated to the thread 107 * descriptor will be released later by the scheduler.105 * descriptor will be released by the scheduler at the next scheduling point. 108 106 ****************************************************************************************** 109 107 * @ trdid : thread identifier.
Note: See TracChangeset
for help on using the changeset viewer.