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 #include "libgomp.h"
00028 #include <limits.h>
00029
00030
00031
00032
00033
00034
00035
00036
00037 unsigned
00038 gomp_resolve_num_threads (unsigned specified, unsigned count)
00039 {
00040 struct gomp_thread *thread = gomp_thread();
00041 struct gomp_task_icv *icv;
00042 unsigned threads_requested, max_num_threads, num_threads;
00043 unsigned long remaining;
00044
00045 icv = gomp_icv (false);
00046
00047 if (specified == 1)
00048 return 1;
00049 else if (thread->ts.active_level >= 1 && !icv->nest_var)
00050 return 1;
00051 else if (thread->ts.active_level >= gomp_max_active_levels_var)
00052 return 1;
00053
00054
00055 if (specified == 0)
00056 threads_requested = icv->nthreads_var;
00057 else
00058 threads_requested = specified;
00059
00060 max_num_threads = threads_requested;
00061
00062
00063
00064 if (icv->dyn_var)
00065 {
00066 unsigned dyn = gomp_dynamic_max_threads ();
00067 if (dyn < max_num_threads)
00068 max_num_threads = dyn;
00069
00070
00071 if (count && count < max_num_threads)
00072 max_num_threads = count;
00073 }
00074
00075
00076 if (__builtin_expect (gomp_thread_limit_var == ULONG_MAX, 1)
00077 || max_num_threads == 1)
00078 return max_num_threads;
00079
00080 #ifdef HAVE_SYNC_BUILTINS
00081 do
00082 {
00083 remaining = gomp_remaining_threads_count;
00084 num_threads = max_num_threads;
00085 if (num_threads > remaining)
00086 num_threads = remaining + 1;
00087 }
00088 while (__sync_val_compare_and_swap (&gomp_remaining_threads_count,
00089 remaining, remaining - num_threads + 1)
00090 != remaining);
00091 #else
00092 gomp_mutex_lock (&gomp_remaining_threads_lock);
00093 num_threads = max_num_threads;
00094 remaining = gomp_remaining_threads_count;
00095 if (num_threads > remaining)
00096 num_threads = remaining + 1;
00097 gomp_remaining_threads_count -= num_threads - 1;
00098 gomp_mutex_unlock (&gomp_remaining_threads_lock);
00099 #endif
00100
00101 return num_threads;
00102 }
00103
00104 void
00105 GOMP_parallel_start (void (*fn) (void *), void *data, unsigned num_threads)
00106 {
00107 num_threads = gomp_resolve_num_threads (num_threads, 0);
00108 gomp_team_start (fn, data, num_threads, gomp_new_team (num_threads));
00109 }
00110
00111 void
00112 GOMP_parallel_end (void)
00113 {
00114 if (__builtin_expect (gomp_thread_limit_var != ULONG_MAX, 0))
00115 {
00116 struct gomp_thread *thr = gomp_thread ();
00117 struct gomp_team *team = thr->ts.team;
00118 if (team && team->nthreads > 1)
00119 {
00120 #ifdef HAVE_SYNC_BUILTINS
00121 __sync_fetch_and_add (&gomp_remaining_threads_count,
00122 1UL - team->nthreads);
00123 #else
00124 gomp_mutex_lock (&gomp_remaining_threads_lock);
00125 gomp_remaining_threads_count -= team->nthreads - 1;
00126 gomp_mutex_unlock (&gomp_remaining_threads_lock);
00127 #endif
00128 }
00129 }
00130 gomp_team_end ();
00131 }
00132
00133
00134
00135
00136 int
00137 omp_get_num_threads (void)
00138 {
00139 struct gomp_team *team = gomp_thread ()->ts.team;
00140 return team ? team->nthreads : 1;
00141 }
00142
00143 int
00144 omp_get_thread_num (void)
00145 {
00146 return gomp_thread ()->ts.team_id;
00147 }
00148
00149
00150
00151
00152
00153 int
00154 omp_in_parallel (void)
00155 {
00156 return gomp_thread ()->ts.active_level > 0;
00157 }
00158
00159 int
00160 omp_get_level (void)
00161 {
00162 return gomp_thread ()->ts.level;
00163 }
00164
00165 int
00166 omp_get_ancestor_thread_num (int level)
00167 {
00168 struct gomp_team_state *ts = &gomp_thread ()->ts;
00169 if (level < 0 || level > ts->level)
00170 return -1;
00171 for (level = ts->level - level; level > 0; --level)
00172 ts = &ts->team->prev_ts;
00173 return ts->team_id;
00174 }
00175
00176 int
00177 omp_get_team_size (int level)
00178 {
00179 struct gomp_team_state *ts = &gomp_thread ()->ts;
00180 if (level < 0 || level > ts->level)
00181 return -1;
00182 for (level = ts->level - level; level > 0; --level)
00183 ts = &ts->team->prev_ts;
00184 if (ts->team == NULL)
00185 return 1;
00186 else
00187 return ts->team->nthreads;
00188 }
00189
00190 int
00191 omp_get_active_level (void)
00192 {
00193 return gomp_thread ()->ts.active_level;
00194 }
00195
00196 ialias (omp_get_num_threads)
00197 ialias (omp_get_thread_num)
00198 ialias (omp_in_parallel)
00199 ialias (omp_get_level)
00200 ialias (omp_get_ancestor_thread_num)
00201 ialias (omp_get_team_size)
00202 ialias (omp_get_active_level)