Jack2  1.9.8
JackProcessSync.cpp
00001 /*
00002 Copyright (C) 2004-2008 Grame
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU Lesser General Public License as published by
00006 the Free Software Foundation; either version 2.1 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU Lesser General Public License for more details.
00013 
00014 You should have received a copy of the GNU Lesser General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 
00018 */
00019 
00020 #include "JackProcessSync.h"
00021 #include "JackError.h"
00022 
00023 namespace Jack
00024 {
00025 
00026 void JackProcessSync::Signal()
00027 {
00028     int res = pthread_cond_signal(&fCond);
00029     if (res != 0)
00030         jack_error("JackProcessSync::Signal error err = %s", strerror(res));
00031 }
00032 
00033 // TO DO : check thread consistency?
00034 void JackProcessSync::LockedSignal()
00035 {
00036     int res = pthread_mutex_lock(&fMutex);
00037     if (res != 0)
00038         jack_error("JackProcessSync::LockedSignal error err = %s", strerror(res));
00039     res = pthread_cond_signal(&fCond);
00040     if (res != 0)
00041         jack_error("JackProcessSync::LockedSignal error err = %s", strerror(res));
00042     res = pthread_mutex_unlock(&fMutex);
00043     if (res != 0)
00044         jack_error("JackProcessSync::LockedSignal error err = %s", strerror(res));
00045 }
00046 
00047 void JackProcessSync::SignalAll()
00048 {
00049     int res = pthread_cond_broadcast(&fCond);
00050     if (res != 0)
00051         jack_error("JackProcessSync::SignalAll error err = %s", strerror(res));
00052 }
00053 
00054 // TO DO : check thread consistency?
00055 void JackProcessSync::LockedSignalAll()
00056 {
00057     int res = pthread_mutex_lock(&fMutex);
00058     if (res != 0)
00059         jack_error("JackProcessSync::LockedSignalAll error err = %s", strerror(res));
00060     res = pthread_cond_broadcast(&fCond);
00061     if (res != 0)
00062         jack_error("JackProcessSync::LockedSignalAll error err = %s", strerror(res));
00063     res = pthread_mutex_unlock(&fMutex);
00064     if (res != 0)
00065         jack_error("JackProcessSync::LockedSignalAll error err = %s", strerror(res));
00066 }
00067 
00068 void JackProcessSync::Wait()
00069 {
00070     ThrowIf(!pthread_equal(pthread_self(), fOwner), JackException("JackProcessSync::Wait: a thread has to have locked a mutex before it can wait"));
00071     fOwner = 0;
00072 
00073     int res = pthread_cond_wait(&fCond, &fMutex);
00074     if (res != 0) {
00075         jack_error("JackProcessSync::Wait error err = %s", strerror(res));
00076     } else {
00077         fOwner = pthread_self();
00078     }
00079 }
00080 
00081 // TO DO : check thread consistency?
00082 void JackProcessSync::LockedWait()
00083 {
00084     int res;
00085     res = pthread_mutex_lock(&fMutex);
00086     if (res != 0)
00087         jack_error("JackProcessSync::LockedWait error err = %s", strerror(res));
00088     if ((res = pthread_cond_wait(&fCond, &fMutex)) != 0)
00089         jack_error("JackProcessSync::LockedWait error err = %s", strerror(res));
00090     res = pthread_mutex_unlock(&fMutex);
00091     if (res != 0)
00092         jack_error("JackProcessSync::LockedWait error err = %s", strerror(res));
00093 }
00094 
00095 bool JackProcessSync::TimedWait(long usec)
00096 {
00097     ThrowIf(!pthread_equal(pthread_self(), fOwner), JackException("JackProcessSync::TimedWait: a thread has to have locked a mutex before it can wait"));
00098     fOwner = 0;
00099 
00100     struct timeval T0, T1;
00101     timespec time;
00102     struct timeval now;
00103     int res;
00104 
00105     jack_log("JackProcessSync::TimedWait time out = %ld", usec);
00106     gettimeofday(&T0, 0);
00107 
00108     gettimeofday(&now, 0);
00109     unsigned int next_date_usec = now.tv_usec + usec;
00110     time.tv_sec = now.tv_sec + (next_date_usec / 1000000);
00111     time.tv_nsec = (next_date_usec % 1000000) * 1000;
00112 
00113     res = pthread_cond_timedwait(&fCond, &fMutex, &time);
00114     if (res != 0) {
00115         jack_error("JackProcessSync::TimedWait error usec = %ld err = %s", usec, strerror(res));
00116     } else {
00117         fOwner = pthread_self();
00118     }
00119 
00120     gettimeofday(&T1, 0);
00121     jack_log("JackProcessSync::TimedWait finished delta = %5.1lf",
00122              (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec));
00123 
00124     return (res == 0);
00125 }
00126 
00127 // TO DO : check thread consistency?
00128 bool JackProcessSync::LockedTimedWait(long usec)
00129 {
00130     struct timeval T0, T1;
00131     timespec time;
00132     struct timeval now;
00133     int res1, res2;
00134 
00135     res1 = pthread_mutex_lock(&fMutex);
00136     if (res1 != 0)
00137         jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1));
00138 
00139     jack_log("JackProcessSync::TimedWait time out = %ld", usec);
00140     gettimeofday(&T0, 0);
00141 
00142     gettimeofday(&now, 0);
00143     unsigned int next_date_usec = now.tv_usec + usec;
00144     time.tv_sec = now.tv_sec + (next_date_usec / 1000000);
00145     time.tv_nsec = (next_date_usec % 1000000) * 1000;
00146     res2 = pthread_cond_timedwait(&fCond, &fMutex, &time);
00147     if (res2 != 0)
00148         jack_error("JackProcessSync::LockedTimedWait error usec = %ld err = %s", usec, strerror(res2));
00149 
00150     gettimeofday(&T1, 0);
00151     res1 = pthread_mutex_unlock(&fMutex);
00152     if (res1 != 0)
00153         jack_error("JackProcessSync::LockedTimedWait error err = %s", usec, strerror(res1));
00154 
00155     jack_log("JackProcessSync::TimedWait finished delta = %5.1lf",
00156              (1e6 * T1.tv_sec - 1e6 * T0.tv_sec + T1.tv_usec - T0.tv_usec));
00157 
00158     return (res2 == 0);
00159 }
00160 
00161 
00162 } // end of namespace
00163