1169695Skan/* Copyright (C) 2005 Free Software Foundation, Inc. 2169695Skan Contributed by Richard Henderson <rth@redhat.com>. 3169695Skan 4169695Skan This file is part of the GNU OpenMP Library (libgomp). 5169695Skan 6169695Skan Libgomp is free software; you can redistribute it and/or modify it 7169695Skan under the terms of the GNU Lesser General Public License as published by 8169695Skan the Free Software Foundation; either version 2.1 of the License, or 9169695Skan (at your option) any later version. 10169695Skan 11169695Skan Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY 12169695Skan WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13169695Skan FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 14169695Skan more details. 15169695Skan 16169695Skan You should have received a copy of the GNU Lesser General Public License 17169695Skan along with libgomp; see the file COPYING.LIB. If not, write to the 18169695Skan Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 19169695Skan MA 02110-1301, USA. */ 20169695Skan 21169695Skan/* As a special exception, if you link this library with other files, some 22169695Skan of which are compiled with GCC, to produce an executable, this library 23169695Skan does not by itself cause the resulting executable to be covered by the 24169695Skan GNU General Public License. This exception does not however invalidate 25169695Skan any other reasons why the executable file might be covered by the GNU 26169695Skan General Public License. */ 27169695Skan 28169695Skan/* This file handles the (bare) PARALLEL construct. */ 29169695Skan 30169695Skan#include "libgomp.h" 31169695Skan 32169695Skan 33169695Skan/* Determine the number of threads to be launched for a PARALLEL construct. 34169695Skan This algorithm is explicitly described in OpenMP 2.5 section 2.4.1. 35169695Skan SPECIFIED is a combination of the NUM_THREADS clause and the IF clause. 36169695Skan If the IF clause is false, SPECIFIED is forced to 1. When NUM_THREADS 37169695Skan is not present, SPECIFIED is 0. */ 38169695Skan 39169695Skanunsigned 40169695Skangomp_resolve_num_threads (unsigned specified) 41169695Skan{ 42169695Skan /* Early exit for false IF condition or degenerate NUM_THREADS. */ 43169695Skan if (specified == 1) 44169695Skan return 1; 45169695Skan 46169695Skan /* If this is a nested region, and nested regions are disabled, force 47169695Skan this team to use only one thread. */ 48169695Skan if (gomp_thread()->ts.team && !gomp_nest_var) 49169695Skan return 1; 50169695Skan 51169695Skan /* If NUM_THREADS not specified, use nthreads_var. */ 52169695Skan if (specified == 0) 53169695Skan specified = gomp_nthreads_var; 54169695Skan 55169695Skan /* If dynamic threads are enabled, bound the number of threads 56169695Skan that we launch. */ 57169695Skan if (gomp_dyn_var) 58169695Skan { 59169695Skan unsigned dyn = gomp_dynamic_max_threads (); 60169695Skan if (dyn < specified) 61169695Skan return dyn; 62169695Skan } 63169695Skan 64169695Skan return specified; 65169695Skan} 66169695Skan 67169695Skanvoid 68169695SkanGOMP_parallel_start (void (*fn) (void *), void *data, unsigned num_threads) 69169695Skan{ 70169695Skan num_threads = gomp_resolve_num_threads (num_threads); 71169695Skan gomp_team_start (fn, data, num_threads, NULL); 72169695Skan} 73169695Skan 74169695Skanvoid 75169695SkanGOMP_parallel_end (void) 76169695Skan{ 77169695Skan gomp_team_end (); 78169695Skan} 79169695Skan 80169695Skan 81169695Skan/* The public OpenMP API for thread and team related inquiries. */ 82169695Skan 83169695Skanint 84169695Skanomp_get_num_threads (void) 85169695Skan{ 86169695Skan struct gomp_team *team = gomp_thread ()->ts.team; 87169695Skan return team ? team->nthreads : 1; 88169695Skan} 89169695Skan 90169695Skan/* ??? Does this function need to disregard dyn_var? I don't see 91169695Skan how else one could get a useable "maximum". */ 92169695Skan 93169695Skanint 94169695Skanomp_get_max_threads (void) 95169695Skan{ 96169695Skan return gomp_resolve_num_threads (0); 97169695Skan} 98169695Skan 99169695Skanint 100169695Skanomp_get_thread_num (void) 101169695Skan{ 102169695Skan return gomp_thread ()->ts.team_id; 103169695Skan} 104169695Skan 105169695Skan/* ??? This isn't right. The definition of this function is false if any 106169695Skan of the IF clauses for any of the parallels is false. Which is not the 107169695Skan same thing as any outer team having more than one thread. */ 108169695Skan 109169695Skanint omp_in_parallel (void) 110169695Skan{ 111169695Skan struct gomp_team *team = gomp_thread ()->ts.team; 112169695Skan 113169695Skan while (team) 114169695Skan { 115169695Skan if (team->nthreads > 1) 116169695Skan return true; 117169695Skan team = team->prev_ts.team; 118169695Skan } 119169695Skan 120169695Skan return false; 121169695Skan} 122169695Skan 123169695Skanialias (omp_get_num_threads) 124169695Skanialias (omp_get_max_threads) 125169695Skanialias (omp_get_thread_num) 126169695Skanialias (omp_in_parallel) 127