Jack2  1.9.8
JackProcessSync.cpp
1 /*
2 Copyright (C) 2004-2008 Grame
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13 
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 
18 */
19 
20 #include "JackProcessSync.h"
21 #include "JackError.h"
22 
23 namespace Jack
24 {
25 
26 void JackProcessSync::Signal()
27 {
28  int res = pthread_cond_signal(&fCond);
29  if (res != 0)
30  jack_error("JackProcessSync::Signal error err = %s", strerror(res));
31 }
32 
33 // TO DO : check thread consistency?
34 void JackProcessSync::LockedSignal()
35 {
36  int res = pthread_mutex_lock(&fMutex);
37  if (res != 0)
38  jack_error("JackProcessSync::LockedSignal error err = %s", strerror(res));
39  res = pthread_cond_signal(&fCond);
40  if (res != 0)
41  jack_error("JackProcessSync::LockedSignal error err = %s", strerror(res));
42  res = pthread_mutex_unlock(&fMutex);
43  if (res != 0)
44  jack_error("JackProcessSync::LockedSignal error err = %s", strerror(res));
45 }
46 
47 void JackProcessSync::SignalAll()
48 {
49  int res = pthread_cond_broadcast(&fCond);
50  if (res != 0)
51  jack_error("JackProcessSync::SignalAll error err = %s", strerror(res));
52 }
53 
54 // TO DO : check thread consistency?
55 void JackProcessSync::LockedSignalAll()
56 {
57  int res = pthread_mutex_lock(&fMutex);
58  if (res != 0)
59  jack_error("JackProcessSync::LockedSignalAll error err = %s", strerror(res));
60  res = pthread_cond_broadcast(&fCond);
61  if (res != 0)
62  jack_error("JackProcessSync::LockedSignalAll error err = %s", strerror(res));
63  res = pthread_mutex_unlock(&fMutex);
64  if (res != 0)
65  jack_error("JackProcessSync::LockedSignalAll error err = %s", strerror(res));
66 }
67 
68 void JackProcessSync::Wait()
69 {
70  ThrowIf(!pthread_equal(pthread_self(), fOwner), JackException("JackProcessSync::Wait: a thread has to have locked a mutex before it can wait"));
71  fOwner = 0;
72 
73  int res = pthread_cond_wait(&fCond, &fMutex);
74  if (res != 0) {
75  jack_error("JackProcessSync::Wait error err = %s", strerror(res));
76  } else {
77  fOwner = pthread_self();
78  }
79 }
80 
81 // TO DO : check thread consistency?
82 void JackProcessSync::LockedWait()
83 {
84  int res;
85  res = pthread_mutex_lock(&fMutex);
86  if (res != 0)
87  jack_error("JackProcessSync::LockedWait error err = %s", strerror(res));
88  if ((res = pthread_cond_wait(&fCond, &fMutex)) != 0)
89  jack_error("JackProcessSync::LockedWait error err = %s", strerror(res));
90  res = pthread_mutex_unlock(&fMutex);
91  if (res != 0)
92  jack_error("JackProcessSync::LockedWait error err = %s", strerror(res));
93 }
94 
95 bool JackProcessSync::TimedWait(long usec)
96 {
97  ThrowIf(!pthread_equal(pthread_self(), fOwner), JackException("JackProcessSync::TimedWait: a thread has to have locked a mutex before it can wait"));
98  fOwner = 0;
99 
100  struct timeval T0, T1;
101  timespec time;
102  struct timeval now;
103  int res;
104 
105  jack_log("JackProcessSync::TimedWait time out = %ld", usec);
106  gettimeofday(&T0, 0);
107 
108  gettimeofday(&now, 0);
109  unsigned int next_date_usec = now.tv_usec + usec;
110  time.tv_sec = now.tv_sec + (next_date_usec / 1000000);
111  time.tv_nsec = (next_date_usec % 1000000) * 1000;
112 
113  res = pthread_cond_timedwait(&fCond, &fMutex, &time);
114  if (res != 0) {
115  jack_error("JackProcessSync::TimedWait error usec = %ld err = %s", usec, strerror(res));
116  } else {
117  fOwner = pthread_self();
118  }
119 
120  gettimeofday(&T1, 0);
121  jack_log("JackProcessSync::TimedWait finished delta = %5.1lf",
122  (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec));
123 
124  return (res == 0);
125 }
126 
127 // TO DO : check thread consistency?
128 bool JackProcessSync::LockedTimedWait(long usec)
129 {
130  struct timeval T0, T1;
131  timespec time;
132  struct timeval now;
133  int res1, res2;
134 
135  res1 = pthread_mutex_lock(&fMutex);
136  if (res1 != 0)
137  jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1));
138 
139  jack_log("JackProcessSync::TimedWait time out = %ld", usec);
140  gettimeofday(&T0, 0);
141 
142  gettimeofday(&now, 0);
143  unsigned int next_date_usec = now.tv_usec + usec;
144  time.tv_sec = now.tv_sec + (next_date_usec / 1000000);
145  time.tv_nsec = (next_date_usec % 1000000) * 1000;
146  res2 = pthread_cond_timedwait(&fCond, &fMutex, &time);
147  if (res2 != 0)
148  jack_error("JackProcessSync::LockedTimedWait error usec = %ld err = %s", usec, strerror(res2));
149 
150  gettimeofday(&T1, 0);
151  res1 = pthread_mutex_unlock(&fMutex);
152  if (res1 != 0)
153  jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1));
154 
155  jack_log("JackProcessSync::TimedWait finished delta = %5.1lf",
156  (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec));
157 
158  return (res2 == 0);
159 }
160 
161 
162 } // end of namespace
163