Jack2 1.9.8
|
00001 /* 00002 Copyright (C) 2003 Paul Davis 00003 Copyright (C) 2004-2008 Grame 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU Lesser General Public License as published by 00007 the Free Software Foundation; either version 2.1 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 00019 */ 00020 00021 #include "JackClientInterface.h" 00022 #include "JackEngineControl.h" 00023 #include "JackGraphManager.h" 00024 #include "JackClientControl.h" 00025 #include <algorithm> 00026 #include <math.h> 00027 00028 namespace Jack 00029 { 00030 00031 static inline jack_time_t JACK_MAX(jack_time_t a, jack_time_t b) 00032 { 00033 return (a < b) ? b : a; 00034 } 00035 00036 void JackEngineControl::CalcCPULoad(JackClientInterface** table, 00037 JackGraphManager* manager, 00038 jack_time_t cur_cycle_begin, 00039 jack_time_t prev_cycle_end) 00040 { 00041 fPrevCycleTime = fCurCycleTime; 00042 fCurCycleTime = cur_cycle_begin; 00043 jack_time_t last_cycle_end = prev_cycle_end; 00044 00045 // In Asynchronous mode, last cycle end is the max of client end dates 00046 if (!fSyncMode) { 00047 for (int i = fDriverNum; i < CLIENT_NUM; i++) { 00048 JackClientInterface* client = table[i]; 00049 JackClientTiming* timing = manager->GetClientTiming(i); 00050 if (client && client->GetClientControl()->fActive && timing->fStatus == Finished) 00051 last_cycle_end = JACK_MAX(last_cycle_end, timing->fFinishedAt); 00052 } 00053 } 00054 00055 // Store the execution time for later averaging 00056 if (last_cycle_end > 0) 00057 fRollingClientUsecs[fRollingClientUsecsIndex++] = last_cycle_end - fPrevCycleTime; 00058 if (fRollingClientUsecsIndex >= JACK_ENGINE_ROLLING_COUNT) 00059 fRollingClientUsecsIndex = 0; 00060 00061 // Each time we have a full set of iterations, recompute the current 00062 // usage from the latest JACK_ENGINE_ROLLING_COUNT client entries. 00063 if (fRollingClientUsecsCnt && (fRollingClientUsecsIndex == 0)) { 00064 jack_time_t avg_usecs = 0; 00065 jack_time_t max_usecs = 0; 00066 00067 for (int i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) { 00068 avg_usecs += fRollingClientUsecs[i]; // This is really a running 00069 // total to be averaged later 00070 max_usecs = JACK_MAX(fRollingClientUsecs[i], max_usecs); 00071 } 00072 00073 fMaxUsecs = JACK_MAX(fMaxUsecs, max_usecs); 00074 00075 if (max_usecs < ((fPeriodUsecs * 95) / 100)) { 00076 // Average the values from our JACK_ENGINE_ROLLING_COUNT array 00077 fSpareUsecs = (jack_time_t)(fPeriodUsecs - (avg_usecs / JACK_ENGINE_ROLLING_COUNT)); 00078 } else { 00079 // Use the 'worst case' value (or zero if we exceeded 'fPeriodUsecs') 00080 fSpareUsecs = jack_time_t((max_usecs < fPeriodUsecs) ? fPeriodUsecs - max_usecs : 0); 00081 } 00082 00083 fCPULoad = ((1.f - (float(fSpareUsecs) / float(fPeriodUsecs))) * 50.f + (fCPULoad * 0.5f)); 00084 } 00085 00086 fRollingClientUsecsCnt++; 00087 } 00088 00089 void JackEngineControl::ResetRollingUsecs() 00090 { 00091 memset(fRollingClientUsecs, 0, sizeof(fRollingClientUsecs)); 00092 fRollingClientUsecsIndex = 0; 00093 fRollingClientUsecsCnt = 0; 00094 fSpareUsecs = 0; 00095 fRollingInterval = int(floor((JACK_ENGINE_ROLLING_INTERVAL * 1000.f) / fPeriodUsecs)); 00096 } 00097 00098 void JackEngineControl::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) 00099 { 00100 ResetFrameTime(callback_usecs); 00101 fXrunDelayedUsecs = delayed_usecs; 00102 if (delayed_usecs > fMaxDelayedUsecs) 00103 fMaxDelayedUsecs = delayed_usecs; 00104 } 00105 00106 } // end of namespace