aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.4.3/libgomp/work.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.4.3/libgomp/work.c')
-rw-r--r--gcc-4.4.3/libgomp/work.c264
1 files changed, 0 insertions, 264 deletions
diff --git a/gcc-4.4.3/libgomp/work.c b/gcc-4.4.3/libgomp/work.c
deleted file mode 100644
index 6bd9c245b..000000000
--- a/gcc-4.4.3/libgomp/work.c
+++ /dev/null
@@ -1,264 +0,0 @@
-/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc.
- Contributed by Richard Henderson <rth@redhat.com>.
-
- 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 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 General Public License for
- more details.
-
- 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.
-
- 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
- <http://www.gnu.org/licenses/>. */
-
-/* This file contains routines to manage the work-share queue for a team
- of threads. */
-
-#include "libgomp.h"
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-/* Allocate a new work share structure, preferably from current team's
- free gomp_work_share cache. */
-
-static struct gomp_work_share *
-alloc_work_share (struct gomp_team *team)
-{
- struct gomp_work_share *ws;
- unsigned int i;
-
- /* This is called in a critical section. */
- if (team->work_share_list_alloc != NULL)
- {
- ws = team->work_share_list_alloc;
- team->work_share_list_alloc = ws->next_free;
- return ws;
- }
-
-#ifdef HAVE_SYNC_BUILTINS
- ws = team->work_share_list_free;
- /* We need atomic read from work_share_list_free,
- as free_work_share can be called concurrently. */
- __asm ("" : "+r" (ws));
-
- if (ws && ws->next_free)
- {
- struct gomp_work_share *next = ws->next_free;
- ws->next_free = NULL;
- team->work_share_list_alloc = next->next_free;
- return next;
- }
-#else
- gomp_mutex_lock (&team->work_share_list_free_lock);
- ws = team->work_share_list_free;
- if (ws)
- {
- team->work_share_list_alloc = ws->next_free;
- team->work_share_list_free = NULL;
- gomp_mutex_unlock (&team->work_share_list_free_lock);
- return ws;
- }
- gomp_mutex_unlock (&team->work_share_list_free_lock);
-#endif
-
- team->work_share_chunk *= 2;
- ws = gomp_malloc (team->work_share_chunk * sizeof (struct gomp_work_share));
- ws->next_alloc = team->work_shares[0].next_alloc;
- team->work_shares[0].next_alloc = ws;
- team->work_share_list_alloc = &ws[1];
- for (i = 1; i < team->work_share_chunk - 1; i++)
- ws[i].next_free = &ws[i + 1];
- ws[i].next_free = NULL;
- return ws;
-}
-
-/* Initialize an already allocated struct gomp_work_share.
- This shouldn't touch the next_alloc field. */
-
-void
-gomp_init_work_share (struct gomp_work_share *ws, bool ordered,
- unsigned nthreads)
-{
- gomp_mutex_init (&ws->lock);
- if (__builtin_expect (ordered, 0))
- {
-#define INLINE_ORDERED_TEAM_IDS_CNT \
- ((sizeof (struct gomp_work_share) \
- - offsetof (struct gomp_work_share, inline_ordered_team_ids)) \
- / sizeof (((struct gomp_work_share *) 0)->inline_ordered_team_ids[0]))
-
- if (nthreads > INLINE_ORDERED_TEAM_IDS_CNT)
- ws->ordered_team_ids
- = gomp_malloc (nthreads * sizeof (*ws->ordered_team_ids));
- else
- ws->ordered_team_ids = ws->inline_ordered_team_ids;
- memset (ws->ordered_team_ids, '\0',
- nthreads * sizeof (*ws->ordered_team_ids));
- ws->ordered_num_used = 0;
- ws->ordered_owner = -1;
- ws->ordered_cur = 0;
- }
- else
- ws->ordered_team_ids = NULL;
- gomp_ptrlock_init (&ws->next_ws, NULL);
- ws->threads_completed = 0;
-}
-
-/* Do any needed destruction of gomp_work_share fields before it
- is put back into free gomp_work_share cache or freed. */
-
-void
-gomp_fini_work_share (struct gomp_work_share *ws)
-{
- gomp_mutex_destroy (&ws->lock);
- if (ws->ordered_team_ids != ws->inline_ordered_team_ids)
- free (ws->ordered_team_ids);
- gomp_ptrlock_destroy (&ws->next_ws);
-}
-
-/* Free a work share struct, if not orphaned, put it into current
- team's free gomp_work_share cache. */
-
-static inline void
-free_work_share (struct gomp_team *team, struct gomp_work_share *ws)
-{
- gomp_fini_work_share (ws);
- if (__builtin_expect (team == NULL, 0))
- free (ws);
- else
- {
- struct gomp_work_share *next_ws;
-#ifdef HAVE_SYNC_BUILTINS
- do
- {
- next_ws = team->work_share_list_free;
- ws->next_free = next_ws;
- }
- while (!__sync_bool_compare_and_swap (&team->work_share_list_free,
- next_ws, ws));
-#else
- gomp_mutex_lock (&team->work_share_list_free_lock);
- next_ws = team->work_share_list_free;
- ws->next_free = next_ws;
- team->work_share_list_free = ws;
- gomp_mutex_unlock (&team->work_share_list_free_lock);
-#endif
- }
-}
-
-/* The current thread is ready to begin the next work sharing construct.
- In all cases, thr->ts.work_share is updated to point to the new
- structure. In all cases the work_share lock is locked. Return true
- if this was the first thread to reach this point. */
-
-bool
-gomp_work_share_start (bool ordered)
-{
- struct gomp_thread *thr = gomp_thread ();
- struct gomp_team *team = thr->ts.team;
- struct gomp_work_share *ws;
-
- /* Work sharing constructs can be orphaned. */
- if (team == NULL)
- {
- ws = gomp_malloc (sizeof (*ws));
- gomp_init_work_share (ws, ordered, 1);
- thr->ts.work_share = ws;
- return ws;
- }
-
- ws = thr->ts.work_share;
- thr->ts.last_work_share = ws;
- ws = gomp_ptrlock_get (&ws->next_ws);
- if (ws == NULL)
- {
- /* This thread encountered a new ws first. */
- struct gomp_work_share *ws = alloc_work_share (team);
- gomp_init_work_share (ws, ordered, team->nthreads);
- thr->ts.work_share = ws;
- return true;
- }
- else
- {
- thr->ts.work_share = ws;
- return false;
- }
-}
-
-/* The current thread is done with its current work sharing construct.
- This version does imply a barrier at the end of the work-share. */
-
-void
-gomp_work_share_end (void)
-{
- struct gomp_thread *thr = gomp_thread ();
- struct gomp_team *team = thr->ts.team;
- gomp_barrier_state_t bstate;
-
- /* Work sharing constructs can be orphaned. */
- if (team == NULL)
- {
- free_work_share (NULL, thr->ts.work_share);
- thr->ts.work_share = NULL;
- return;
- }
-
- bstate = gomp_barrier_wait_start (&team->barrier);
-
- if (gomp_barrier_last_thread (bstate))
- {
- if (__builtin_expect (thr->ts.last_work_share != NULL, 1))
- free_work_share (team, thr->ts.last_work_share);
- }
-
- gomp_team_barrier_wait_end (&team->barrier, bstate);
- thr->ts.last_work_share = NULL;
-}
-
-/* The current thread is done with its current work sharing construct.
- This version does NOT imply a barrier at the end of the work-share. */
-
-void
-gomp_work_share_end_nowait (void)
-{
- struct gomp_thread *thr = gomp_thread ();
- struct gomp_team *team = thr->ts.team;
- struct gomp_work_share *ws = thr->ts.work_share;
- unsigned completed;
-
- /* Work sharing constructs can be orphaned. */
- if (team == NULL)
- {
- free_work_share (NULL, ws);
- thr->ts.work_share = NULL;
- return;
- }
-
- if (__builtin_expect (thr->ts.last_work_share == NULL, 0))
- return;
-
-#ifdef HAVE_SYNC_BUILTINS
- completed = __sync_add_and_fetch (&ws->threads_completed, 1);
-#else
- gomp_mutex_lock (&ws->lock);
- completed = ++ws->threads_completed;
- gomp_mutex_unlock (&ws->lock);
-#endif
-
- if (completed == team->nthreads)
- free_work_share (team, thr->ts.last_work_share);
- thr->ts.last_work_share = NULL;
-}