Changeset 408 for trunk/kernel/syscalls
- Timestamp:
- Dec 5, 2017, 4:20:07 PM (7 years ago)
- Location:
- trunk/kernel/syscalls
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_exec.c
r407 r408 150 150 // Implementation note: 151 151 // This function build an exec_info_t structure containing all informations 152 // required to create the new process descriptor and the associated thread. 152 // required to initialize the new process descriptor and the associated thread. 153 // It includes the process PID (unchanged), main() arguments, environment variables, 154 // and the pathname to the new process .elf file. 153 155 // It calls the process_exec_get_strings() functions to copy the main() arguments and 154 156 // the environment variables from user buffers to the exec_info_t structure, allocate 155 157 // and call the process_make_exec() function. 156 // Finally, it destroys the calling thread and process. 158 // As it must destroy all parent process copies, and all parent threads in all clusters, 159 // the process_make_exec() function must be executed in the parent owner cluster, 160 // and this sys_exec() function uses a RPC to access the owner cluster if required. 161 // 157 162 // TODO : the args & envs arguments are not supported yet : both must be NULL 158 163 ///////////////////////////////////////////////////////////////////////////////////////// … … 169 174 tm_start = hal_get_cycles(); 170 175 171 // get p ointers on parent process and thread176 // get parent process pid 172 177 thread_t * this = CURRENT_THREAD; 173 178 process_t * process = this->process; … … 177 182 __FUNCTION__, local_cxy, this->core->lid, pid, (uint32_t)hal_get_cycles() ); 178 183 179 sched_display( 0 ); 184 // get owner cluster 185 cxy_t owner_cxy = CXY_FROM_PID( pid ); 180 186 181 187 // check pathname length … … 189 195 // copy pathname in exec_info structure (kernel space) 190 196 hal_strcpy_from_uspace( exec_info.path , pathname , CONFIG_VFS_MAX_PATH_LENGTH ); 197 191 198 // check args argument 192 199 assert( (args == NULL) , __FUNCTION__ , … … 196 203 assert( (envs == NULL) , __FUNCTION__ , 197 204 "args not supported yet\n" ); 198 199 // compute client_cxy (local cluster) and server_cxy (target cluster)200 cxy_t cxy_server = CXY_FROM_PID( pid );201 cxy_t cxy_client = local_cxy;202 203 // register parent process in exec_info204 exec_info.parent_xp = process->ref_xp;205 206 // new process keep the parent process PID207 exec_info.keep_pid = true;208 205 209 206 // check and store args in exec_info structure if required … … 229 226 } 230 227 228 // register PID in exec_info 229 exec_info.pid = pid; 230 231 231 // call process_make_exec (local or remote) 232 if( cxy_server == cxy_client)232 if( owner_cxy == local_cxy ) 233 233 { 234 234 error = process_make_exec( &exec_info ); … … 236 236 else 237 237 { 238 rpc_process_exec_client( cxy_server , &exec_info , &error ); 238 rpc_process_make_exec_client( owner_cxy, 239 &exec_info, 240 &error ); 239 241 } 240 242 … … 242 244 { 243 245 printk("\n[ERROR] in %s : cannot create new process %x in cluster %x\n", 244 __FUNCTION__, pid, cxy_server);246 __FUNCTION__, pid, owner_cxy ); 245 247 this->errno = error; 246 248 return -1; 247 249 } 248 249 // FIXME delete the local process descriptor250 // process_kill( process );251 250 252 251 tm_end = hal_get_cycles(); -
trunk/kernel/syscalls/sys_fork.c
r407 r408 41 41 int sys_fork() 42 42 { 43 process_t * parent_process; // pointer on parent process descriptor 44 pid_t parent_pid; // parent process identifier 45 thread_t * parent_thread; // pointer on parent thread descriptor 46 process_t * child_process; // pointer on child process descriptor 47 pid_t child_pid; // child process identifier 48 thread_t * child_thread; // pointer on child main thread descriptor 49 cxy_t target_cxy; // target cluster for forked child process 50 error_t error; 43 process_t * parent_process_ptr; // pointer on local parent process descriptor 44 xptr_t parent_thread_xp; // extended pointer on parent thread descriptor 45 pid_t parent_pid; // parent process identifier 46 thread_t * parent_thread_ptr; // local pointer on local parent thread descriptor 51 47 52 uint64_t tm_start; 53 uint64_t tm_end; 48 pid_t child_pid; // child process identifier 49 thread_t * child_thread_ptr; // local pointer on remote child thread descriptor 50 cxy_t target_cxy; // target cluster for forked child process 51 52 xptr_t ref_process_xp; // extended pointer on reference parent process 53 cxy_t ref_process_cxy; // cluster of reference parent process 54 process_t * ref_process_ptr; // local pointer on reference parent process 55 56 error_t error; 57 58 uint64_t tm_start; 59 uint64_t tm_end; 54 60 55 61 tm_start = hal_get_cycles(); 56 62 57 // get pointers on parent process and thread 58 parent_thread = CURRENT_THREAD; 59 parent_process = parent_thread->process; 60 parent_pid = parent_process->pid; 63 // get pointers on local parent process and thread 64 parent_thread_ptr = CURRENT_THREAD; 65 parent_thread_xp = XPTR( local_cxy , parent_thread_ptr ); 66 parent_process_ptr = parent_thread_ptr->process; 67 parent_pid = parent_process_ptr->pid; 61 68 62 fork_dmsg("\n[DBG] %s : core[%x,%d] enters for process %x/ cycle %d\n",63 __FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid, (uint32_t)tm_start );69 fork_dmsg("\n[DBG] %s : core[%x,%d] parent process %x enters / cycle %d\n", 70 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid, parent_pid, (uint32_t)tm_start ); 64 71 65 // check parent process children number 66 if( hal_atomic_add( &parent_process->children_nr , 1 ) >= CONFIG_PROCESS_MAX_CHILDREN ) 72 // get infos on reference process 73 ref_process_xp = parent_process_ptr->ref_xp; 74 ref_process_cxy = GET_CXY( ref_process_xp ); 75 ref_process_ptr = (process_t *)GET_PTR( ref_process_xp ); 76 77 // check parent process children number from reference 78 xptr_t children_xp = XPTR( ref_process_cxy , &ref_process_ptr->children_nr ); 79 if( hal_remote_atomic_add( children_xp , 1 ) >= CONFIG_PROCESS_MAX_CHILDREN ) 67 80 { 68 81 printk("\n[ERROR] in %s : too much children processes\n", __FUNCTION__); 69 hal_atomic_add ( &parent_process->children_nr , -1 ); 70 return EAGAIN; 82 hal_remote_atomic_add ( children_xp , -1 ); 83 parent_thread_ptr->errno = EAGAIN; 84 return -1; 71 85 } 72 86 73 // Select target cluster for future migration ofchild process and main thread.87 // Select target cluster for child process and main thread. 74 88 // If placement is not user-defined, the placement is defined by the DQDT. 75 // The two first processes ("init" and "sh") on boot cluster do not migrate. 76 77 if( parent_thread->fork_user ) 89 if( parent_thread_ptr->fork_user ) // user defined placement 78 90 { 79 // user defined placement 80 target_cxy = parent_thread->fork_cxy; 81 parent_thread->fork_user = false; 91 target_cxy = parent_thread_ptr->fork_cxy; 92 parent_thread_ptr->fork_user = false; 82 93 } 83 else if( (LPID_FROM_PID(parent_process->pid) < 2) && (local_cxy == 0) ) 84 { 85 // 2 first process stay in boot cluster 86 target_cxy = local_cxy; 87 } 88 else 94 else // DQDT placement 89 95 { 90 // DQDT placement91 96 target_cxy = dqdt_get_cluster_for_process(); 92 97 } 93 98 94 //printk("\n[DBG] %s : core[%x,%d] for process %x selects target_cluster = %x\n", 95 //__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid , target_cxy ); 96 97 // allocates memory in local cluster for the child process descriptor 98 child_process = process_alloc(); 99 100 if( child_process == NULL ) 101 { 102 printk("\n[ERROR] in %s : cannot allocate child process\n", __FUNCTION__ ); 103 hal_atomic_add ( &parent_process->children_nr , -1 ); 104 return EAGAIN; 105 } 106 107 // get a new PID for child process, 108 if( target_cxy == local_cxy ) // target cluster is local 99 // call process_make_fork in target cluster 100 if( target_cxy == local_cxy ) 109 101 { 110 error = cluster_pid_alloc( XPTR( target_cxy , child_process ) , &child_pid ); 102 error = process_make_fork( ref_process_xp, 103 parent_thread_xp, 104 &child_pid, 105 &child_thread_ptr ); 111 106 } 112 else // target cluster is remote107 else 113 108 { 114 rpc_process_pid_alloc_client( target_cxy , child_process , &error , &child_pid ); 109 rpc_process_make_fork_client( target_cxy, 110 ref_process_xp, 111 parent_thread_xp, 112 &child_pid, 113 &child_thread_ptr, 114 &error ); 115 115 } 116 116 117 117 if( error ) 118 118 { 119 printk("\n[ERROR] in %s : cannot allocate PID\n", __FUNCTION__ ); 120 hal_atomic_add ( &parent_process->children_nr , -1);121 p rocess_destroy( child_process );122 return EAGAIN;119 printk("\n[ERROR] in %s : cannot fork process %x in cluster %x\n", 120 __FUNCTION__, parent_pid, local_cxy ); 121 parent_thread_ptr->errno = EAGAIN; 122 return -1; 123 123 } 124 124 125 // initialize and register the child process descriptor 126 process_reference_init( child_process , child_pid , XPTR(local_cxy, parent_process) ); 127 128 // initialises child process standard files structures 129 // ( root / cwd / bin ) from parent process descriptor 130 131 vfs_file_count_up( parent_process->vfs_root_xp ); 132 child_process->vfs_root_xp = parent_process->vfs_root_xp; 133 134 vfs_file_count_up( parent_process->vfs_cwd_xp ); 135 child_process->vfs_cwd_xp = parent_process->vfs_cwd_xp; 136 137 vfs_file_count_up( parent_process->vfs_bin_xp ); 138 child_process->vfs_bin_xp = parent_process->vfs_bin_xp; 139 140 // copy the parent process fd_array to the child process fd_array 141 process_fd_remote_copy( XPTR( local_cxy , &child_process->fd_array ), 142 XPTR( local_cxy , &parent_process->fd_array ) ); 143 144 //printk("\n[DBG] %s : core[%x,%d] for process %x created child process %x\n", 145 //__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid , child_pid ); 146 147 // replicate VMM 148 error = vmm_copy( child_process , parent_process ); 149 150 if( error ) 151 { 152 printk("\n[ERROR] in %s : cannot duplicate VMM\n", __FUNCTION__ ); 153 hal_atomic_add ( &parent_process->children_nr , -1 ); 154 process_destroy( child_process ); 155 return ENOMEM; 156 } 157 158 //printk("\n[DBG] %s : core[%x,%d] for process %x duplicated vmm in child process\n", 159 //__FUNCTION__ , local_cxy , parent_thread->core->lid , parent_pid ); 160 //vmm_display( parent_process , true ); 161 //vmm_display( child_process , true ); 162 163 // create child main thread in local cluster 164 error = thread_user_fork( child_process, 165 parent_thread->u_stack_size, 166 parent_thread->u_stack_base, 167 &child_thread ); 168 if( error ) 169 { 170 printk("\n[ERROR] in %s : cannot duplicate main thread\n", __FUNCTION__ ); 171 hal_atomic_add( &parent_process->children_nr , -1 ); 172 process_destroy( child_process ); 173 return ENOMEM; 174 } 175 176 //printk("\n[DBG] %s : core[%x,%d] initialised child main thread\n", 177 //__FUNCTION__ , local_cxy , parent_thread->core->lid ); 178 179 // update DQDT for the child thread 180 dqdt_local_update_threads( 1 ); 181 182 // set child_thread FPU_context from parent_thread register values 183 // only when the parent process is the FPU owner 184 if( CURRENT_THREAD->core->fpu_owner == parent_thread ) 125 // set remote child FPU_context from parent_thread register values 126 // only when the parent thread is the FPU owner 127 if( CURRENT_THREAD->core->fpu_owner == parent_thread_ptr ) 185 128 { 186 hal_fpu_context_save( child_thread->fpu_context);129 hal_fpu_context_save( XPTR( target_cxy , child_thread_ptr ) ); 187 130 } 188 131 189 // set child_thread CPU context from parent_thread register values 190 hal_do_cpu_save( child_thread->cpu_context, 191 child_thread, 192 (int)((intptr_t)child_thread - (intptr_t)parent_thread) ); 132 // set remote child CPU context from parent_thread register values 133 hal_cpu_context_fork( XPTR( target_cxy , child_thread_ptr ) ); 193 134 194 195 // from this point, both parent and child threads execute the following code 196 // but child execute it only when it has been unblocked by its parent 135 // From this point, both parent and child threads execute the following code. 136 // They can be distinguished by the CURRENT_THREAD value, and child will only 137 // execute it when it is unblocked by parent. 138 // - parent unblock child, and return child PID to user application. 139 // - child thread does nothing, and return 0 to user pplication 197 140 198 141 thread_t * current = CURRENT_THREAD; 199 142 200 if( current == parent_thread )143 if( current == parent_thread_ptr ) // current == parent thread 201 144 { 202 145 // parent_thread unblock child_thread 203 thread_unblock( XPTR( local_cxy , child_thread) , THREAD_BLOCKED_GLOBAL );146 thread_unblock( XPTR( target_cxy , child_thread_ptr ) , THREAD_BLOCKED_GLOBAL ); 204 147 205 148 tm_end = hal_get_cycles(); … … 207 150 fork_dmsg("\n[DBG] %s : core[%x,%d] parent_process %x exit / cycle %d\n" 208 151 " child_process %x / child_thread = %x / cost = %d\n", 209 __FUNCTION__, local_cxy, parent_thread ->core->lid, parent_pid, (uint32_t)tm_start,210 child_pid, child_thread ->trdid , (uint32_t)(tm_end - tm_start) );152 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid, parent_pid, (uint32_t)tm_end, 153 child_pid, child_thread_ptr->trdid , (uint32_t)(tm_end - tm_start) ); 211 154 212 155 return child_pid; 213 156 } 214 else // current == child_thread157 else // current == child_thread 215 158 { 216 assert( (current == child_thread) , __FUNCTION__ , 217 "current thread %x is not the child thread %x\n", current , child_thread);159 160 tm_end = hal_get_cycles(); 218 161 219 162 fork_dmsg("\n[DBG] %s : core[%x,%d] child process %x exit / cycle %d\n", 220 __FUNCTION__, local_cxy, parent_thread ->core->lid, child_pid, (uint32_t)hal_get_cycles());163 __FUNCTION__, local_cxy, parent_thread_ptr->core->lid, child_pid, (uint32_t)tm_end ); 221 164 222 165 return 0; -
trunk/kernel/syscalls/sys_get_cycle.c
r407 r408 48 48 { 49 49 printk("\n[ERROR] in %s : user buffer unmapped for thread %x in process %x\n", 50 50 __FUNCTION__ , this->trdid , process->pid ); 51 51 this->errno = EFAULT; 52 52 return -1; -
trunk/kernel/syscalls/sys_read.c
r407 r408 61 61 xptr_t file_xp; // remote file extended pointer 62 62 uint32_t nbytes; // number of bytes actually read 63 63 reg_t save_sr; // required to enable IRQs during syscall 64 64 uint32_t tm_start; 65 65 uint32_t tm_end; … … 93 93 return -1; 94 94 } 95 96 // enable IRQs 97 hal_enable_irq( &save_sr ); 95 98 96 99 // get extended pointer on remote file descriptor … … 150 153 return -1; 151 154 } 155 156 // restore IRQs 157 hal_restore_irq( save_sr ); 152 158 153 159 hal_fence(); … … 190 196 #endif 191 197 192 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / nbytes = %d/ cycle %d\n"193 " first byte = %c / file_id = %d / cost = %d\n",194 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , nbytes , tm_start,195 *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start );198 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 199 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n", 200 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , 201 tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start ); 196 202 197 203 return nbytes; -
trunk/kernel/syscalls/sys_signal.c
r407 r408 33 33 void * handler ) 34 34 { 35 thread_t * this = CURRENT_THREAD;35 thread_t * this = CURRENT_THREAD; 36 36 37 printk("\n[ERROR] in %s : not implemented yet\n", __FUNCTION__ ); 38 this->errno = EINVAL; 39 return -1; 40 37 41 if((sig_id == 0) || (sig_id >= SIG_NR) || (sig_id == SIGKILL) || (sig_id == SIGSTOP)) 38 42 { -
trunk/kernel/syscalls/sys_thread_exit.c
r407 r408 73 73 74 74 // deschedule 75 sched_yield( );75 sched_yield("waiting parent join"); 76 76 } 77 77 } -
trunk/kernel/syscalls/sys_thread_join.c
r407 r408 138 138 139 139 // deschedule 140 sched_yield( );140 sched_yield("waiting child exit"); 141 141 } 142 142 } -
trunk/kernel/syscalls/sys_thread_sleep.c
r407 r408 36 36 37 37 thread_block( this , THREAD_BLOCKED_GLOBAL ); 38 sched_yield( );38 sched_yield("blocked on sleep"); 39 39 40 40 thread_dmsg("\n[DBG] %s : thread %x in process %x resume at cycle\n", -
trunk/kernel/syscalls/sys_thread_yield.c
r407 r408 27 27 int sys_thread_yield() 28 28 { 29 sched_yield( );29 sched_yield("user request"); 30 30 return 0; 31 31 } -
trunk/kernel/syscalls/sys_write.c
r407 r408 40 40 { 41 41 error_t error; 42 paddr_t paddr; 43 xptr_t file_xp; 44 uint32_t nbytes; 45 42 paddr_t paddr; // unused, but required for user space checking 43 xptr_t file_xp; // remote file extended pointer 44 uint32_t nbytes; // number of bytes actually written 45 reg_t save_sr; // required to enable IRQs during syscall 46 46 uint32_t tm_start; 47 47 uint32_t tm_end; … … 70 70 return -1; 71 71 } 72 73 // enable IRQs 74 hal_enable_irq( &save_sr ); 72 75 73 76 // get extended pointer on remote file descriptor … … 128 131 } 129 132 133 // restore IRQs 134 hal_restore_irq( save_sr ); 135 130 136 hal_fence(); 131 137 132 138 tm_end = hal_get_cycles(); 133 139 134 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x / nbytes = %d/ cycle %d\n"135 " first byte = %c / file_id = %d / cost = %d\n",136 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , nbytes , tm_start,137 *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start );140 syscall_dmsg("\n[DBG] %s : core[%x,%d] / thread %x in process %x / cycle %d\n" 141 "nbytes = %d / first byte = %c / file_id = %d / cost = %d\n", 142 __FUNCTION__ , local_cxy , this->core->lid , this->trdid , this->process->pid , 143 tm_start , nbytes , *((char *)(intptr_t)paddr) , file_id , tm_end - tm_start ); 138 144 139 145 return nbytes; -
trunk/kernel/syscalls/syscalls.h
r407 r408 41 41 * terminating thread. 42 42 ****************************************************************************************** 43 * @ exit_vallue : pointer to be returned to parent thread if th ead is attached.43 * @ exit_vallue : pointer to be returned to parent thread if thread is attached. 44 44 * @ return 0 if success / return -1 if failure. 45 45 *****************************************************************************************/ … … 154 154 155 155 /****************************************************************************************** 156 * [10] This slot not allocated yet 157 ****************************************************************************************** 158 * @ return 0 if success / returns -1 if failure. 159 *****************************************************************************************/ 160 161 /****************************************************************************************** 162 * [11] This function rmove an existing mapping defined by the <addr> and <size> 156 * [10] This function implement the exit system call terminating a POSIX process. 157 ****************************************************************************************** 158 * @ status : terminaison status (not used in present implementation). 159 *****************************************************************************************/ 160 void sys_exit( uint32_t status ); 161 162 /****************************************************************************************** 163 * [11] This function remove an existing mapping defined by the <addr> and <size> 163 164 * arguments in user space. 164 165 ****************************************************************************************** … … 194 195 * [14] This function read bytes from an open file identified by its file descriptor. 195 196 * The file can be a regular file or character oriented device. 197 * IRQs are enabled during this system call. 196 198 ****************************************************************************************** 197 199 * @ file_id : open file index in fd_array. … … 207 209 * [15] This function writes bytes to an open file identified by its file descriptor. 208 210 * The file can be a regular file or character oriented device. 211 * IRQs are enabled during this system call. 209 212 ****************************************************************************************** 210 213 * @ file_id : open file index in fd_array.
Note: See TracChangeset
for help on using the changeset viewer.