X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libgomp%2Ftask.c;h=4b75850072bb450ff6f55ff16e1dd51c20d000e4;hb=dfca10ff9293bf42ae17cd904c9b45d9fcbb59ab;hp=ce991b8dca26198e9ea76fd08c83a94cfbbfdb24;hpb=9ead5ba09452820435a61778a944899a0254e021;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libgomp/task.c b/libgomp/task.c index ce991b8dca2..4b75850072b 100644 --- a/libgomp/task.c +++ b/libgomp/task.c @@ -1,29 +1,26 @@ -/* Copyright (C) 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2007, 2008, 2009, 2011 Free Software Foundation, Inc. Contributed by Richard Henderson . This file is part of the GNU OpenMP Library (libgomp). Libgomp is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU Lesser General Public License - along with libgomp; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301, USA. */ + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. -/* As a special exception, if you link this library with other files, some - of which are compiled with GCC, to produce an executable, this library - does not by itself cause the resulting executable to be covered by the - GNU General Public License. This exception does not however invalidate - any other reasons why the executable file might be covered by the GNU - General Public License. */ + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ /* This file handles the maintainence of tasks in response to task creation and termination. */ @@ -44,6 +41,7 @@ gomp_init_task (struct gomp_task *task, struct gomp_task *parent_task, task->kind = GOMP_TASK_IMPLICIT; task->in_taskwait = false; task->in_tied_task = false; + task->final_task = false; task->children = NULL; gomp_sem_init (&task->taskwait_sem, 0); } @@ -80,8 +78,7 @@ gomp_clear_parent (struct gomp_task *children) void GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *), - long arg_size, long arg_align, bool if_clause, - unsigned flags __attribute__((unused))) + long arg_size, long arg_align, bool if_clause, unsigned flags) { struct gomp_thread *thr = gomp_thread (); struct gomp_team *team = thr->ts.team; @@ -98,12 +95,14 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *), #endif if (!if_clause || team == NULL + || (thr->task && thr->task->final_task) || team->task_count > 64 * team->nthreads) { struct gomp_task task; gomp_init_task (&task, thr->task, gomp_icv (false)); task.kind = GOMP_TASK_IFFALSE; + task.final_task = (thr->task && thr->task->final_task) || (flags & 2); if (thr->task) task.in_tied_task = thr->task->in_tied_task; thr->task = &task; @@ -117,10 +116,11 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *), } else fn (data); - if (task.children) + if (team != NULL) { gomp_mutex_lock (&team->task_lock); - gomp_clear_parent (task.children); + if (task.children != NULL) + gomp_clear_parent (task.children); gomp_mutex_unlock (&team->task_lock); } gomp_end_task (); @@ -148,6 +148,7 @@ GOMP_task (void (*fn) (void *), void *data, void (*cpyfn) (void *, void *), task->fn = fn; task->fn_data = arg; task->in_tied_task = true; + task->final_task = (flags & 2) >> 1; gomp_mutex_lock (&team->task_lock); if (parent->children) { @@ -273,6 +274,7 @@ gomp_barrier_handle_tasks (gomp_barrier_state_t state) gomp_team_barrier_done (&team->barrier, state); gomp_mutex_unlock (&team->task_lock); gomp_team_barrier_wake (&team->barrier, 0); + gomp_mutex_lock (&team->task_lock); } } } @@ -289,8 +291,9 @@ GOMP_taskwait (void) struct gomp_task *child_task = NULL; struct gomp_task *to_free = NULL; - if (task == NULL || task->children == NULL) + if (task == NULL || team == NULL) return; + gomp_mutex_lock (&team->task_lock); while (1) { @@ -365,3 +368,20 @@ GOMP_taskwait (void) } } } + +/* Called when encountering a taskyield directive. */ + +void +GOMP_taskyield (void) +{ + /* Nothing at the moment. */ +} + +int +omp_in_final (void) +{ + struct gomp_thread *thr = gomp_thread (); + return thr->task && thr->task->final_task; +} + +ialias (omp_in_final)