File: TestConditionVariable.cxx

package info (click to toggle)
vtk7 7.1.1%2Bdfsg2-8
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 127,396 kB
  • sloc: cpp: 1,539,584; ansic: 124,382; python: 78,038; tcl: 47,013; xml: 8,142; yacc: 5,040; java: 4,439; perl: 3,132; lex: 1,926; sh: 1,500; makefile: 126; objc: 83
file content (128 lines) | stat: -rw-r--r-- 3,432 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
#include "vtkConditionVariable.h"
#include "vtkMultiThreader.h"
#include "vtksys/SystemTools.hxx"

#include <stdlib.h>


typedef struct {
  vtkMutexLock* Lock;
  vtkConditionVariable* Condition;
  int Done;
  int NumberOfWorkers;
} vtkThreadUserData;

VTK_THREAD_RETURN_TYPE vtkTestCondVarThread( void* arg )
{
  int threadId = static_cast<vtkMultiThreader::ThreadInfo*>(arg)->ThreadID;
  int threadCount = static_cast<vtkMultiThreader::ThreadInfo*>(arg)->NumberOfThreads;
  vtkThreadUserData* td = static_cast<vtkThreadUserData*>(
    static_cast<vtkMultiThreader::ThreadInfo*>(arg)->UserData );
  if ( td )
  {
    if ( threadId == 0 )
    {
      td->Done = 0;
      td->Lock->Lock();
      cout << "Thread " << ( threadId + 1 ) << " of " << threadCount << " initializing.\n";
      cout.flush();
      td->Lock->Unlock();

      int i;
      for ( i = 0; i < 2 * threadCount; ++ i )
      {
        td->Lock->Lock();
        cout << "Signaling (count " << i << ")...\n";
        cout.flush();
        td->Lock->Unlock();
        td->Condition->Signal();

        //sleep( 1 );
      }

      i = 0;
      do
      {
        td->Lock->Lock();
        td->Done = 1;
        cout << "Broadcasting...\n";
        cout.flush();
        td->Lock->Unlock();
        td->Condition->Broadcast();
        vtksys::SystemTools::Delay( 200 ); // 0.2 s between broadcasts
      }
      while ( td->NumberOfWorkers > 0 && ( i ++ < 1000 ) );
      if ( i >= 1000 )
      {
        exit( 2 );
      }
    }
    else
    {
      // Wait for thread 0 to initialize... Ugly but effective
      while ( td->Done < 0 )
      {
        vtksys::SystemTools::Delay( 200 ); // 0.2 s between checking
      }

      // Wait for the condition and then note we were signaled.
      // This part looks like a Hansen Monitor:
      // ref: http://www.cs.utexas.edu/users/lorenzo/corsi/cs372h/07S/notes/Lecture12.pdf (page 2/5), code on Tradeoff slide.

      td->Lock->Lock();
      while ( td->Done <= 0 )
      {
        cout << " Thread " << ( threadId + 1 ) << " waiting.\n";
        cout.flush();
        // Wait() performs an Unlock internally.
        td->Condition->Wait( td->Lock );
        // Once Wait() returns, the lock is locked again.
        cout << " Thread " << ( threadId + 1 ) << " responded.\n";
        cout.flush();
      }
      -- td->NumberOfWorkers;
      td->Lock->Unlock();
    }

    td->Lock->Lock();
    cout << "  Thread " << ( threadId + 1 ) << " of " << threadCount << " exiting.\n";
    cout.flush();
    td->Lock->Unlock();
  }
  else
  {
    cout << "No thread data!\n";
    cout << "  Thread " << ( threadId + 1 ) << " of " << threadCount << " exiting.\n";
    cout.flush();
  }

  return VTK_THREAD_RETURN_VALUE;
}

int TestConditionVariable( int, char*[] )
{
  vtkMultiThreader* threader = vtkMultiThreader::New();
  int numThreads = threader->GetNumberOfThreads();

  vtkThreadUserData data;
  data.Lock = vtkMutexLock::New();
  data.Condition = vtkConditionVariable::New();
  data.Done = -1;
  data.NumberOfWorkers = numThreads - 1;

  threader->SetNumberOfThreads( numThreads );
  threader->SetSingleMethod( vtkTestCondVarThread, &data );
  threader->SingleMethodExecute();

  cout << "Done with threader.\n";
  cout.flush();

  vtkIndent indent;
  indent = indent.GetNextIndent();
  data.Condition->PrintSelf( cout, indent );

  data.Lock->Delete();
  data.Condition->Delete();
  threader->Delete();
  return 0;
}