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 #include <limits.h>
00030 #include "wait.h"
00031
00032
00033 void
00034 gomp_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
00035 {
00036 if (__builtin_expect ((state & 1) != 0, 0))
00037 {
00038
00039 bar->awaited = bar->total;
00040 atomic_write_barrier ();
00041 bar->generation += 4;
00042 futex_wake ((int *) &bar->generation, INT_MAX);
00043 }
00044 else
00045 {
00046 unsigned int generation = state;
00047
00048 do
00049 do_wait ((int *) &bar->generation, generation);
00050 while (bar->generation == generation);
00051 }
00052 }
00053
00054 void
00055 gomp_barrier_wait (gomp_barrier_t *bar)
00056 {
00057 gomp_barrier_wait_end (bar, gomp_barrier_wait_start (bar));
00058 }
00059
00060
00061
00062
00063
00064
00065
00066
00067 void
00068 gomp_barrier_wait_last (gomp_barrier_t *bar)
00069 {
00070 gomp_barrier_state_t state = gomp_barrier_wait_start (bar);
00071 if (state & 1)
00072 gomp_barrier_wait_end (bar, state);
00073 }
00074
00075 void
00076 gomp_team_barrier_wake (gomp_barrier_t *bar, int count)
00077 {
00078 futex_wake ((int *) &bar->generation, count == 0 ? INT_MAX : count);
00079 }
00080
00081 void
00082 gomp_team_barrier_wait_end (gomp_barrier_t *bar, gomp_barrier_state_t state)
00083 {
00084 unsigned int generation;
00085
00086 if (__builtin_expect ((state & 1) != 0, 0))
00087 {
00088
00089 struct gomp_thread *thr = gomp_thread ();
00090 struct gomp_team *team = thr->ts.team;
00091 bar->awaited = bar->total;
00092 atomic_write_barrier ();
00093 if (__builtin_expect (team->task_count, 0))
00094 {
00095 gomp_barrier_handle_tasks (state);
00096 state &= ~1;
00097 }
00098 else
00099 {
00100 bar->generation = state + 3;
00101 futex_wake ((int *) &bar->generation, INT_MAX);
00102 return;
00103 }
00104 }
00105
00106 generation = state;
00107 do
00108 {
00109 do_wait ((int *) &bar->generation, generation);
00110 if (__builtin_expect (bar->generation & 1, 0))
00111 gomp_barrier_handle_tasks (state);
00112 if ((bar->generation & 2))
00113 generation |= 2;
00114 }
00115 while (bar->generation != state + 4);
00116 }
00117
00118 void
00119 gomp_team_barrier_wait (gomp_barrier_t *bar)
00120 {
00121 gomp_team_barrier_wait_end (bar, gomp_barrier_wait_start (bar));
00122 }