File: itkBarrier.cxx

package info (click to toggle)
insighttoolkit 3.6.0-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 94,956 kB
  • ctags: 74,981
  • sloc: cpp: 355,621; ansic: 195,070; fortran: 28,713; python: 3,802; tcl: 1,996; sh: 1,175; java: 583; makefile: 415; csh: 184; perl: 175
file content (133 lines) | stat: -rw-r--r-- 3,236 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile: itkBarrier.cxx,v $
  Language:  C++
  Date:      $Date: 2006-03-16 22:07:44 $
  Version:   $Revision: 1.7 $

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even 
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkBarrier.h"
#include "itkMacro.h"

#ifdef ITK_USE_SPROC
#include "itkMultiThreader.h"
#endif

namespace itk {

#ifdef ITK_USE_FETCHOP_BARRIERS
atomic_reservoir_t Barrier::m_Reservoir = 0;
bool Barrier::m_ReservoirInitialized = false;
int Barrier::m_MaxBarriers = 1024;
#endif

Barrier::Barrier()
{
  m_NumberExpected = 0;
#ifndef ITK_USE_SPROC
#ifndef ITK_USE_FETCHOP_BARRIERS
  m_NumberArrived  = 0;
  m_ConditionVariable = ConditionVariable::New();
#endif
#endif
}

Barrier::~Barrier()
{
#if defined ITK_USE_FETCHOP_BARRIERS
  if (m_Pvar !=0 && Barrier::m_Reservoir != 0 )
    {
    atomic_free_variable(Barrier::m_Reservoir, m_Pvar);
    m_Pvar = 0;
    }

  if (Barrier::m_Reservoir != 0)
    {
    atomic_free_reservoir(Barrier::m_Reservoir);
    Barrier::m_Reservoir = 0;
    }
#elif defined ITK_USE_SPROC
  if (m_Barrier != 0)
    {
    // Note: free_barrier should be called here
    // but is buggy and causes a seg fault. jc 7/29/03
    
    //    free_barrier( m_Barrier );
    }
#endif
}

void Barrier::Initialize( unsigned int n )
{
  m_NumberExpected = n;

#if defined ITK_USE_FETCHOP_BARRIERS
  // Create the reservoir.
  if (Barrier::m_ReservoirInitialized == false)
    {
    Barrier::m_Reservoir = atomic_alloc_reservoir(USE_DEFAULT_PM, 
                                                  m_MaxBarriers, 0);
    if (Barrier::m_Reservoir != 0)
      {
      Barrier::m_ReservoirInitialized = true;
      }
    else
      {
      itkExceptionMacro( << "atomic_alloc_reservoir call failed!" );
      }
    }

  m_FetchopFlag = 0;
  m_Pvar = atomic_alloc_variable(Barrier::m_Reservoir, 0);
  storeop_store(m_Pvar, 0);
#elif defined ITK_USE_SPROC
  if (MultiThreader::GetInitialized() == false)
    {
    MultiThreader::Initialize();
    }
  m_Barrier = new_barrier( MultiThreader::GetThreadArena() );
#endif  
}

void Barrier::Wait()
{
#if defined ITK_USE_FETCHOP_BARRIERS
  int gen = m_FetchopFlag;
  atomic_var_t val = atomic_fetch_and_increment(m_Pvar);
  if (val == m_NumberExpected - 1)
    {
    storeop_store(m_Pvar, 0);
    m_FetchopFlag++;
    }
  while (m_FetchopFlag == gen)
    { // spin
    }
#elif defined ITK_USE_SPROC
  barrier(m_Barrier, m_NumberExpected);
#else
  m_Mutex.Lock();
  m_NumberArrived++;
  if ( m_NumberArrived == m_NumberExpected )
    {
    // Clear all blocked threads
    m_NumberArrived = 0;
    m_ConditionVariable->Broadcast();
    }
  else
    {
    // Block this thread
    m_ConditionVariable->Wait( &m_Mutex );
    }
  m_Mutex.Unlock();
#endif
}

}// end namespace itk