Changeset 407 for trunk/kernel/syscalls/sys_fork.c
- Timestamp:
- Nov 7, 2017, 3:08:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/syscalls/sys_fork.c
r406 r407 24 24 #include <kernel_config.h> 25 25 #include <hal_types.h> 26 #include <hal_context.h> 27 #include <hal_switch.h> 26 28 #include <hal_atomic.h> 27 29 #include <errno.h> … … 45 47 pid_t child_pid; // child process identifier 46 48 thread_t * child_thread; // pointer on child main thread descriptor 47 trdid_t child_trdid; // child main thread identifier 48 lid_t child_core_lid; // core local index for the child main thread 49 cxy_t target_cxy; // final target cluster for forked child process 49 cxy_t target_cxy; // target cluster for forked child process 50 50 error_t error; 51 52 uint64_t tm_start; 53 uint64_t tm_end; 54 55 tm_start = hal_get_cycles(); 51 56 52 57 // get pointers on parent process and thread … … 55 60 parent_pid = parent_process->pid; 56 61 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 ); 64 57 65 // check parent process children number 58 66 if( hal_atomic_add( &parent_process->children_nr , 1 ) >= CONFIG_PROCESS_MAX_CHILDREN ) … … 61 69 hal_atomic_add ( &parent_process->children_nr , -1 ); 62 70 return EAGAIN; 63 }64 65 fork_dmsg("\n[DMSG] %s : enters for process %d at cycle [%d]\n",66 __FUNCTION__, parent_process->pid, hal_get_cycles());67 68 // save FPU state in fpu_context if parent process is FPU owner69 // because we want the child process to share the FPU context70 if( CURRENT_CORE->fpu_owner == parent_thread )71 {72 hal_fpu_context_save( parent_thread );73 fork_dmsg("\n[DMSG] %s : save FPU\n", __FUNCTION__);74 71 } 75 72 … … 95 92 } 96 93 97 fork_dmsg("INFO : %s selecttarget_cluster = %x\n",98 __FUNCTION__, target_cxy );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 ); 99 96 100 97 // allocates memory in local cluster for the child process descriptor … … 127 124 128 125 // initialize and register the child process descriptor 129 process_reference_init( child_process , child_pid , parent_pid ); 130 131 fork_dmsg("\n[DMSG] : %s created child process : pid = %x / ppid = %x\n", 132 __FUNCTION__, child_pid , parent_pid ); 126 process_reference_init( child_process , child_pid , XPTR(local_cxy, parent_process) ); 133 127 134 128 // initialises child process standard files structures … … 148 142 XPTR( local_cxy , &parent_process->fd_array ) ); 149 143 150 fork_dmsg("\n[DMSG] %s : duplicated child process from parent process\n",151 __FUNCTION__);152 153 // replicate s virtual memory manager144 //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 154 148 error = vmm_copy( child_process , parent_process ); 155 149 … … 162 156 } 163 157 164 fork_dmsg("\n[DMSG] %s : parent vmm duplicated in child process\n", __FUNCTION__ ); 165 166 // create child main thread descriptor in local cluster 167 error = thread_user_fork( parent_process , &child_thread ); 168 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 ); 169 168 if( error ) 170 169 { 171 printk("\n[ERROR] in %s : cannot duplicate thread\n", __FUNCTION__ );170 printk("\n[ERROR] in %s : cannot duplicate main thread\n", __FUNCTION__ ); 172 171 hal_atomic_add( &parent_process->children_nr , -1 ); 173 172 process_destroy( child_process ); … … 175 174 } 176 175 177 // register child thread in child process, and get a TRDID 178 spinlock_lock( &child_process->th_lock ); 179 error = process_register_thread( child_process, child_thread , &child_trdid ); 180 spinlock_unlock( &child_process->th_lock ); 181 182 if( error ) 183 { 184 printk("\n[ERROR] in %s : cannot register thread\n", __FUNCTION__ ); 185 hal_atomic_add ( &parent_process->children_nr , -1 ); 186 thread_destroy( child_thread ); 187 process_destroy( child_process ); 188 return EAGAIN; 189 } 190 191 // get a local core to execute child thread 192 child_core_lid = cluster_select_local_core(); 193 194 // Update child thread descriptor 195 child_thread->core = &LOCAL_CLUSTER->core_tbl[child_core_lid]; 196 child_thread->process = child_process; 197 child_thread->trdid = child_trdid; 198 199 fork_dmsg("\n[DMSG] %s : initialised child main thread\n", __FUNCTION__ ); 200 201 // register local child thread into local child process th_tbl[] 202 // we don't use the th_lock because there is no concurrent access 203 ltid_t ltid = LTID_FROM_TRDID( child_trdid ); 204 child_process->th_tbl[ltid] = child_thread; 205 child_process->th_nr = 1; 206 207 // register child thread in scheduler 208 sched_register_thread( child_thread->core , child_thread ); 209 210 fork_dmsg("\n[DMSG] %s : registered main thread in scheduler\n", __FUNCTION__); 176 //printk("\n[DBG] %s : core[%x,%d] initialised child main thread\n", 177 //__FUNCTION__ , local_cxy , parent_thread->core->lid ); 211 178 212 179 // update DQDT for the child thread 213 180 dqdt_local_update_threads( 1 ); 214 181 215 fork_dmsg("\n[DMSG] %s : completed / parent pid = %x / child pid = %x / at cycle [%d]\n", 216 __FUNCTION__, parent_process->pid, child_process->pid, hal_get_cycles() ); 217 218 return child_process->pid; 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 ) 185 { 186 hal_fpu_context_save( child_thread->fpu_context ); 187 } 188 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) ); 193 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 197 198 thread_t * current = CURRENT_THREAD; 199 200 if( current == parent_thread ) 201 { 202 // parent_thread unblock child_thread 203 thread_unblock( XPTR( local_cxy , child_thread ) , THREAD_BLOCKED_GLOBAL ); 204 205 tm_end = hal_get_cycles(); 206 207 fork_dmsg("\n[DBG] %s : core[%x,%d] parent_process %x exit / cycle %d\n" 208 " 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) ); 211 212 return child_pid; 213 } 214 else // current == child_thread 215 { 216 assert( (current == child_thread) , __FUNCTION__ , 217 "current thread %x is not the child thread %x\n", current , child_thread ); 218 219 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() ); 221 222 return 0; 223 } 219 224 220 225 } // end sys_fork()
Note: See TracChangeset
for help on using the changeset viewer.