Changeset 14 for trunk/kernel/kern/thread.c
- Timestamp:
- May 3, 2017, 1:23:24 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/thread.c
r5 r14 24 24 */ 25 25 26 #include < almos_config.h>26 #include <kernel_config.h> 27 27 #include <hal_types.h> 28 28 #include <hal_context.h> … … 76 76 77 77 ///////////////////////////////////////////////////////////////////////////////////// 78 // This static function makes the actual allocation and initialisation for a thread79 // descriptor. It iscalled by the three functions:78 // This static function allocates physical memory for a thread descriptor. 79 // It can be called by the three functions: 80 80 // - thread_user_create() 81 // - thread_user_ copy()81 // - thread_user_fork() 82 82 // - thread_kernel_create() 83 83 ///////////////////////////////////////////////////////////////////////////////////// 84 // @ new_thread : buffer for new thread pointer. 85 // @ process : local pointer on process descriptor. 86 // @ type : thread type. 87 // @ func : local pointer on thread entry function. 88 // @ args : local pointer on thread entry function arguments. 89 // @ core_lid : target core local index. 84 // @ return pointer on thread descriptor if success / return NULL if failure. 90 85 ///////////////////////////////////////////////////////////////////////////////////// 91 static error_t thread_create( thread_t ** new_thread, 92 process_t * process, 93 thread_type_t type, 94 void * func, 95 void * args, 96 lid_t core_lid, 97 intptr_t u_stack_base, 98 uint32_t u_stack_size ) 99 { 100 error_t error; 101 thread_t * thread; // pointer on thread descriptor 86 static thread_t * thread_alloc() 87 { 102 88 page_t * page; // pointer on page descriptor containing thread descriptor 103 89 kmem_req_t req; // kmem request 104 trdid_t trdid; // allocated thread identifier105 106 cluster_t * local_cluster = LOCAL_CLUSTER;107 90 108 91 // allocates memory for thread descriptor + kernel stack 109 92 req.type = KMEM_PAGE; 110 req.size = CONFIG_THREAD_ PAGE_ORDER;93 req.size = CONFIG_THREAD_DESC_ORDER; 111 94 req.flags = AF_KERNEL | AF_ZERO; 112 95 page = kmem_alloc( &req ); 113 if( page == NULL ) return ENOMEM; 114 115 // get pointer on new thread descriptor 116 thread = (thread_t *)ppm_page2base( page ); 117 118 // register new thread in local process descriptor, and get a TRDID 96 97 // return pointer on new thread descriptor 98 if( page == NULL ) 99 { 100 printk("\n[ERROR] in %s : no memory for thread descriptor\n", __FUNCTION__ ); 101 return NULL; 102 } 103 else 104 { 105 return (thread_t *)ppm_page2base( page ); 106 } 107 } // end thread_alloc() 108 109 ///////////////////////////////////////////////////////////////////////////////////// 110 // This static function initializes a thread descriptor (kernel or user). 111 // It can be called by the four functions: 112 // - thread_user_create() 113 // - thread_user_fork() 114 // - thread_kernel_create() 115 // - thread_user_init() 116 ///////////////////////////////////////////////////////////////////////////////////// 117 // @ thread : pointer on thread descriptor 118 // @ process : pointer on process descriptor. 119 // @ type : thread type. 120 // @ func : pointer on thread entry function. 121 // @ args : pointer on thread entry function arguments. 122 // @ core_lid : target core local index. 123 // @ u_stack_base : stack base (user thread only) 124 // @ u_stack_size : stack base (user thread only) 125 ///////////////////////////////////////////////////////////////////////////////////// 126 static error_t thread_init( thread_t * thread, 127 process_t * process, 128 thread_type_t type, 129 void * func, 130 void * args, 131 lid_t core_lid, 132 intptr_t u_stack_base, 133 uint32_t u_stack_size ) 134 { 135 error_t error; 136 trdid_t trdid; // allocated thread identifier 137 138 cluster_t * local_cluster = LOCAL_CLUSTER; 139 140 // register new thread in process descriptor, and get a TRDID 119 141 spinlock_lock( &process->th_lock ); 120 142 error = process_register_thread( process, thread , &trdid ); … … 123 145 if( error ) 124 146 { 125 // release allocated memory for thread descriptor 126 req.type = KMEM_PAGE; 127 req.ptr = page; 128 kmem_free( &req ); 129 return EAGAIN; 130 } 131 147 printk("\n[ERROR] in %s : cannot get TRDID\n", __FUNCTION__ ); 148 return EINVAL; 149 } 150 132 151 // Initialize new thread descriptor 133 152 thread->trdid = trdid; … … 138 157 thread->core = &local_cluster->core_tbl[core_lid]; 139 158 thread->process = process; 140 thread->page = page;141 159 142 160 thread->local_locks = 0; … … 149 167 thread->u_stack_size = u_stack_size; 150 168 thread->k_stack_base = (intptr_t)thread; 151 thread->k_stack_size = CONFIG_ PPM_PAGE_SIZE << CONFIG_THREAD_PAGE_ORDER;169 thread->k_stack_size = CONFIG_THREAD_DESC_SIZE; 152 170 153 171 thread->entry_func = func; // thread entry point … … 182 200 sched_register_thread( thread->core , thread ); 183 201 184 *new_thread = thread;185 202 return 0; 186 } // end thread_create() 203 204 } // end thread_init() 187 205 188 206 … … 197 215 process_t * process; // pointer to local process descriptor 198 216 lid_t core_lid; // selected core local index 199 200 thread_dmsg("\n[INFO] %s : enters\n", 201 217 kmem_req_t req; // kmem request (for release) 218 219 thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ ); 202 220 203 221 cluster_t * local_cluster = LOCAL_CLUSTER; … … 214 232 if( process == NULL ) return ENOMEM; 215 233 216 // make allocation / initialisation 217 error = thread_create( &thread, 218 process, 219 THREAD_USER, 220 attr->entry_func, 221 attr->entry_args, 222 core_lid, 223 u_stack_base, 224 u_stack_size ); 225 if( error ) return ENOMEM; 226 227 // set LOADABLE flag / set ATTACHED flag if required 234 // allocates memory tor thread descriptor 235 thread = thread_alloc(); 236 237 if( thread == NULL ) return ENOMEM; 238 239 // initializes thread descriptor 240 error = thread_init( thread, 241 process, 242 THREAD_USER, 243 attr->entry_func, 244 attr->entry_args, 245 core_lid, 246 u_stack_base, 247 u_stack_size ); 248 249 if( error ) // release allocated memory for thread descriptor 250 { 251 req.type = KMEM_PAGE; 252 req.ptr = ppm_base2page( thread ); 253 kmem_free( &req ); 254 return EINVAL; 255 } 256 257 // set LOADABLE flag 228 258 thread->flags = THREAD_FLAG_LOADABLE; 259 260 // set DETACHED flag if required 229 261 if( attr->flags & PT_FLAG_DETACH ) thread->flags |= THREAD_FLAG_DETACHED; 230 262 … … 242 274 *new_thread = thread; 243 275 return 0; 276 244 277 } // end thread_user_create() 245 278 … … 252 285 { 253 286 error_t error; 254 thread_t * new; // pointer onthread descriptor287 thread_t * thread; // pointer on new thread descriptor 255 288 lid_t core_lid; // selected core local index 256 257 thread_dmsg("\n[INFO] %s : enters\n", 258 289 kmem_req_t req; // kmem request (for release) 290 291 thread_dmsg("\n[INFO] %s : enters\n", __FUNCTION__ ); 259 292 260 293 // select a target core in local cluster … … 264 297 thread_t * this = CURRENT_THREAD; 265 298 266 // make allocation / initialisation 267 error = thread_create( &new, 268 process, 269 THREAD_USER, 270 this->entry_func, 271 this->entry_args, 272 core_lid, 273 u_stack_base, 274 u_stack_size ); 299 // allocated memory for new thread descriptor 300 thread = thread_alloc(); 301 302 if( thread == NULL ) return ENOMEM; 303 304 // initializes thread descriptor 305 error = thread_init( thread, 306 process, 307 THREAD_USER, 308 this->entry_func, 309 this->entry_args, 310 core_lid, 311 u_stack_base, 312 u_stack_size ); 313 314 if( error ) // release allocated memory for thread descriptor 315 { 316 req.type = KMEM_PAGE; 317 req.ptr = ppm_base2page( thread ); 318 kmem_free( &req ); 319 return EINVAL; 320 } 321 322 // set ATTACHED flag if set in this thread 323 if( this->flags & THREAD_FLAG_DETACHED ) thread->flags = THREAD_FLAG_DETACHED; 324 325 // allocate & initialise CPU context from calling thread 326 error = hal_cpu_context_copy( thread , this ); 275 327 if( error ) return ENOMEM; 276 328 277 // set ATTACHED flag if set in this thread 278 if( this->signals & THREAD_FLAG_DETACHED ) new->signals = THREAD_FLAG_DETACHED; 279 280 // allocate & initialise CPU context from calling thread 281 error = hal_cpu_context_copy( new , this ); 329 // allocate & initialise FPU context from calling thread 330 error = hal_fpu_context_copy( thread , this ); 282 331 if( error ) return ENOMEM; 283 332 284 // allocate & initialise FPU context from calling thread285 error = hal_fpu_context_copy( new , this );286 if( error ) return ENOMEM;287 288 333 thread_dmsg("INFO : %s thread %x for process %x on core %d in cluster %x\n", 289 __FUNCTION__, new->trdid, process->pid, core_lid, local_cxy );290 291 *new_thread = new;334 __FUNCTION__, thread->trdid, process->pid, core_lid, local_cxy ); 335 336 *new_thread = thread; 292 337 return 0; 293 338 … … 304 349 { 305 350 error_t error; 306 thread_t * new; // pointer on new thread descriptor 307 308 thread_dmsg("\n[INFO] %s : enters for %s in cluster %x\n", 351 thread_t * thread; // pointer on new thread descriptor 352 kmem_req_t req; // kmem request (for release) 353 354 thread_dmsg("\n[INFO] %s : enters for type %s in cluster %x\n", 309 355 __FUNCTION__ , thread_type_str( type ) , local_cxy ); 310 356 … … 316 362 __FUNCTION__ , "illegal core_lid" ); 317 363 318 // make allocation / initialisation 319 error = thread_create( &new, 320 &process_zero, 321 type, 322 func, 323 args, 324 core_lid, 325 0 , 0 ); // no user stack for a kernel thread 326 if( error ) 327 { 328 printk("\n[ERROR] in %s : cannot create thread\n", __FUNCTION__ ); 329 return ENOMEM; 330 } 364 // allocated memory for new thread descriptor 365 thread = thread_alloc(); 366 367 if( thread == NULL ) return ENOMEM; 368 369 // initializes thread descriptor 370 error = thread_init( thread, 371 &process_zero, 372 type, 373 func, 374 args, 375 core_lid, 376 0 , 0 ); // no user stack for a kernel thread 377 378 if( error ) // release allocated memory for thread descriptor 379 { 380 req.type = KMEM_PAGE; 381 req.ptr = ppm_base2page( thread ); 382 kmem_free( &req ); 383 return EINVAL; 384 } 385 331 386 332 387 // allocate & initialise CPU context 333 hal_cpu_context_create( new);334 335 thread_dmsg("\n[INFO] %s : sucessfully exit / trdid = %x / core= %d\n",336 __FUNCTION__ , new->trdid , core_lid );337 338 *new_thread = new;388 hal_cpu_context_create( thread ); 389 390 thread_dmsg("\n[INFO] %s : exit in cluster %x / trdid = %x / core_lid = %d\n", 391 __FUNCTION__ , local_cxy , thread->trdid , core_lid ); 392 393 *new_thread = thread; 339 394 return 0; 340 395 341 396 } // end thread_kernel_create() 342 397 398 /////////////////////////////////////////////////// 399 error_t thread_kernel_init( thread_t * thread, 400 thread_type_t type, 401 void * func, 402 void * args, 403 lid_t core_lid ) 404 { 405 assert( ( (type == THREAD_KERNEL) || (type == THREAD_RPC) || 406 (type == THREAD_IDLE) || (type == THREAD_DEV) ) , 407 __FUNCTION__ , "illegal thread type" ); 408 409 if( core_lid >= LOCAL_CLUSTER->cores_nr ) 410 { 411 printk("\n[PANIC] in %s : illegal core_lid / cores = %d / lid = %d / cxy = %x\n", 412 __FUNCTION__ , LOCAL_CLUSTER->cores_nr , core_lid , local_cxy ); 413 hal_core_sleep(); 414 } 415 416 error_t error = thread_init( thread, 417 &process_zero, 418 type, 419 func, 420 args, 421 core_lid, 422 0 , 0 ); // no user stack for a kernel thread 423 424 // allocate & initialize CPU context if success 425 if( error == 0 ) hal_cpu_context_create( thread ); 426 427 return error; 428 429 } // end thread_kernel_init() 343 430 344 431 /////////////////////////////////////////////////////////////////////////////////////// … … 592 679 593 680 594 ///////////////////////// 595 void * thread_idle_func() 596 { 681 /////////////////////// 682 void thread_idle_func() 683 { 684 lid_t lid = CURRENT_CORE->lid; 685 597 686 while( 1 ) 598 687 { 599 thread_dmsg("\n[INFO] %s : core %d in cluster %x goes to sleeping state at cycle\n",600 __FUNCTION__ , core->lid , local_cxy, hal_time_stamp() );688 thread_dmsg("\n[INFO] %s : core[%x][%d] goes to sleep at cycle %d\n", 689 __FUNCTION__ , local_cxy , lid , hal_time_stamp() ); 601 690 602 691 // force core to sleeping state 603 692 hal_core_sleep(); 604 693 605 thread_dmsg("\n[INFO] %s : core %d in cluster %x wake up at cycle %d\n", 606 __FUNCTION__ , core->lid , local_cxy , hal_time_stamp() ); 607 608 // force scheduling at wake-up 694 thread_dmsg("\n[INFO] %s : core[%x][%d] wake up at cycle %d\n", 695 __FUNCTION__ , local_cxy , lid , hal_time_stamp() ); 696 697 // acknowledge IRQ 698 dev_icu_irq_handler(); 699 700 // force scheduling 609 701 sched_yield(); 610 702 }
Note: See TracChangeset
for help on using the changeset viewer.