Changeset 433 for trunk/kernel/syscalls
- Timestamp:
- Feb 14, 2018, 3:40:19 PM (7 years ago)
- Location:
- trunk/kernel/syscalls
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_display.c
r421 r433 25 25 #include <hal_uspace.h> 26 26 #include <errno.h> 27 #include <vmm.h> 27 28 #include <cluster.h> 28 29 #include <thread.h> 29 30 #include <process.h> 31 #include <string.h> 30 32 31 33 … … 35 37 reg_t arg1 ) 36 38 { 39 // get thread, process and core 40 thread_t * this = CURRENT_THREAD; 41 process_t * process = this->process; 42 core_t * core = this->core; 43 44 #if CONFIG_DEBUG_SYS_DISPLAY 45 uint64_t tm_start; 46 uint64_t tm_end; 47 tm_start = hal_get_cycles(); 48 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 ); 51 #endif 52 37 53 if( type == DISPLAY_STRING ) 38 54 { 39 55 paddr_t paddr; 40 56 char kbuf[256]; 57 uint32_t length; 41 58 42 59 char * string = (char *)arg0; 43 60 44 61 // check string in user space 45 if( vmm_v2p_translate( false , string , &paddr ) ) return -1; 62 if( vmm_v2p_translate( false , string , &paddr ) ) 63 { 64 printk("\n[ERROR] in %s : string buffer %x unmapped\n", 65 __FUNCTION__ , string ); 66 return -1; 67 } 46 68 47 69 // ckeck string length 48 if( hal_strlen_from_uspace( string ) >= 256 ) return -1; 70 length = hal_strlen_from_uspace( string ); 71 if( length >= 256 ) 72 { 73 printk("\n[ERROR] in %s : string length %d too large\n", 74 __FUNCTION__ , length ); 75 return -1; 76 } 49 77 50 78 // copy string in kernel space 51 79 hal_strcpy_from_uspace( kbuf , string , 256 ); 52 53 // get thread, process and core54 thread_t * this = CURRENT_THREAD;55 process_t * process = this->process;56 core_t * core = this->core;57 80 58 81 // print message on TXT0 kernel terminal … … 60 83 this->trdid , process->pid , local_cxy, core->lid , 61 84 (uint32_t)hal_get_cycles() , kbuf ); 62 63 return 0;64 85 } 65 86 else if( type == DISPLAY_VMM ) … … 70 91 xptr_t process_xp = cluster_get_reference_process_from_pid( pid ); 71 92 72 if( process_xp == XPTR_NULL ) return -1; 93 if( process_xp == XPTR_NULL ) 94 { 95 printk("\n[ERROR] in %s : undefined PID %x\n", 96 __FUNCTION__ , pid ); 97 return -1; 98 } 73 99 74 100 // get cluster and local pointer on process … … 85 111 rpc_vmm_display_client( process_cxy , process_ptr , true ); 86 112 } 87 88 return 0;89 113 } 90 114 else if( type == DISPLAY_SCHED ) … … 94 118 95 119 // check cluster argument 96 if( cluster_is_undefined( cxy ) ) return -1; 120 if( cluster_is_undefined( cxy ) ) 121 { 122 printk("\n[ERROR] in %s : undefined cluster identifier %x\n", 123 __FUNCTION__ , cxy ); 124 return -1; 125 } 97 126 98 127 // check core argument 99 if( lid >= LOCAL_CLUSTER->cores_nr ) return -1; 128 if( lid >= LOCAL_CLUSTER->cores_nr ) 129 { 130 printk("\n[ERROR] in %s : undefined local index %d\n", 131 __FUNCTION__ , lid ); 132 return -1; 133 } 100 134 101 // call kernel function102 135 if( cxy == local_cxy ) 103 136 { … … 108 141 rpc_sched_display_client( cxy , lid ); 109 142 } 110 111 return 0;112 143 } 113 144 else if( type == DISPLAY_PROCESS ) … … 116 147 117 148 // check cluster argument 118 if( cluster_is_undefined( cxy ) ) return -1; 149 if( cluster_is_undefined( cxy ) ) 150 { 151 printk("\n[ERROR] in %s : undefined cluster identifier %x\n", 152 __FUNCTION__ , cxy ); 153 return -1; 154 } 119 155 120 // call kernel function121 156 cluster_processes_display( cxy ); 122 123 return 0;124 157 } 125 158 else if( type == DISPLAY_VFS ) … … 128 161 process_t * process = CURRENT_THREAD->process; 129 162 vfs_display( process->vfs_root_xp ); 130 131 return 0;132 163 } 133 164 else if( type == DISPLAY_CHDEV ) 134 165 { 135 // call kernel function136 166 chdev_dir_display(); 167 } 168 else 169 { 170 printk("\n[ERROR] in %s : undefined display type %x\n", 171 __FUNCTION__ , type ); 172 return -1; 173 } 137 174 138 return 0; 139 } 140 else return -1; 175 #if CONFIG_DEBUG_SYS_DISPLAY 176 tm_end = hal_get_cycles(); 177 if( CONFIG_DEBUG_SYS_DISPLAY < tm_end ) 178 printk("\n[DBG] %s : thread %x exit / process %x / cost = %d / cycle %d\n", 179 __FUNCTION__, this, process->pid, (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end ); 180 #endif 141 181 142 } // end sys_get_sched() 182 return 0; 183 184 } // end sys_display() -
trunk/kernel/syscalls/sys_exec.c
r421 r433 149 149 ///////////////////////////////////////////////////////////////////////////////////////// 150 150 // Implementation note: 151 // This function build an exec_info_t structure containing all informations 151 // This function must be called by the main thread (thread 0 in owner cluster). 152 // IT build an exec_info_t structure containing all informations 152 153 // required to initialize the new process descriptor and the associated thread. 153 // It includes the process PID (unchanged), main() arguments,environment variables,154 // It includes the process main() arguments, the environment variables, 154 155 // and the pathname to the new process .elf file. 155 156 // It calls the process_exec_get_strings() functions to copy the main() arguments and … … 169 170 error_t error; 170 171 171 // get parent processpid172 // get calling thread, process, & pid 172 173 thread_t * this = CURRENT_THREAD; 173 174 process_t * process = this->process; 174 175 pid_t pid = process->pid; 175 176 176 #if CONFIG_SYSCALL_DEBUG 177 assert( (CXY_FROM_PID( pid ) == local_cxy) , __FUNCTION__ , 178 "must be called in the owner cluster\n"); 179 180 assert( (LTID_FROM_TRDID( this->trdid ) == 0) , __FUNCTION__ , 181 "must be called by the main thread\n"); 182 183 assert( (args == NULL) , __FUNCTION__ , 184 "args not supported yet\n" ); 185 186 assert( (envs == NULL) , __FUNCTION__ , 187 "args not supported yet\n" ); 188 189 // get owner cluster 190 191 // check pathname length 192 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 193 { 194 195 #if CONFIG_DEBUG_SYSCALLS_ERROR 196 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); 197 #endif 198 this->errno = ENFILE; 199 return -1; 200 } 201 202 // copy pathname in exec_info structure (kernel space) 203 hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 204 205 #if CONFIG_DEBUG_SYS_EXEC 177 206 uint64_t tm_start; 178 207 uint64_t tm_end; 179 208 tm_start = hal_get_cycles(); 180 printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle = %d\n", 181 __FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)tm_start ); 182 #endif 183 184 // get owner cluster 185 cxy_t owner_cxy = CXY_FROM_PID( pid ); 186 187 // check pathname length 188 if( hal_strlen_from_uspace( pathname ) >= CONFIG_VFS_MAX_PATH_LENGTH ) 189 { 190 printk("\n[ERROR] in %s : pathname too long\n", __FUNCTION__ ); 191 this->errno = ENFILE; 192 return -1; 193 } 194 195 // copy pathname in exec_info structure (kernel space) 196 hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 197 198 // check args argument 199 assert( (args == NULL) , __FUNCTION__ , 200 "args not supported yet\n" ); 201 202 // check envs argument 203 assert( (envs == NULL) , __FUNCTION__ , 204 "args not supported yet\n" ); 209 if( CONFIG_DEBUG_SYS_EXEC < tm_start ) 210 printk("\n[DBG] %s : thread %x enter / process %x / path %s / cycle = %d\n", 211 __FUNCTION__, this, pid, exec_info.path, (uint32_t)tm_start ); 212 #endif 205 213 206 214 // check and store args in exec_info structure if required … … 209 217 if( process_exec_get_strings( &exec_info , true , args ) ) 210 218 { 211 printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ ); 219 220 #if CONFIG_DEBUG_SYSCALLS_ERROR 221 printk("\n[ERROR] in %s : cannot access args\n", __FUNCTION__ ); 222 #endif 212 223 this->errno = error; 213 224 return -1; … … 220 231 if( process_exec_get_strings( &exec_info , false , envs ) ) 221 232 { 222 printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ ); 233 234 #if CONFIG_DEBUG_SYCALLS_ERROR 235 printk("\n[ERROR] in %s : cannot access envs\n", __FUNCTION__ ); 236 #endif 223 237 this->errno = error; 224 238 return -1; … … 226 240 } 227 241 228 // register PID in exec_info 229 exec_info.pid = pid; 230 231 // call process_make_exec (local or remote) 232 if( owner_cxy == local_cxy ) 233 { 234 error = process_make_exec( &exec_info ); 235 } 236 else 237 { 238 rpc_process_make_exec_client( owner_cxy, 239 &exec_info, 240 &error ); 241 } 242 // call relevant kernel function 243 error = process_make_exec( &exec_info ); 242 244 243 245 if( error ) 244 246 { 245 printk("\n[ERROR] in %s : cannot create new process %x in cluster %x\n", 246 __FUNCTION__, pid, owner_cxy ); 247 248 #if CONFIG_DEBUG_SYSCALLS_ERROR 249 printk("\n[ERROR] in %s : cannot create process %x in cluster %x\n", 250 __FUNCTION__, pid, CXY_FROM_PID( pid ); 251 #endif 247 252 this->errno = error; 248 253 return -1; 249 254 } 250 255 251 #if CONFIG_ SYSCALL_DEBUG256 #if CONFIG_DEBUG_SYS_EXEC 252 257 tm_end = hal_get_cycles(); 253 printk("\n[DBG] %s : core[%x,%d] exit / process %x / path = %s / cost = %d / cycle %d\n", 254 __FUNCTION__, local_cxy, this->core->lid, pid, exec_info.path, 255 (uint32_t)(tm_end - tm_start) , (uint32_t)tm_end ); 256 #endif 257 258 return 0; 258 if( CONFIG_DEBUG_SYS_EXEC < tm_end ) 259 printk("\n[DBG] %s : thread %x exit / process %x / cost = %d / cycle %d\n", 260 __FUNCTION__, this, pid, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 261 #endif 262 263 // deschedule <=> old thread suicide because the BLOCKED_GLOBAL 264 // and the FLAG_REQ_DELETE have been set by process_make_exec() 265 sched_yield( "old process suicide in sys_exec()" ); 266 267 assert( false , __FUNCTION__ , "This code should not be executed\n" ); 268 269 return 0; 259 270 260 271 } // end sys_exec() -
trunk/kernel/syscalls/sys_exit.c
r416 r433 36 36 int sys_exit( uint32_t status ) 37 37 { 38 uint32_tsave_sr; // required to enable IRQs38 reg_t save_sr; // required to enable IRQs 39 39 40 thread_t * this = CURRENT_THREAD; 41 pid_t pid = this->process->pid; 40 thread_t * this = CURRENT_THREAD; 41 process_t * process = this->process; 42 pid_t pid = process->pid; 42 43 43 #if CONFIG_ SYSCALL_DEBUG44 #if CONFIG_DEBUG_SYS_EXIT 44 45 uint64_t tm_start; 45 46 uint64_t tm_end; 46 47 tm_start = hal_get_cycles(); 47 printk("\n[DBG] %s : core[%x,%d] enter / process %x / status %x / cycle %d\n", 48 __FUNCTION__ , local_cxy , this->core->lid , pid , status , (uint32_t)tm_start ); 48 if( CONFIG_DEBUG_SYS_EXIT < tm_start ) 49 printk("\n[DBG] %s : thread %x enter / process %x / status %x / cycle %d\n", 50 __FUNCTION__ , this, pid , status , (uint32_t)tm_start ); 49 51 #endif 50 52 51 // get owner process cluster 52 cxy_t owner_cxy = CXY_FROM_PID( pid ); 53 // get cluster and pointers on process in owner cluster 54 xptr_t owner_xp = cluster_get_owner_process_from_pid( pid ); 55 cxy_t owner_cxy = GET_CXY( owner_xp ); 56 process_t * owner_ptr = GET_PTR( owner_xp ); 57 58 assert( (owner_xp != XPTR_NULL) , __FUNCTION__ , "owner_xp cannot be NULL\n" ); 53 59 54 60 // enable IRQs 55 61 hal_enable_irq( &save_sr ); 56 62 57 // execute process_make_exit() function in owner cluster 58 if( local_cxy == owner_cxy ) // owner is local 59 { 60 process_make_exit( pid , status ); 61 } 62 else // owner is remote 63 { 64 rpc_process_make_exit_client( owner_cxy, pid , status ); 65 } 63 // the process_make_kill() function must be executed 64 // by an RPC thread in reference cluster 65 rpc_process_make_kill_client( owner_cxy, owner_ptr, true , status ); 66 66 67 67 // restore IRQs … … 70 70 hal_fence(); 71 71 72 #if CONFIG_ SYSCALL_DEBUG72 #if CONFIG_DEBUG_SYS_EXIT 73 73 tm_end = hal_get_cycles(); 74 printk("\n[DBG] %s : core[%x,%d] exit / process %x / status %x / cost = %d\n", 75 __FUNCTION__ , local_cxy , this->core->lid , pid , status , (uint32_t)(tm_end - tm_start) ); 74 if( CONFIG_DEBUG_SYS_EXIT < tm_end ) 75 printk("\n[DBG] %s : thread %x exit / process %x / status %x / cost = %d / cycle %d\n", 76 __FUNCTION__, this, pid, status, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 76 77 #endif 77 78 -
trunk/kernel/syscalls/sys_fork.c
r416 r433 63 63 parent_pid = parent_process_ptr->pid; 64 64 65 #if CONFIG_ SYSCALL_DEBUG65 #if CONFIG_DEBUG_SYS_FORK 66 66 uint64_t tm_start; 67 67 uint64_t tm_end; 68 68 tm_start = hal_get_cycles(); 69 printk("\n[DBG] %s : core[%x,%d] enter / process %x / cycle = %d\n", 70 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid, parent_pid, 71 (uint32_t)tm_start );69 if( CONFIG_DEBUG_SYS_FORK < tm_start ) 70 printk("\n[DBG] %s : thread %x enter / parent %x / cycle = %d\n", 71 __FUNCTION__, parent_thread_ptr, parent_pid, (uint32_t)tm_start ); 72 72 #endif 73 73 … … 148 148 thread_unblock( XPTR( target_cxy , child_thread_ptr ) , THREAD_BLOCKED_GLOBAL ); 149 149 150 #if CONFIG_ SYSCALL_DEBUG150 #if CONFIG_DEBUG_SYS_FORK 151 151 tm_end = hal_get_cycles(); 152 printk("\n[DBG] %s : core[%x,%d] parent_process %x exit / cost = %d\n", 153 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid, parent_pid, 154 (uint32_t)(tm_end - tm_start));152 if( CONFIG_DEBUG_SYS_FORK < tm_end ) 153 printk("\n[DBG] %s : parent_thread %x exit / cost = %d / cycle %d\n", 154 __FUNCTION__ , parent_thread_ptr, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 155 155 #endif 156 156 … … 160 160 { 161 161 162 #if CONFIG_ SYSCALL_DEBUG162 #if CONFIG_DEBUG_SYS_FORK 163 163 tm_end = hal_get_cycles(); 164 printk("\n[DBG] %s : core[%x,%d] child process %x exit / cost = %d\n", 165 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid, child_pid, 166 (uint32_t)(tm_end - tm_start));164 if( CONFIG_DEBUG_SYS_FORK < tm_end ) 165 printk("\n[DBG] %s : child_thread %x exit / cost = %d / cycle %d\n", 166 __FUNCTION__ , child_thread_ptr, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 167 167 #endif 168 168 -
trunk/kernel/syscalls/sys_kill.c
r421 r433 38 38 { 39 39 uint32_t save_sr; // required to enable IRQs 40 xptr_t process_xp;// extended pointer on target reference process41 cxy_t process_cxy;// target process cluster42 process_t * process_ptr;// local pointer on target process40 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 43 43 xptr_t parent_xp; // extended pointer on parent process 44 44 cxy_t parent_cxy; // parent process cluster 45 45 process_t * parent_ptr; // local pointer on parent process 46 46 pid_t ppid; // parent process PID 47 uint32_t retval; // return value for the switch 47 48 48 49 thread_t * this = CURRENT_THREAD; 49 50 50 #if CONFIG_ SYSCALL_DEBUG51 #if CONFIG_DEBUG_SYS_KILL 51 52 uint64_t tm_start; 52 53 uint64_t tm_end; 53 54 tm_start = hal_get_cycles(); 54 printk("\n[DBG] %s : core[%x,%d] enter / process %x / sig %d / cycle %d\n", 55 __FUNCTION__ , local_cxy , this->core->lid , pid, sig_id, (uint32_t)tm_start ); 55 if( CONFIG_DEBUG_SYS_KILL < tm_start ) 56 printk("\n[DBG] %s : thread %x enter / process %x / sig %d / cycle %d\n", 57 __FUNCTION__ , this, pid, sig_id, (uint32_t)tm_start ); 56 58 #endif 57 59 58 // get cluster and pointers on referenceprocess59 process_xp = cluster_get_reference_process_from_pid( pid );60 process_cxy = GET_CXY( process_xp );61 process_ptr = (process_t *)GET_PTR( process_xp );60 // get cluster and pointers on owner process 61 owner_xp = cluster_get_owner_process_from_pid( pid ); 62 owner_cxy = GET_CXY( owner_xp ); 63 owner_ptr = GET_PTR( owner_xp ); 62 64 63 65 // check process existence 64 if( process_xp == XPTR_NULL )66 if( owner_xp == XPTR_NULL ) 65 67 { 66 syscall_dmsg("\n[ERROR] in %s : process %x not found\n", 67 __FUNCTION__ , pid ); 68 69 syscall_dmsg("\n[ERROR] in %s : process %x not found\n", __FUNCTION__ , pid ); 70 68 71 this->errno = EINVAL; 69 72 return -1; … … 71 74 72 75 // get parent process PID 73 parent_xp = hal_remote_lwd( XPTR( process_cxy , &process_ptr->parent_xp ) );76 parent_xp = hal_remote_lwd( XPTR( owner_cxy , &owner_ptr->parent_xp ) ); 74 77 parent_cxy = GET_CXY( parent_xp ); 75 78 parent_ptr = GET_PTR( parent_xp ); … … 79 82 if( ppid < 2 ) 80 83 { 81 syscall_dmsg("\n[ERROR] in %s : process %x cannot be killed\n",82 __FUNCTION__ , pid );83 this->errno = EINVAL;84 return -1;85 }86 84 87 // does nothing if sig_id == 0 88 if( sig_id == 0 ) return 0; 89 90 // check sig_id 91 if( (sig_id != SIGSTOP) && (sig_id != SIGCONT) && (sig_id != SIGKILL) ) 92 { 93 syscall_dmsg("\n[ERROR] in %s : illegal signal type for process %x\n", 94 __FUNCTION__ , sig_id , pid ); 85 syscall_dmsg("\n[ERROR] in %s : process %x cannot be killed\n", __FUNCTION__ , pid ); 86 95 87 this->errno = EINVAL; 96 88 return -1; … … 100 92 hal_enable_irq( &save_sr ); 101 93 102 // execute process_make_kill() function in owner cluster 103 if( local_cxy == process_cxy ) // owner cluster is local 94 // analyse signal type 95 // supported values are : 0, SIGSTOP, SIGCONT, SIGKILL 96 switch( sig_id ) 104 97 { 105 process_make_kill( pid , sig_id ); 98 case 0 : 99 { 100 // does nothing 101 retval = 0; 102 break; 103 } 104 case SIGSTOP: 105 { 106 // remove TXT ownership from target process 107 process_txt_reset_ownership( owner_xp ); 108 109 // block all threads in all clusters 110 process_sigaction( owner_ptr , BLOCK_ALL_THREADS ); 111 112 // atomically update reference process termination state 113 hal_remote_atomic_or( XPTR( owner_cxy , &owner_ptr->term_state ) , 114 PROCESS_FLAG_BLOCK ); 115 116 retval = 0; 117 break; 118 } 119 case SIGCONT: 120 { 121 // unblock all threads in all clusters 122 process_sigaction( owner_ptr , UNBLOCK_ALL_THREADS ); 123 124 // atomically update reference process termination state 125 hal_remote_atomic_and( XPTR( owner_cxy , &owner_ptr->term_state ) , 126 ~PROCESS_FLAG_BLOCK ); 127 retval = 0; 128 break; 129 } 130 break; 131 case SIGKILL: 132 { 133 // the process_make_kill() function must be executed 134 // by an RPC thread in process owner cluster 135 // It deletes all target process threads in all clusters, 136 // and updates the process termination state 137 rpc_process_make_kill_client( owner_cxy , owner_ptr , false , 0 ); 138 139 retval = 0; 140 break; 141 } 142 default: 143 { 144 145 syscall_dmsg("\n[ERROR] in %s : illegal signal type %d for process %x\n", 146 __FUNCTION__ , sig_id , pid ); 147 148 this->errno = EINVAL; 149 retval = -1; 150 break; 151 } 106 152 } 107 else // owner cluster is remote 108 { 109 rpc_process_make_kill_client( process_cxy , pid , sig_id ); 110 } 111 153 112 154 // restore IRQs 113 155 hal_restore_irq( save_sr ); … … 115 157 hal_fence(); 116 158 117 #if CONFIG_ SYSCALL_DEBUG159 #if CONFIG_DEBUG_SYS_KILL 118 160 tm_end = hal_get_cycles(); 119 printk("\n[DBG] %s : core[%x,%d] exit / process %x / sig %d / cost = %d\n", 120 __FUNCTION__ , local_cxy , this->core->lid , pid, sig_id, (uint32_t)(tm_end - tm_start) ); 161 if( CONFIG_DEBUG_SYS_KILL < tm_end ) 162 printk("\n[DBG] %s : thread %x enter / process %x / sig %d / cost = %d / cycle %d\n", 163 __FUNCTION__ , this, pid, sig_id, (uint32_t)(tm_end - tm_start), (uint32_t)tm_end ); 121 164 #endif 122 123 return 0;165 166 return retval; 124 167 125 168 } // end sys_kill() -
trunk/kernel/syscalls/sys_read.c
r421 r433 65 65 66 66 #if CONFIG_READ_DEBUG 67 enter_sys_read = (uint32_t)tm_start; 68 #endif 69 70 thread_t * this = CURRENT_THREAD; 71 process_t * process = this->process; 72 73 #if CONFIG_DEBUG_SYS_READ 67 74 uint64_t tm_start; 68 75 uint64_t tm_end; 69 76 tm_start = hal_get_cycles(); 70 #endif 71 72 #if CONFIG_READ_DEBUG 73 enter_sys_read = (uint32_t)tm_start; 74 #endif 75 76 thread_t * this = CURRENT_THREAD; 77 process_t * process = this->process; 78 77 if( CONFIG_DEBUG_SYS_READ < tm_start ) 78 printk("\n[DBG] %s : thread %d enter / process %x / vaddr = %x / count %d / cycle %d\n", 79 __FUNCTION__, this, process->pid, vaddr, count, (uint32_t)tm_start ); 80 #endif 81 79 82 // check file_id argument 80 83 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) … … 188 191 hal_fence(); 189 192 190 #if CONFIG_ READ_DEBUG193 #if CONFIG_DEBUG_SYS_READ 191 194 tm_end = hal_get_cycles(); 192 printk("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 195 if( CONFIG_DEBUG_SYS_READ < tm_end ) 196 printk("\n[DBG] %s : thread %x / process %x / cycle %d\n" 193 197 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n", 194 198 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , -
trunk/kernel/syscalls/sys_thread_exit.c
r409 r433 87 87 thread_block( this , THREAD_BLOCKED_JOIN ); 88 88 89 // release the lock protecting the flags89 // release the lock protecting the join 90 90 remote_spinlock_unlock( XPTR( local_cxy, &this->join_lock ) ); 91 91 -
trunk/kernel/syscalls/sys_wait.c
r421 r433 41 41 pid_t child_pid; 42 42 int child_state; 43 thread_t * child_thread; 43 44 44 45 thread_t * this = CURRENT_THREAD; 45 46 process_t * process = this->process; 47 pid_t pid = process->pid; 46 48 47 #if CONFIG_ SYSCALL_DEBUG49 #if CONFIG_DEBUG_SYS_WAIT 48 50 uint64_t tm_start; 49 51 uint64_t tm_end; 50 52 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 , process->pid, (uint32_t)tm_start ); 53 if( CONFIG_DEBUG_SYS_WAIT < tm_start ) 54 printk("\n[DBG] %s : thread %x enter / process %x / cycle %d\n", 55 __FUNCTION__, this, process->pid, (uint32_t)tm_start ); 53 56 #endif 54 57 … … 64 67 } 65 68 66 // get cluster and local pointer on reference process 67 xptr_t ref_xp = process->ref_xp; 68 cxy_t ref_cxy = GET_CXY( ref_xp ); 69 process_t * ref_ptr = GET_PTR( ref_xp ); 69 // get process owner cluster 70 cxy_t owner_cxy = CXY_FROM_PID( pid ); 70 71 71 // get extended pointer on children list root 72 xptr_t root_xp = XPTR( ref_cxy , &ref_ptr->children_root ); 72 // This function must be executed in owner cluster 73 assert( (owner_cxy == local_cxy) , __FUNCTION__ , 74 "calling thread must execute in owner cluster" ); 73 75 74 // get extended pointer on lock protecting the children list 75 xptr_t lock_xp = XPTR( ref_cxy , &ref_ptr->children_lock ); 76 // This function must be executed by the main thread 77 assert( (process->th_tbl[0] == this) , __FUNCTION__ , 78 "this function must be executed by the main thread" ); 79 80 // get extended pointer on children list root and lock 81 xptr_t children_root_xp = XPTR( owner_cxy , &process->children_root ); 82 xptr_t children_lock_xp = XPTR( owner_cxy , &process->children_lock ); 76 83 77 84 // exit this blocking loop only when a child processes change state 78 85 while( 1 ) 79 86 { 80 // get lock 81 remote_spinlock_lock( lock_xp );87 // get lock protecting children list 88 remote_spinlock_lock( children_lock_xp ); 82 89 83 // scan the list of child process84 XLIST_FOREACH( root_xp , iter_xp )90 // scan the list of owner child process 91 XLIST_FOREACH( children_root_xp , iter_xp ) 85 92 { 86 // get child process cluster and local pointer93 // get child process owner cluster and local pointer 87 94 child_xp = XLIST_ELEMENT( iter_xp , process_t , children_list ); 88 95 child_ptr = GET_PTR( child_xp ); 89 96 child_cxy = GET_CXY( child_xp ); 90 97 91 // get t he child PID92 child_ pid = (int)hal_remote_lw( XPTR( child_cxy , &child_ptr->pid ));98 // get term_state from child owner process 99 child_state = (int)hal_remote_lw ( XPTR(child_cxy,&child_ptr->term_state)); 93 100 94 // get the child process state 95 child_state = hal_remote_lw( XPTR( child_cxy , &child_ptr->state ) ); 101 // test if child process is terminated, 102 // but termination not yet reported to parent process 103 if( ((child_state & PROCESS_FLAG_EXIT) || 104 (child_state & PROCESS_FLAG_KILL) || 105 (child_state & PROCESS_FLAG_BLOCK)) && 106 ((child_state & PROCESS_FLAG_WAIT) == 0) ) 107 { 108 // get pointer on main thread and PID from child owner process 109 child_pid = (pid_t) hal_remote_lw ( XPTR(child_cxy,&child_ptr->pid)); 110 child_thread = (thread_t *)hal_remote_lpt( XPTR(child_cxy,&child_ptr->th_tbl[0])); 96 111 97 // check child process state 98 if( child_state != PROCESS_STATE_RUNNING ) 99 { 100 // release lock 101 remote_spinlock_unlock( lock_xp ); 112 // set the PROCESS_FLAG_WAIT in owner child descriptor 113 hal_remote_atomic_or( XPTR( child_cxy , &child_ptr->term_state ), 114 PROCESS_FLAG_WAIT ); 102 115 103 #if CONFIG_SYSCALL_DEBUG 116 // set the THREAD_FLAG_REQ_DELETE in child main thread 117 hal_remote_atomic_or( XPTR( child_cxy , &child_thread->flags ) , 118 THREAD_FLAG_REQ_DELETE ); 119 120 #if CONFIG_DEBUG_SYS_WAIT 104 121 tm_end = hal_get_cycles(); 105 printk("\n[DBG] %s : core[%x,%d] exit / process %x / cost = %d\n", 106 __FUNCTION__ , local_cxy, this->core->lid, process->pid, (uint32_t)(tm_end - tm_start) ); 122 if( CONFIG_DEBUG_SYS_WAIT < tm_end ) 123 printk("\n[DBG] %s : thread %x exit / process %x / cycle %d\n", 124 __FUNCTION__, this, process->pid, (uint32_t)tm_end ); 107 125 #endif 108 126 109 // return relevant info toprocess110 hal_copy_to_uspace( status , &child_state , sizeof(int) );111 return child_pid;127 // return relevant info to calling parent process 128 hal_copy_to_uspace( status , &child_state , sizeof(int) ); 129 return child_pid; 112 130 } 113 131 } 114 132 115 133 // release lock 116 remote_spinlock_unlock( lock_xp );134 remote_spinlock_unlock( children_lock_xp ); 117 135 118 // block the calling thread until a child process change state 119 thread_block( this , THREAD_BLOCKED_WAIT ); 120 sched_yield( "wait child termination" ); 136 // deschedule without blocking 137 sched_yield( "parent wait children termination" ); 121 138 } 122 139 -
trunk/kernel/syscalls/sys_write.c
r421 r433 46 46 reg_t save_sr; // required to enable IRQs during syscall 47 47 48 #if CONFIG_WRITE_DEBUG 48 thread_t * this = CURRENT_THREAD; 49 process_t * process = this->process; 50 51 #if CONFIG_DEBUG_SYS_WRITE 49 52 uint32_t tm_start; 50 53 uint32_t tm_end; 51 54 tm_start = hal_get_cycles(); 55 if( CONFIG_DEBUG_SYS_WRITE < tm_start ) 56 printk("\n[DBG] %s : thread %x / process %x / vaddr %x / count %d / cycle %d\n", 57 __FUNCTION__, this, process->pid, vaddr, count, (uint32_t)tm_start ); 52 58 #endif 53 54 thread_t * this = CURRENT_THREAD;55 process_t * process = this->process;56 59 57 60 // check file_id argument 58 61 if( file_id >= CONFIG_PROCESS_FILE_MAX_NR ) 59 62 { 60 printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ ); 63 64 #if CONFIG_DEBUG_SYSCALLS_ERROR 65 printk("\n[ERROR] in %s : illegal file descriptor index\n", __FUNCTION__ ); 66 #endif 61 67 this->errno = EBADFD; 62 68 return -1; … … 68 74 if ( error ) 69 75 { 70 printk("\n[ERROR] in %s : user buffer unmapped = %x\n", 71 __FUNCTION__ , (intptr_t)vaddr ); 76 77 #if CONFIG_DEBUG_SYSCALLS_ERROR 78 printk("\n[ERROR] in %s : user buffer unmapped = %x\n", __FUNCTION__ , (intptr_t)vaddr ); 79 #endif 72 80 this->errno = EINVAL; 73 81 return -1; … … 82 90 if( file_xp == XPTR_NULL ) 83 91 { 84 printk("\n[ERROR] in %s : undefined file descriptor index = %d in process %x\n", 85 __FUNCTION__ , file_id , process->pid ); 92 93 #if CONFIG_DEBUG_SYSCALLS_ERROR 94 printk("\n[ERROR] in %s : undefined file descriptor index = %d in process %x\n", 95 __FUNCTION__ , file_id , process->pid ); 96 #endif 86 97 this->errno = EBADFD; 87 98 return -1; … … 103 114 if( (attr & FD_ATTR_WRITE_ENABLE) == 0 ) 104 115 { 105 printk("\n[ERROR] in %s : file %d not writable in process %x\n", 106 __FUNCTION__ , file_id , process->pid ); 116 117 #if CONFIG_DEBUG_SYSCALLS_ERROR 118 printk("\n[ERROR] in %s : file %d not writable in process %x\n", 119 __FUNCTION__ , file_id , process->pid ); 120 #endif 107 121 this->errno = EBADFD; 108 122 return -1; … … 131 145 if( nbytes != count ) 132 146 { 133 printk("\n[ERROR] in %s cannot write data to file %d in process %x\n", 134 __FUNCTION__ , file_id , process->pid ); 147 148 #if CONFIG_DEBUG_SYSCALLS_ERROR 149 printk("\n[ERROR] in %s cannot write data to file %d in process %x\n", 150 __FUNCTION__ , file_id , process->pid ); 151 #endif 135 152 this->errno = error; 136 153 return -1; … … 142 159 hal_fence(); 143 160 144 #if CONFIG_ WRITE_DEBUG161 #if CONFIG_DEBUG_SYS_WRITE 145 162 tm_end = hal_get_cycles(); 146 printk("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 163 if( CONFIG_DEBUG_SYS_WRITE < tm_end ) 164 printk("\n[DBG] %s : thread %x in process %x / cycle %d\n" 147 165 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n", 148 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , 149 (uint32_t)tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id , 150 (uint32_t)(tm_end - tm_start) ); 166 __FUNCTION__, this, process->pid, (uint32_t)tm_start, 167 nbytes, *((char *)(intptr_t)paddr) , file_id , (uint32_t)(tm_end - tm_start) ); 151 168 #endif 152 169 153 #if (CONFIG_WRITE_DEBUG & 0x1)154 printk("\n@@@@@@@@@@@@ timing to write character %c\n"155 " - enter_sys_write = %d\n"156 " - exit_sys_write = %d\n",157 *((char *)(intptr_t)paddr) , (uint32_t)tm_start , (uint32_t)tm_end );158 #endif159 160 170 return nbytes; 161 171 -
trunk/kernel/syscalls/syscalls.h
r421 r433 171 171 /****************************************************************************************** 172 172 * [10] This function implement the exit system call terminating a POSIX process. 173 * In the present implementation, this function implements actually the _exit(): 174 * - it does not flush open ourput steams. 175 * - it does not close open streams. 173 176 ****************************************************************************************** 174 177 * @ status : terminaison status (not used in present implementation). … … 421 424 422 425 /****************************************************************************************** 423 * [34] This function implements the "kill" system call .426 * [34] This function implements the "kill" system call on the kernel side. 424 427 * It register the signal defined by the <sig_id> argument in all thread descriptors 425 428 * of a target process identified by the <pid> argument. This is done in all clusters … … 432 435 ****************************************************************************************** 433 436 * @ pid : target process identifier. 434 * @ sig_id : index defining the signal type (from 1 to 31).437 * @ sig_id : index defining the signal type. 435 438 * @ return 0 if success / returns -1 if failure. 436 439 *****************************************************************************************/ … … 439 442 440 443 /****************************************************************************************** 441 * [35] This function implements the "getpid" system call .444 * [35] This function implements the "getpid" system call on the kernel side. 442 445 ****************************************************************************************** 443 446 * @ returns the process PID for the calling thread. … … 446 449 447 450 /****************************************************************************************** 448 * [36] This function implement the "fork" system call .449 * The calling process descriptor (parent process), and the associated thread descriptor are450 * replicated in the same cluster as the calling thread, but the new process (child process)451 * is registered in another target cluster, that is the new process owner.452 * The child process and the associated main thread will be migrated to the target cluster453 * later, when the child process makes an "exec" or any other system call... TODO [AG]451 * [36] This function implement the "fork" system call on the kernel side. 452 * The calling process descriptor (parent process), and the associated thread descriptor 453 * are replicated in a - likely - remote cluster, that becomes the child process owner. 454 * The child process get a new PID, and is linked to the parent PID. The child process 455 * inherit from its parent the memory image, and all open files (including the TXT). 456 * The child process becomes the TXT terminal owner. 454 457 * The target cluster depends on the "fork_user" flag and "fork_cxy" variable that can be 455 458 * stored in the calling thread descriptor by the specific fork_place() system call. 456 * If not, the sys_fork()function makes a query to the DQDT to select the target cluster.459 * If not, the kernel function makes a query to the DQDT to select the target cluster. 457 460 ****************************************************************************************** 458 461 * @ if success, returns child process PID to parent, and return O to child. … … 462 465 463 466 /****************************************************************************************** 464 * [37] This function implement the "exec" system call , that creates a new process465 * descriptor.466 * It is executed in the client cluster, but the new process descriptor and the main467 * thread are created in a server cluster, that is generally another cluster.468 * - if the server_cluster is the client cluster, it calls directly the process_make_exec()469 * function to create a new process, and launch a new thread in local cluster.470 * - if the target_cluster is remote, it calls the rpc_process_exec_client() to execute471 * process_signedmake_exec() on the remote cluster.472 * In both case this function build an exec_info_t structure containing all informations473 * required to build the new process descriptor and the associated thread.474 * Finally, the calling process and thread are deleted.467 * [37] This function implement the "exec" system call on the kernel side. 468 * It creates, in the same cluster as the calling thread, a new process descriptor, 469 * and a new associated main thread descriptor, executing a new memory image defined 470 * by the <filename> argument. This new process inherit from the old process the PID 471 * and the PPID, as well as all open files (including the TXT). 472 * The old process descriptor, and all its threads are blocked, and marked for deletion. 473 * Therefore the exec syscall does not return to the calling thread in case of success. 474 * This function build an exec_info_t structure containing the new process arguments, 475 * as defined by the <arv> argument, and the new process environment variables, 476 * as defined by the <envp> argument. 477 * TODO : the <argv> and <envp> arguments are not supported yet (both must be NULL). 475 478 ****************************************************************************************** 476 479 * @ filename : string pointer on .elf filename (pointer in user space) 477 480 * @ argv : array of strings on process arguments (pointers in user space) 478 481 * @ envp : array of strings on environment variables (pointers in user space) 479 * @ returns Oif success / returns -1 if failure.482 * @ does not return if success / returns -1 if failure. 480 483 *****************************************************************************************/ 481 484 int sys_exec( char * filename, … … 495 498 496 499 /****************************************************************************************** 497 * [39] This blocking function wait a change of a child process state. A changecan be:498 * - a termination of child following a child exit.499 * - a termination of child following a SIGKILL signal.500 * [39] This blocking function waits a change of a child process state, that can be: 501 * - a termination of child following a process_make_exit(). 502 * - a termination of child following a process_make_kill(). 500 503 * - a blocking of child following a SIGSTOP signal. 501 * It returns the PID of the involved child process, after storing in the memory slot 502 * pointed by the <status> argument relevant information on the child state change. 504 * In case of a multi-thread process, this function must be called by the main thread 505 * runningin the reference cluster. 506 * When a change has been observed, it returns the PID of the child process, and stores 507 * in the <status> argument relevant information on the child state change. 503 508 * The following macros can be used to extract information from status: 504 509 * - WIFEXITED(status) : is true if the child process terminated with an exit(). … … 506 511 * - WIFSTOPPED(status) : is true if the child process is stopped by a signal. 507 512 * - WEXITSTATUS(status) : returns the low-order 8 bits of the exit() argument. 508 * A status of 0 indicates a normal termination.509 513 * If a parent process terminates without waiting for all child processes to terminate, 510 514 * the remaining child processes are attached to the init process. 511 ****************************************************************************************** 512 * @ status : pointer on the child PID status. 513 * @ return child PID if success / return -1 if failure. 515 * WARNING: negative values for the <pid> argument are not supported. 516 ****************************************************************************************** 517 * @ searched_pid : searched child process identifier. 518 * @ status : [out] child termination status. 519 * @ return child PID if success / return -1 if searched PID not found. 514 520 *****************************************************************************************/ 515 521 int sys_wait( uint32_t * status );
Note: See TracChangeset
for help on using the changeset viewer.