CPN
Computational Process Networks
ReentrantLock.h
Go to the documentation of this file.
1 //=============================================================================
2 // Computational Process Networks class library
3 // Copyright (C) 1997-2006 Gregory E. Allen and The University of Texas
4 //
5 // This library is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Library General Public License as published
7 // by the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Library General Public License for more details.
14 //
15 // The GNU Public License is available in the file LICENSE, or you
16 // can write to the Free Software Foundation, Inc., 59 Temple Place -
17 // Suite 330, Boston, MA 02111-1307, USA, or you can find it on the
18 // World Wide Web at http://www.fsf.org.
19 //=============================================================================
25 #ifndef SYNC_REENTRANTLOCK_H
26 #define SYNC_REENTRANTLOCK_H
27 #pragma once
28 #include <cpn/common.h>
29 #include <cpn/utils/AutoLock.h>
31 #include <pthread.h>
32 #ifdef SYNC_PROFILE
33 #include <sys/time.h>
34 #endif
35 
36 namespace Sync {
37 
38  template<class Status_t>
40  class ReentrantCondition;
41 
42  namespace Internal {
43 #ifdef SYNC_PROFILE
44  inline double getTime() {
45  timeval tv;
46  gettimeofday(&tv, 0);
47  return static_cast<double>(tv.tv_sec) + 1e-6 * static_cast<double>(tv.tv_usec);
48  }
49 #endif
50  }
51 
55  class ReentrantLock {
56  public:
58  pthread_mutexattr_t attr;
59  pthread_mutexattr_init(&attr);
60  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
61  ENSURE(!pthread_mutex_init(&lock, &attr));
62  pthread_mutexattr_destroy(&attr);
63 #ifdef SYNC_PROFILE
64  wait_time = 0;
65  lock_time = 0;
66  lock_count = 0;
67 #endif
68  }
70  ENSURE_ABORT(!pthread_mutex_destroy(&lock));
71  }
72 
73  void Unlock() const {
74 #ifdef SYNC_PROFILE
75  lock_count--;
76  if (lock_count == 0) {
77  lock_time += Internal::getTime() - lock_last;
78  }
79 #endif
80  ENSURE_ABORT(!pthread_mutex_unlock(&lock));
81  }
82 
83  void Lock() const {
84 #ifdef SYNC_PROFILE
85  double start = Internal::getTime();
86 #endif
87  ENSURE_ABORT(!pthread_mutex_lock(&lock));
88 #ifdef SYNC_PROFILE
89  double time = Internal::getTime();
90  if (lock_count == 0) {
91  lock_last = time;
92  }
93  lock_count++;
94  wait_time += time - start;
95 #endif
96  }
97 
98 #ifdef SYNC_PROFILE
99  double GetWaitTime() const { return wait_time; }
100  double GetLockTime() const { return lock_time; }
101 #endif
102 
103  private:
104 #ifdef SYNC_PROFILE
105  mutable double wait_time;
106  mutable double lock_time;
107  mutable double lock_last;
108  mutable unsigned lock_count;
109 #endif
110 
111  mutable pthread_mutex_t lock;
112 
113  template<class T> friend class StatusHandler;
114  friend class ReentrantCondition;
115  };
116 
118 
124  public:
126  ENSURE(!pthread_cond_init(&cond, 0));
127 #ifdef SYNC_PROFILE
128  wait_time = 0;
129 #endif
130  }
131  ~ReentrantCondition() { ENSURE_ABORT(!pthread_cond_destroy(&cond)); }
132  void Signal() { pthread_cond_signal(&cond); }
133  void Broadcast() { pthread_cond_broadcast(&cond); }
134  void Wait(ReentrantLock &lock) const {
135 #ifdef SYNC_PROFILE
136  double time = Internal::getTime();
137  unsigned lock_count = lock.lock_count;
138  lock.lock_count = 0;
139  lock.lock_time += time - lock.lock_last;
140 #endif
141  pthread_cond_wait(&cond, &lock.lock);
142 #ifdef SYNC_PROFILE
143  double end = Internal::getTime();
144  lock.lock_count = lock_count;
145  lock.lock_last = end;
146  wait_time += end - time;
147 #endif
148  }
149 #ifdef SYNC_PROFILE
150  double GetWaitTime() const { return wait_time; }
151 #endif
152  private:
153 #ifdef SYNC_PROFILE
154  mutable double wait_time;
155 #endif
156  mutable pthread_cond_t cond;
157  };
158 }
159 #endif
void Wait(ReentrantLock &lock) const
#define ENSURE_ABORT(exp,...)
pthread_mutex_t lock
#define ENSURE(exp,...)
void Lock() const
Definition: ReentrantLock.h:83
AutoLock< const ReentrantLock > AutoReentrantLock
static PthreadMutex lock
Definition: NodeLoader.cc:36
Works just like a pthread condition but works with the ReentrantLock.
void Unlock() const
Definition: ReentrantLock.h:73
Automatic locking on the stack.