Changeset 23 for trunk/kernel/kern/thread.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/thread.c
r16 r23 3 3 * 4 4 * Author Ghassan Almaless (2008,2009,2010,2011,2012) 5 * Mohamed Lamine Karaoui (2015) 6 * Alain Greiner (2016) 5 * Alain Greiner (2016,2017) 7 6 * 8 7 * Copyright (c) UPMC Sorbonne Universites … … 74 73 static thread_t * thread_alloc() 75 74 { 76 page_t * page; 77 kmem_req_t req; 75 page_t * page; // pointer on page descriptor containing thread descriptor 76 kmem_req_t req; // kmem request 78 77 79 78 // allocates memory for thread descriptor + kernel stack … … 84 83 85 84 // return pointer on new thread descriptor 86 if( page == NULL ) 87 { 88 printk("\n[ERROR] in %s : no memory for thread descriptor\n", __FUNCTION__ ); 89 return NULL; 90 } 91 else 92 { 93 return (thread_t *)ppm_page2base( page ); 94 } 95 } // end thread_alloc() 85 if( page == NULL ) return NULL; 86 else return (thread_t *)ppm_page2base( page ); 87 } 88 89 ///////////////////////////////////////////////////////////////////////////////////// 90 // This static function releases the physical memory for a thread descriptor. 91 // It can be called by the three functions: 92 // - thread_user_create() 93 // - thread_user_fork() 94 // - thread_kernel_create() 95 ///////////////////////////////////////////////////////////////////////////////////// 96 // @ thread : pointer on thread descriptor. 97 ///////////////////////////////////////////////////////////////////////////////////// 98 static void thread_release( thread_t * thread ) 99 { 100 kmem_req_t req; 101 102 req.type = KMEM_PAGE; 103 req.ptr = ppm_base2page( thread ); 104 kmem_free( &req ); 105 } 96 106 97 107 ///////////////////////////////////////////////////////////////////////////////////// … … 194 204 195 205 ///////////////////////////////////////////////////////// 196 error_t thread_user_create( thread_t ** new_thread, 206 error_t thread_user_create( pid_t pid, 207 void * start_func, 208 void * start_arg, 197 209 pthread_attr_t * attr, 198 intptr_t u_stack_base, 199 uint32_t u_stack_size ) 210 thread_t ** new_thread ) 200 211 { 201 212 error_t error; … … 203 214 process_t * process; // pointer to local process descriptor 204 215 lid_t core_lid; // selected core local index 205 kmem_req_t req; // kmem request (for release) 206 207 thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ ); 208 209 cluster_t * local_cluster = LOCAL_CLUSTER; 216 vseg_t * vseg; // stack vseg 217 218 thread_dmsg("\n[INFO] %s : enters for process %x\n", __FUNCTION__ , pid ); 219 220 // get process descriptor local copy 221 process = process_get_local_copy( pid ); 222 223 if( process == NULL ) 224 { 225 printk("\n[ERROR] in %s : cannot get process descriptor %x\n", 226 __FUNCTION__ , pid ); 227 return ENOMEM; 228 } 210 229 211 230 // select a target core in local cluster 212 if( attr-> flags & PT_FLAG_CORE_DEFINED ) core_lid = attr->lid;213 else core_lid = cluster_select_local_core();231 if( attr->attributes & PT_ATTR_CORE_DEFINED ) core_lid = attr->lid; 232 else core_lid = cluster_select_local_core(); 214 233 215 234 // check core local index 216 if( core_lid >= local_cluster->cores_nr ) return EINVAL; 217 218 // get process descriptor local copy 219 process = process_get_local_copy( attr->pid ); 220 if( process == NULL ) return ENOMEM; 235 if( core_lid >= LOCAL_CLUSTER->cores_nr ) 236 { 237 printk("\n[ERROR] in %s : illegal core index attribute = %d\n", 238 __FUNCTION__ , core_lid ); 239 240 return EINVAL; 241 } 242 243 // allocate a stack from local VMM 244 vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK ); 245 246 if( vseg == NULL ); 247 { 248 printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ ); 249 return ENOMEM; 250 } 221 251 222 252 // allocates memory tor thread descriptor 223 253 thread = thread_alloc(); 224 254 225 if( thread == NULL ) return ENOMEM; 255 if( thread == NULL ) 256 { 257 printk("\n[ERROR] in %s : cannot create new thread\n", __FUNCTION__ ); 258 vmm_remove_vseg( vseg ); 259 return ENOMEM; 260 } 226 261 227 262 // initializes thread descriptor … … 229 264 process, 230 265 THREAD_USER, 231 attr->entry_func,232 attr->entry_args,266 start_func, 267 start_arg, 233 268 core_lid, 234 u_stack_base,235 u_stack_size);236 237 if( error ) // release allocated memory for thread descriptor238 { 239 req.type = KMEM_PAGE;240 req.ptr = ppm_base2page( thread);241 kmem_free( &req);269 vseg->min, 270 vseg->max - vseg->min ); 271 272 if( error ) 273 { 274 printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ ); 275 vmm_remove_vseg( vseg ); 276 thread_release( thread ); 242 277 return EINVAL; 243 278 } … … 247 282 248 283 // set DETACHED flag if required 249 if( attr-> flags & PT_FLAG_DETACH ) thread->flags |= THREAD_FLAG_DETACHED;284 if( attr->attributes & PT_ATTR_DETACH ) thread->flags |= THREAD_FLAG_DETACHED; 250 285 251 286 // allocate & initialise CPU context 252 287 error = hal_cpu_context_create( thread ); 253 if( error ) return ENOMEM; 288 289 if( error ) 290 { 291 printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ ); 292 vmm_remove_vseg( vseg ); 293 thread_release( thread ); 294 return ENOMEM; 295 } 254 296 255 297 // allocate & initialise FPU context 256 298 error = hal_fpu_context_create( thread ); 257 if( error ) return ENOMEM; 258 299 300 if( error ) 301 { 302 printk("\n[ERROR] in %s : cannot create FPU context\n", __FUNCTION__ ); 303 vmm_remove_vseg( vseg ); 304 thread_release( thread ); 305 return ENOMEM; 306 } 307 259 308 thread_dmsg("\n[INFO] %s : exit / trdid = %x / process %x / core = %d\n", 260 309 __FUNCTION__ , thread->trdid , process->pid , core_lid ); … … 266 315 267 316 268 ///////////////////////////////////////////////// 269 error_t thread_user_fork( thread_t ** new_thread, 270 process_t * process, 271 intptr_t u_stack_base, 272 uint32_t u_stack_size ) 317 ////////////////////////////////////////////// 318 error_t thread_user_fork( process_t * process, 319 thread_t ** new_thread ) 273 320 { 274 321 error_t error; 275 322 thread_t * thread; // pointer on new thread descriptor 276 323 lid_t core_lid; // selected core local index 277 kmem_req_t req; // kmem request (for release)324 vseg_t * vseg; // stack vseg 278 325 279 326 thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ ); 327 328 // allocate a stack from local VMM 329 vseg = vmm_create_vseg( process, 0 , 0 , VSEG_TYPE_STACK ); 330 331 if( vseg == NULL ); 332 { 333 printk("\n[ERROR] in %s : cannot create stack vseg\n", __FUNCTION__ ); 334 return ENOMEM; 335 } 280 336 281 337 // select a target core in local cluster … … 288 344 thread = thread_alloc(); 289 345 290 if( thread == NULL ) return ENOMEM; 346 if( thread == NULL ) 347 { 348 printk("\n[ERROR] in %s : cannot allocate new thread\n", __FUNCTION__ ); 349 vmm_remove_vseg( vseg ); 350 return ENOMEM; 351 } 291 352 292 353 // initializes thread descriptor … … 297 358 this->entry_args, 298 359 core_lid, 299 u_stack_base,300 u_stack_size);301 302 if( error ) // release allocated memory for thread descriptor303 { 304 req.type = KMEM_PAGE;305 req.ptr = ppm_base2page( thread);306 kmem_free( &req);360 vseg->min, 361 vseg->max - vseg->min ); 362 363 if( error ) 364 { 365 printk("\n[ERROR] in %s : cannot initialize new thread\n", __FUNCTION__ ); 366 vmm_remove_vseg( vseg ); 367 thread_release( thread ); 307 368 return EINVAL; 308 369 } … … 313 374 // allocate & initialise CPU context from calling thread 314 375 error = hal_cpu_context_copy( thread , this ); 315 if( error ) return ENOMEM; 376 377 if( error ) 378 { 379 printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ ); 380 vmm_remove_vseg( vseg ); 381 thread_release( thread ); 382 return ENOMEM; 383 } 316 384 317 385 // allocate & initialise FPU context from calling thread 318 386 error = hal_fpu_context_copy( thread , this ); 319 if( error ) return ENOMEM; 320 321 thread_dmsg("INFO : %s thread %x for process %x on core %d in cluster %x\n", 387 388 if( error ) 389 { 390 printk("\n[ERROR] in %s : cannot create CPU context\n", __FUNCTION__ ); 391 vmm_remove_vseg( vseg ); 392 thread_release( thread ); 393 return ENOMEM; 394 } 395 396 thread_dmsg("\n[INFO] %s : exit / thread %x for process %x on core %d in cluster %x\n", 322 397 __FUNCTION__, thread->trdid, process->pid, core_lid, local_cxy ); 323 398 … … 473 548 spinlock_unlock( &process->th_lock ); 474 549 550 // update local DQDT 551 dqdt_local_update_threads( -1 ); 552 475 553 // invalidate thread descriptor 476 554 thread->signature = 0; 477 555 478 556 // release memory for thread descriptor 479 kmem_req_t req; 480 req.type = KMEM_PAGE; 481 req.ptr = ppm_base2page( thread ); 482 kmem_free(&req); 557 thread_release( thread ); 483 558 484 559 tm_end = hal_time_stamp(); … … 706 781 707 782 //////////////////////////////////////////////// 708 void thread_signals_handle r( thread_t * thread )783 void thread_signals_handle( thread_t * thread ) 709 784 { 710 785 // TODO … … 712 787 } 713 788 714 789 ///////////////////////////////////// 790 xptr_t thread_get_xptr( pid_t pid, 791 trdid_t trdid ) 792 { 793 cxy_t target_cxy; // target thread cluster identifier 794 ltid_t target_thread_ltid; // target thread local index 795 thread_t * target_thread_ptr; // target thread local pointer 796 xptr_t target_process_xp; // extended pointer on target process descriptor 797 process_t * target_process_ptr; // local pointer on target process descriptor 798 pid_t target_process_pid; // target process identifier 799 xlist_entry_t root; // root of list of process in target cluster 800 xptr_t lock_xp; // extended pointer on lock protecting this list 801 802 // get target cluster identifier and local thread identifier 803 target_cxy = CXY_FROM_TRDID( trdid ); 804 target_thread_ltid = LTID_FROM_TRDID( trdid ); 805 806 // get root of list of process descriptors in target cluster 807 hal_remote_memcpy( XPTR( local_cxy , &root ), 808 XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_root ), 809 sizeof(xlist_entry_t) ); 810 811 // get extended pointer on lock protecting the list of processes 812 lock_xp = XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_lock ); 813 814 // take the lock protecting the list of processes in target cluster 815 remote_spinlock_lock( lock_xp ); 816 817 // loop on list of process in target cluster to find the PID process 818 xptr_t iter; 819 bool_t found = false; 820 XLIST_FOREACH( XPTR( target_cxy , &LOCAL_CLUSTER->pmgr.local_root ) , iter ) 821 { 822 target_process_xp = XLIST_ELEMENT( iter , process_t , local_list ); 823 target_process_ptr = (process_t *)GET_PTR( target_process_xp ); 824 target_process_pid = hal_remote_lw( XPTR( target_cxy , &target_process_ptr->pid ) ); 825 if( target_process_pid == pid ) 826 { 827 found = true; 828 break; 829 } 830 } 831 832 // release the lock protecting the list of processes in target cluster 833 remote_spinlock_unlock( lock_xp ); 834 835 // check target thread found 836 if( found == false ) 837 { 838 return XPTR_NULL; 839 } 840 841 // get target thread local pointer 842 xptr_t xp = XPTR( target_cxy , &target_process_ptr->th_tbl[target_thread_ltid] ); 843 target_thread_ptr = (thread_t *)hal_remote_lpt( xp ); 844 845 if( target_thread_ptr == NULL ) 846 { 847 return XPTR_NULL; 848 } 849 850 return XPTR( target_cxy , target_thread_ptr ); 851 852 } // end thread_get_xptr() 853
Note: See TracChangeset
for help on using the changeset viewer.