NVIDIA IndeX: Base API nvidia_logo_transpbg.gif Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
condition.h
Go to the documentation of this file.
1 /***************************************************************************************************
2  * Copyright 2020 NVIDIA Corporation. All rights reserved.
3  **************************************************************************************************/
8 
9 #ifndef MI_BASE_CONDITION_H
10 #define MI_BASE_CONDITION_H
11 
12 #include <mi/base/config.h>
13 #include <mi/base/types.h>
14 
15 #ifndef MI_PLATFORM_WINDOWS
16 #include <cerrno>
17 #include <pthread.h>
18 #include <sys/time.h>
19 #else
20 #include <mi/base/miwindows.h>
21 #endif
22 
23 namespace mi {
24 
25 namespace base {
26 
31 class Condition
33 {
34 public:
37  {
38 #ifndef MI_PLATFORM_WINDOWS
39  m_signaled = false;
40  pthread_mutex_init( &m_mutex, NULL);
41  pthread_cond_init( &m_condvar, NULL);
42 #else
43  m_handle = CreateEvent( NULL, false, false, NULL);
44 #endif
45  }
46 
49  {
50 #ifndef MI_PLATFORM_WINDOWS
51  pthread_mutex_destroy( &m_mutex);
52  pthread_cond_destroy( &m_condvar);
53 #else
54  CloseHandle( m_handle);
55 #endif
56  }
57 
61  void wait()
62  {
63 #ifndef MI_PLATFORM_WINDOWS
64  pthread_mutex_lock( &m_mutex);
65  while( !m_signaled)
66  pthread_cond_wait( &m_condvar, &m_mutex);
67  m_signaled = false;
68  pthread_mutex_unlock( &m_mutex);
69 #else
70  WaitForSingleObject( m_handle, INFINITE);
71 #endif
72  }
73 
81  bool timed_wait( Float64 timeout) {
82 #ifndef MI_PLATFORM_WINDOWS
83  struct timeval now;
84  gettimeofday( &now, NULL);
85  struct timespec timeout_abs;
86  timeout_abs.tv_sec = now.tv_sec + static_cast<long>( floor( timeout));
87  timeout_abs.tv_nsec
88  = 1000 * now.tv_usec + static_cast<long>( 1E9 * ( timeout - floor( timeout)));
89  if( timeout_abs.tv_nsec > 1000000000) {
90  timeout_abs.tv_sec += 1;
91  timeout_abs.tv_nsec -= 1000000000;
92  }
93 
94  bool timed_out = false;
95  pthread_mutex_lock( &m_mutex);
96  while( !m_signaled)
97  {
98  int result = pthread_cond_timedwait( &m_condvar, &m_mutex, &timeout_abs);
99  timed_out = result == ETIMEDOUT;
100  if( result != EINTR)
101  break;
102  }
103  m_signaled = false;
104  pthread_mutex_unlock( &m_mutex);
105  return timed_out;
106 #else
107  DWORD timeout_ms = static_cast<DWORD>( 1000 * timeout);
108  DWORD result = WaitForSingleObject( m_handle, timeout_ms);
109  return result == WAIT_TIMEOUT;
110 #endif
111  }
112 
121  void signal()
122  {
123 #ifndef MI_PLATFORM_WINDOWS
124  pthread_mutex_lock( &m_mutex);
125  m_signaled = true;
126  pthread_cond_signal( &m_condvar);
127  pthread_mutex_unlock( &m_mutex);
128 #else
129  SetEvent( m_handle);
130 #endif
131  }
132 
136  void reset()
137  {
138 #ifndef MI_PLATFORM_WINDOWS
139  pthread_mutex_lock( &m_mutex);
140  m_signaled = false;
141  pthread_mutex_unlock( &m_mutex);
142 #else
143  ResetEvent( m_handle);
144 #endif
145  }
146 
147 private:
148 #ifndef MI_PLATFORM_WINDOWS
149  pthread_mutex_t m_mutex;
152  pthread_cond_t m_condvar;
154  bool m_signaled;
155 #else
156  HANDLE m_handle;
158 #endif
159 };
160  // end group mi_base_threads
162 
163 } // namespace base
164 
165 } // namespace mi
166 
167 #endif // MI_BASE_CONDITION_H