00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <unistd.h>
00037 #include <stdlib.h>
00038 #include <string.h>
00039 #include <ctype.h>
00040 #include <malloc.h>
00041 #include "omp_thread.h"
00042
00043 #define MAX_COUNTER 20000
00044 volatile int __omp_nested = OMP_NESTED_DEFAULT;
00045 volatile int __omp_dynamic = OMP_DYNAMIC_DEFAULT;
00046
00047 volatile int __omp_max_num_threads = OMP_MAX_NUM_THREADS - 1;
00048
00049 volatile int __omp_nthreads_var;
00050
00051 int __omp_num_processors;
00052
00053 omp_sched_t __omp_rt_sched_type = OMP_SCHED_DEFAULT;
00054 int __omp_rt_sched_size = OMP_CHUNK_SIZE_DEFAULT;
00055
00056 volatile unsigned long int __omp_stack_size = OMP_STACK_SIZE_DEFAULT;
00057
00058 volatile omp_exe_mode_t __omp_exe_mode = OMP_EXE_MODE_DEFAULT;
00059
00060 omp_v_thread_t * __omp_level_1_team = NULL;
00061 omp_u_thread_t * __omp_level_1_pthread = NULL;
00062 int __omp_level_1_team_size = 1;
00063 int __omp_level_1_team_alloc_size = 1;
00064 omp_team_t __omp_level_1_team_manager;
00065 omp_u_thread_t * __omp_uthread_hash_table[UTHREAD_HASH_SIZE];
00066
00067
00068 volatile int __omp_level_1_pthread_count = 1;
00069
00070 volatile int __omp_level_1_exit_count = 0;
00071
00072 omp_team_t __omp_root_team;
00073 omp_u_thread_t * __omp_root_u_thread;
00074 omp_v_thread_t __omp_root_v_thread;
00075 pthread_t __omp_root_thread_id = -1;
00076
00077 int __omp_rtl_initialized = 0;
00078
00079
00080
00081 static pthread_attr_t __omp_pthread_attr;
00082
00083
00084
00085 static pthread_mutex_t __omp_level_1_mutex;
00086 static pthread_cond_t __omp_level_1_cond;
00087
00088 static pthread_mutex_t __omp_level_1_barrier_mutex;
00089 static pthread_cond_t __omp_level_1_barrier_cond;
00090
00091 pthread_mutex_t __omp_hash_table_lock;
00092
00093
00094
00095
00096
00097
00098 void __ompc_environment_variables();
00099 void __ompc_level_1_barrier(const int vthread_id);
00100 void __ompc_exit_barrier(omp_v_thread_t *_v_thread);
00101 void __ompc_fini_rtl();
00102 int __ompc_init_rtl(int num_threads);
00103 int __ompc_expand_level_1_team(int new_num_threads);
00104 void *__ompc_level_1_slave(void *_u_thread_id);
00105 void *__ompc_nested_slave(void *_v_thread);
00106
00107 void
00108 __ompc_environment_variables()
00109 {
00110 char *env_var_str;
00111 int env_var_val;
00112
00113 env_var_str = getenv("OMP_NUM_THREADS");
00114 if (env_var_str != NULL) {
00115 sscanf(env_var_str, "%d", &env_var_val);
00116 Is_Valid(env_var_val > 0, ("OMP_NUM_THREAD should > 0"));
00117 if (env_var_val > __omp_max_num_threads)
00118 env_var_val = __omp_max_num_threads;
00119 __omp_nthreads_var = env_var_val;
00120 }
00121
00122 env_var_str = getenv("OMP_DYNAMIC");
00123 if (env_var_str != NULL) {
00124 env_var_val = strncasecmp(env_var_str, "true", 4);
00125
00126 if (env_var_val == 0) {
00127 __omp_dynamic = 1;
00128 } else {
00129 env_var_val = strncasecmp(env_var_str, "false", 4);
00130 if (env_var_val == 0) {
00131 __omp_dynamic = 0;
00132 } else {
00133 Not_Valid("OMP_DYNAMIC should be set to: true/false");
00134 }
00135 }
00136 }
00137
00138 env_var_str = getenv("OMP_NESTED");
00139 if (env_var_str != NULL) {
00140 env_var_val = strncasecmp(env_var_str, "true", 4);
00141
00142 if (env_var_val == 0) {
00143 __omp_nested = 1;
00144 } else {
00145 env_var_val = strncasecmp(env_var_str, "false", 4);
00146 if (env_var_val == 0) {
00147 __omp_nested = 0;
00148 } else {
00149 Not_Valid("OMP_NESTED should be set to: true/false");
00150 }
00151 }
00152 }
00153
00154 env_var_str = getenv("OMP_SCHEDULE");
00155 if (env_var_str != NULL) {
00156 env_var_str = Trim_Leading_Spaces(env_var_str);
00157 if (strncasecmp(env_var_str, "static", 6) == 0) {
00158 env_var_str += 6;
00159 __omp_rt_sched_type = OMP_SCHED_STATIC;
00160 } else if (strncasecmp(env_var_str,"dynamic",7) == 0) {
00161 env_var_str += 7;
00162 __omp_rt_sched_type = OMP_SCHED_DYNAMIC;
00163 } else if (strncasecmp(env_var_str,"guided",6) == 0) {
00164 env_var_str += 6;
00165 __omp_rt_sched_type = OMP_SCHED_GUIDED;
00166 } else {
00167 Not_Valid("using: OMP_SCHEDULE=\"_schedule_[, _chunk_]\"");
00168 }
00169
00170 env_var_str = Trim_Leading_Spaces(env_var_str);
00171
00172 if (*env_var_str != '\0') {
00173 Is_Valid(*env_var_str == ',',
00174 ("An ',' is expected before the chunksize"));
00175 env_var_str = Trim_Leading_Spaces(++env_var_str);
00176 Is_Valid(isdigit((int)(*env_var_str)),
00177 ("number expected for chunksize"));
00178 sscanf(env_var_str, "%d", &env_var_val);
00179 Is_Valid(env_var_val > 0,
00180 ("Positive number expected"));
00181 __omp_rt_sched_size = env_var_val;
00182 } else {
00183 if(__omp_rt_sched_type == OMP_SCHED_STATIC)
00184 __omp_rt_sched_type = OMP_SCHED_STATIC_EVEN;
00185 }
00186
00187 }
00188
00189
00190 env_var_str = getenv("OMP_SLAVE_STACK_SIZE");
00191 if (env_var_str != NULL) {
00192 char stack_size_unit;
00193 unsigned long int stack_size;
00194 sscanf(env_var_str, "%ld%c", &stack_size, &stack_size_unit);
00195 Is_Valid( stack_size > 0, ("stack size must be positive"));
00196 switch (stack_size_unit) {
00197 case 'k':
00198 case 'K':
00199 stack_size *= 1024;
00200 break;
00201 case 'm':
00202 case 'M':
00203 stack_size *= 1024 * 1024;
00204 break;
00205 case 'g':
00206 case 'G':
00207 stack_size *= 1024 * 1024 * 1024;
00208 break;
00209 default:
00210 Not_Valid("Using _stacksize_[kKmMgG]");
00211 break;
00212 }
00213 if (stack_size < OMP_STACK_SIZE_DEFAULT)
00214 {
00215 Warning("specified a slave stack size less than 4MB, using default.");
00216 }
00217
00218 Is_Valid( stack_size < Get_System_Stack_Limit(),
00219 ("beyond current user stack limit, try using ulimit"));
00220 __omp_stack_size = stack_size;
00221 }
00222 }
00223
00224
00225
00226
00227
00228 void
00229 __ompc_level_1_barrier(const int vthread_id)
00230 {
00231 pthread_mutex_lock(&__omp_level_1_barrier_mutex);
00232 __omp_level_1_exit_count++;
00233 if (vthread_id == 0) {
00234 while (__omp_level_1_exit_count != __omp_level_1_team_size)
00235 pthread_cond_wait(&__omp_level_1_barrier_cond, &__omp_level_1_barrier_mutex);
00236
00237 __omp_level_1_exit_count = 0;
00238 __omp_level_1_team_manager.barrier_flag = 0;
00239 } else if (__omp_level_1_exit_count == __omp_level_1_team_size)
00240 pthread_cond_signal(&__omp_level_1_barrier_cond);
00241 pthread_mutex_unlock(&__omp_level_1_barrier_mutex);
00242 }
00243
00244
00245
00246
00247 void
00248 __ompc_exit_barrier(omp_v_thread_t * vthread)
00249 {
00250
00251 Is_True((vthread != NULL) && (vthread->team != NULL),
00252 ("bad vthread or vthread->team in nested groups"));
00253
00254 pthread_mutex_lock(&(vthread->team->barrier_lock));
00255 vthread->team->barrier_count += 1;
00256 pthread_mutex_unlock(&(vthread->team->barrier_lock));
00257
00258
00259 if(vthread->vthread_id == 0) {
00260 OMPC_WAIT_WHILE(vthread->team->barrier_count != vthread->team->team_size);
00261 }
00262 }
00263
00264
00265 void*
00266 __ompc_level_1_slave(void * _uthread_index)
00267 {
00268 long uthread_index;
00269 int counter;
00270 int task_expect = 1;
00271
00272 uthread_index = (long) _uthread_index;
00273
00274 pthread_mutex_lock(&__omp_level_1_mutex);
00275 __omp_level_1_pthread_count++;
00276 pthread_mutex_unlock(&__omp_level_1_mutex);
00277
00278 for(;;) {
00279 if (__omp_level_1_team_manager.new_task != task_expect) {
00280 for( counter = 0; __omp_level_1_team_manager.new_task != task_expect; counter++) {
00281 if (counter > MAX_COUNTER) {
00282 pthread_mutex_lock(&__omp_level_1_mutex);
00283 while (__omp_level_1_team_manager.new_task != task_expect) {
00284 pthread_cond_wait(&__omp_level_1_cond, &__omp_level_1_mutex);
00285 }
00286 pthread_mutex_unlock(&__omp_level_1_mutex);
00287 counter = 0;
00288 }
00289 }
00290 }
00291
00292 task_expect = !task_expect;
00293
00294
00295
00296
00297
00298
00299
00300 if ( __omp_level_1_team[uthread_index].entry_func != NULL) {
00301 __omp_level_1_team[uthread_index].entry_func(uthread_index,
00302 (char *)__omp_level_1_team[uthread_index].frame_pointer);
00303
00304 __omp_level_1_team[uthread_index].entry_func = NULL;
00305 __ompc_level_1_barrier(uthread_index);
00306
00307 }
00308 }
00309
00310
00311 return NULL;
00312 }
00313
00314
00315 void*
00316 __ompc_nested_slave(void * _v_thread)
00317 {
00318 omp_v_thread_t * my_vthread = (omp_v_thread_t *) _v_thread;
00319
00320
00321 OMPC_WAIT_WHILE(my_vthread->team->new_task != 1);
00322
00323
00324 my_vthread->entry_func(my_vthread->vthread_id,
00325 (char *)my_vthread->frame_pointer);
00326
00327
00328 __ompc_exit_barrier(my_vthread);
00329
00330 pthread_exit(NULL);
00331
00332 }
00333
00334 void
00335 __ompc_fini_rtl(void)
00336 {
00337
00338 if (__omp_level_1_team != NULL)
00339 free(__omp_level_1_team);
00340 if (__omp_level_1_pthread != NULL)
00341 free(__omp_level_1_pthread);
00342
00343
00344
00345 }
00346
00347
00348 int
00349 __ompc_init_rtl(int num_threads)
00350 {
00351 int threads_to_create;
00352 int i;
00353 int return_value;
00354
00355
00356 Is_True(__omp_rtl_initialized == 0,
00357 (" RTL has been initialized yet!"));
00358
00359
00360
00361 __omp_num_processors = Get_SMP_CPU_num();
00362 __omp_nthreads_var = __omp_num_processors;
00363
00364
00365 __ompc_environment_variables();
00366 __ompc_sug_numthreads = __omp_nthreads_var;
00367
00368
00369 atexit(__ompc_fini_rtl);
00370
00371
00372 threads_to_create = num_threads == 0 ? __omp_nthreads_var : num_threads;
00373
00374
00375 pthread_attr_init(&__omp_pthread_attr);
00376 pthread_attr_setscope(&__omp_pthread_attr, PTHREAD_SCOPE_SYSTEM);
00377 pthread_attr_setstacksize(&__omp_pthread_attr, __omp_stack_size);
00378
00379
00380
00381 pthread_mutex_init(&__omp_level_1_mutex, NULL);
00382 pthread_mutex_init(&__omp_level_1_barrier_mutex, NULL);
00383 pthread_mutex_init(&__omp_hash_table_lock, NULL);
00384 pthread_cond_init(&__omp_level_1_cond, NULL);
00385 pthread_cond_init(&__omp_level_1_barrier_cond, NULL);
00386 __ompc_init_lock(&_ompc_thread_lock);
00387
00388
00389 __ompc_clear_hash_table();
00390
00391
00392 __omp_level_1_pthread =
00393 (omp_u_thread_t *) malloc(sizeof(omp_u_thread_t) * threads_to_create);
00394 Is_True(__omp_level_1_pthread != NULL,
00395 ("Can't allocate __omp_level_1_pthread"));
00396 memset(__omp_level_1_pthread, 0, sizeof(omp_u_thread_t) * threads_to_create);
00397
00398 __omp_level_1_team =
00399 (omp_v_thread_t *) malloc(sizeof(omp_v_thread_t) * threads_to_create);
00400 Is_True(__omp_level_1_team != NULL,
00401 ("Can't allocate __omp_level_1_team"));
00402 memset(__omp_level_1_team, 0, sizeof(omp_v_thread_t) * threads_to_create);
00403
00404 __omp_level_1_team_manager.team_size = threads_to_create;
00405 __omp_level_1_team_manager.team_level = 1;
00406 __omp_level_1_team_manager.is_nested = 0;
00407 __omp_level_1_team_manager.barrier_count = 0;
00408 __omp_level_1_team_manager.barrier_flag = 0;
00409 __omp_level_1_team_manager.single_count = 0;
00410 __omp_level_1_team_manager.new_task = 0;
00411 __omp_level_1_team_manager.loop_count = 0;
00412
00413 __ompc_init_lock(&(__omp_level_1_team_manager.schedule_lock));
00414 pthread_cond_init(&(__omp_level_1_team_manager.ordered_cond), NULL);
00415 __ompc_init_lock(&(__omp_level_1_team_manager.single_lock));
00416 pthread_mutex_init(&(__omp_level_1_team_manager.barrier_lock), NULL);
00417 pthread_cond_init(&(__omp_level_1_team_manager.barrier_cond), NULL);
00418
00419
00420 for (i=0; i<threads_to_create; i++) {
00421 __omp_level_1_team[i].team = &__omp_level_1_team_manager;
00422 __omp_level_1_team[i].team_size = threads_to_create;
00423 __omp_level_1_team[i].vthread_id = i;
00424 __omp_level_1_team[i].single_count = 0;
00425 __omp_level_1_team[i].loop_count = 0;
00426
00427 __omp_level_1_team[i].executor = &(__omp_level_1_pthread[i]);
00428 __omp_level_1_pthread[i].task = &(__omp_level_1_team[i]);
00429 }
00430
00431
00432 __omp_root_u_thread = __omp_level_1_pthread;
00433
00434 __omp_root_v_thread.vthread_id = 0;
00435 __omp_root_v_thread.executor = __omp_root_u_thread;
00436 __omp_root_v_thread.team_size = 1;
00437
00438 __omp_root_v_thread.team = &__omp_root_team;
00439
00440 __omp_root_team.team_size = 1;
00441 __omp_root_team.team_level = 0;
00442 __omp_root_team.is_nested = 0;
00443
00444 __omp_root_v_thread.entry_func = NULL;
00445 __omp_root_v_thread.frame_pointer = NULL;
00446
00447 __omp_root_thread_id = pthread_self();
00448
00449 __omp_root_u_thread->uthread_id = __omp_root_thread_id;
00450 __omp_root_u_thread->hash_next = NULL;
00451 __ompc_insert_into_hash_table(__omp_root_u_thread);
00452
00453 for (i=1; i< threads_to_create; i++) {
00454 return_value = pthread_create( &(__omp_level_1_pthread[i].uthread_id),
00455 &__omp_pthread_attr, (pthread_entry) __ompc_level_1_slave,
00456 (void *)((unsigned long int)i));
00457 Is_True(return_value == 0, ("Can not create more pthread"));
00458 __ompc_insert_into_hash_table(&(__omp_level_1_pthread[i]));
00459 }
00460
00461 OMPC_WAIT_WHILE(__omp_level_1_pthread_count != threads_to_create);
00462
00463
00464
00465
00466 __omp_level_1_team_size = threads_to_create;
00467 __omp_level_1_team_alloc_size = threads_to_create;
00468 __omp_max_num_threads -= threads_to_create;
00469 __omp_rtl_initialized = 1;
00470 return threads_to_create;
00471 }
00472
00473
00474
00475
00476 int
00477 __ompc_expand_level_1_team(int new_num_threads)
00478 {
00479 int i;
00480 int return_value;
00481 omp_u_thread_t *new_u_team;
00482 omp_v_thread_t *new_v_team;
00483
00484 new_u_team = (omp_u_thread_t *) realloc((void *) __omp_level_1_pthread,
00485 sizeof(omp_u_thread_t) * new_num_threads);
00486
00487 Is_True(new_u_team != NULL, ("Can not realloc level 1 pthread data structure"));
00488
00489 if (new_u_team != __omp_level_1_pthread) {
00490
00491
00492 __ompc_clear_hash_table();
00493
00494 for (i=0; i<__omp_level_1_team_alloc_size; i++)
00495 __ompc_insert_into_hash_table(&(new_u_team[i]));
00496
00497
00498 __omp_root_u_thread = new_u_team;
00499 __omp_root_v_thread.executor = __omp_root_u_thread;
00500 __omp_level_1_pthread = new_u_team;
00501
00502
00503 for (i=0; i<__omp_level_1_team_alloc_size; i++)
00504 __omp_level_1_team[i].executor = &(__omp_level_1_pthread[i]);
00505
00506 }
00507
00508 new_v_team = (omp_v_thread_t *) realloc((void *) __omp_level_1_team,
00509 sizeof(omp_v_thread_t) * new_num_threads);
00510
00511 Is_True(new_v_team != NULL, ("Can not realloc level 1 team data structure"));
00512
00513 if (new_v_team != __omp_level_1_team) {
00514 __omp_level_1_team = new_v_team;
00515 for (i=0; i<__omp_level_1_team_alloc_size; i++)
00516 __omp_level_1_pthread[i].task = &(__omp_level_1_team[i]);
00517
00518 }
00519
00520 for (i=0; i<new_num_threads; i++) {
00521 __omp_level_1_team[i].team_size = new_num_threads;
00522 }
00523
00524
00525 memset(&(__omp_level_1_team[__omp_level_1_team_alloc_size]), 0,
00526 sizeof(omp_v_thread_t) * (new_num_threads - __omp_level_1_team_alloc_size));
00527 __omp_level_1_team_manager.team_size = new_num_threads;
00528
00529 for (i=__omp_level_1_team_alloc_size; i<new_num_threads; i++) {
00530
00531 __omp_level_1_team[i].team = &__omp_level_1_team_manager;
00532 __omp_level_1_team[i].single_count = 0;
00533 __omp_level_1_team[i].loop_count = 0;
00534 __omp_level_1_team[i].vthread_id = i;
00535 __omp_level_1_team[i].executor = &__omp_level_1_pthread[i];
00536 __omp_level_1_pthread[i].task = &__omp_level_1_team[i];
00537
00538
00539 return_value = pthread_create( &(__omp_level_1_pthread[i].uthread_id),
00540 &__omp_pthread_attr, (pthread_entry) __ompc_level_1_slave,
00541 (void *)((unsigned long int)i));
00542 Is_True(return_value == 0, ("Can not create more pthread"));
00543 __ompc_insert_into_hash_table(&(__omp_level_1_pthread[i]));
00544 }
00545
00546 OMPC_WAIT_WHILE(__omp_level_1_pthread_count != new_num_threads);
00547
00548
00549
00550 __omp_max_num_threads -= new_num_threads - __omp_level_1_team_alloc_size;
00551 __omp_level_1_team_size = new_num_threads;
00552 __omp_level_1_team_alloc_size = new_num_threads;
00553 return new_num_threads;
00554 }
00555
00556
00557 void
00558 __ompc_fork(const int _num_threads, omp_micro micro_task,
00559 frame_pointer_t frame_pointer)
00560 {
00561 int i;
00562 int return_value;
00563 int num_threads = _num_threads;
00564 omp_team_t temp_team;
00565 omp_v_thread_t temp_v_thread;
00566 omp_v_thread_t *nest_v_thread_team;
00567 omp_u_thread_t *nest_u_thread_team;
00568 omp_u_thread_t *current_u_thread;
00569 omp_v_thread_t *original_v_thread;
00570
00571
00572 if ( num_threads !=0) {
00573 num_threads = __ompc_check_num_threads(num_threads);
00574 } else {
00575
00576
00577
00578
00579
00580
00581 }
00582
00583
00584 if (__omp_rtl_initialized == 0 ) {
00585
00586 __ompc_init_rtl(num_threads);
00587 }
00588
00589 if (__omp_exe_mode & OMP_EXE_MODE_SEQUENTIAL) {
00590 __omp_exe_mode = OMP_EXE_MODE_NORMAL;
00591
00592
00593
00594 if (num_threads > __omp_level_1_team_alloc_size) {
00595 Is_True( __omp_max_num_threads >0,
00596 ("reach thread number limit, no more new threads"));
00597 __ompc_expand_level_1_team(num_threads);
00598 } else if(num_threads>0) {
00599 __omp_level_1_team_size = num_threads;
00600 __omp_level_1_team_manager.team_size = num_threads;
00601 } else if (num_threads==0) {
00602
00603 __omp_level_1_team_size = __omp_nthreads_var;
00604 __omp_level_1_team_manager.team_size = __omp_nthreads_var;
00605 }
00606
00607 for (i=0; i<__omp_level_1_team_size; i++) {
00608 __omp_level_1_team[i].frame_pointer = frame_pointer;
00609 __omp_level_1_team[i].team_size = __omp_level_1_team_size;
00610 __omp_level_1_team[i].entry_func = micro_task;
00611 }
00612
00613
00614
00615 if (__omp_level_1_team_size > 1) {
00616
00617 pthread_mutex_lock(&__omp_level_1_mutex);
00618 __omp_level_1_team_manager.new_task = !__omp_level_1_team_manager.new_task;
00619 pthread_cond_broadcast(&__omp_level_1_cond);
00620 pthread_mutex_unlock(&__omp_level_1_mutex);
00621 }
00622
00623 __omp_level_1_pthread[0].task = &(__omp_level_1_team[0]);
00624
00625 micro_task(0, frame_pointer);
00626
00627 __ompc_level_1_barrier(0);
00628 __omp_exe_mode = OMP_EXE_MODE_SEQUENTIAL;
00629 __omp_level_1_pthread[0].task = &__omp_root_v_thread;
00630
00631 } else if (__omp_nested == 1) {
00632
00633
00634
00635
00636 __omp_exe_mode = OMP_EXE_MODE_NESTED;
00637
00638 current_u_thread = __ompc_get_current_u_thread();
00639 original_v_thread = current_u_thread->task;
00640
00641 temp_team.team_size = num_threads;
00642 temp_team.is_nested = 1;
00643 temp_team.team_level = original_v_thread->team->team_level + 1;
00644 temp_team.barrier_count = 0;
00645 temp_team.barrier_flag = 0;
00646 temp_team.new_task = 0;
00647
00648 temp_team.loop_count = 0;
00649 temp_team.single_count = 0;
00650
00651 __ompc_init_lock(&(temp_team.schedule_lock));
00652 pthread_cond_init(&(__omp_level_1_team_manager.ordered_cond), NULL);
00653 __ompc_init_lock(&(temp_team.single_lock));
00654 pthread_mutex_init(&(temp_team.barrier_lock), NULL);
00655 pthread_cond_init(&(temp_team.barrier_cond), NULL);
00656
00657 nest_v_thread_team = (omp_v_thread_t *)malloc(
00658 sizeof(omp_v_thread_t) * num_threads);
00659 Is_True(nest_v_thread_team != NULL,
00660 ("Can't allocate nested v_thread team"));
00661
00662
00663 nest_u_thread_team = (omp_u_thread_t *)malloc(
00664 sizeof(omp_u_thread_t) * num_threads );
00665 Is_True(nest_u_thread_team != NULL,
00666 ("Can't allocate nested u_thread team"));
00667
00668
00669
00670 __omp_max_num_threads -= num_threads - 1;
00671 for (i=1; i<num_threads; i++) {
00672 nest_v_thread_team[i].vthread_id = i;
00673 nest_v_thread_team[i].single_count = 0;
00674 nest_v_thread_team[i].loop_count = 0;
00675 nest_v_thread_team[i].team = &temp_team;
00676 nest_v_thread_team[i].team_size = num_threads;
00677 nest_v_thread_team[i].entry_func = micro_task;
00678 nest_v_thread_team[i].frame_pointer = frame_pointer;
00679 nest_v_thread_team[i].executor = &(nest_u_thread_team[i]);
00680
00681 nest_u_thread_team[i].hash_next = NULL;
00682 nest_u_thread_team[i].task = &(nest_v_thread_team[i]);
00683 return_value = pthread_create(&(nest_u_thread_team[i].uthread_id),
00684 &__omp_pthread_attr, (pthread_entry) __ompc_nested_slave,
00685 (void *)(&(nest_v_thread_team[i])));
00686 Is_True(return_value == 0, ("Can not create more pthread"));
00687 __ompc_insert_into_hash_table(&(nest_u_thread_team[i]));
00688 }
00689
00690 temp_team.new_task = 1;
00691
00692 nest_v_thread_team[0].vthread_id = 0;
00693 nest_v_thread_team[0].single_count = 0;
00694 nest_v_thread_team[0].loop_count = 0;
00695 nest_v_thread_team[0].team = &temp_team;
00696 nest_v_thread_team[0].team_size = num_threads;
00697
00698 nest_v_thread_team[0].entry_func = micro_task;
00699 nest_v_thread_team[0].frame_pointer = frame_pointer;
00700 nest_v_thread_team[0].executor = current_u_thread;
00701 current_u_thread->task = &(nest_v_thread_team[0]);
00702
00703
00704
00705
00706 micro_task(0, frame_pointer);
00707
00708 __ompc_exit_barrier(&(nest_v_thread_team[0]));
00709
00710 for (i=1; i<num_threads; i++) {
00711 __ompc_remove_from_hash_table(nest_u_thread_team[i].uthread_id);
00712 }
00713
00714 free(nest_v_thread_team);
00715 free(nest_u_thread_team);
00716
00717 current_u_thread->task = original_v_thread;
00718
00719
00720 } else {
00721 current_u_thread = __ompc_get_current_u_thread();
00722 original_v_thread = current_u_thread->task;
00723
00724 temp_v_thread.team_size = 1;
00725 temp_v_thread.single_count = 0;
00726 temp_v_thread.loop_count = 0;
00727 temp_v_thread.executor = current_u_thread;
00728 temp_v_thread.team = &temp_team;
00729 temp_v_thread.entry_func = micro_task;
00730 temp_v_thread.frame_pointer = frame_pointer;
00731
00732 temp_team.team_size = 1;
00733 temp_team.team_level = original_v_thread->team->team_level + 1;
00734 temp_team.is_nested = 1;
00735
00736
00737
00738 temp_team.loop_count = 0;
00739 temp_team.single_count = 0;
00740
00741 __ompc_init_lock(&(temp_team.schedule_lock));
00742 __ompc_init_lock(&(temp_team.single_lock));
00743
00744 current_u_thread->task = &temp_v_thread;
00745
00746
00747
00748 __omp_exe_mode = OMP_EXE_MODE_NESTED_SEQUENTIAL;
00749
00750
00751 micro_task(0, frame_pointer);
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761 __ompc_destroy_lock(&(temp_team.schedule_lock));
00762 __ompc_destroy_lock(&(temp_team.single_lock));
00763 }
00764 }
00765
00766
00767
00768
00769
00770 void
00771 __ompc_serialized_parallel (int vthread_id)
00772 {
00773
00774 }
00775
00776 void
00777 __ompc_end_serialized_parallel (int vthread_id)
00778 {
00779
00780 }