Jack2
1.9.10
|
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 00056 // Store the execution time for later averaging 00057 if (last_cycle_end > 0) { 00058 fRollingClientUsecs[fRollingClientUsecsIndex++] = last_cycle_end - fPrevCycleTime; 00059 } 00060 if (fRollingClientUsecsIndex >= JACK_ENGINE_ROLLING_COUNT) { 00061 fRollingClientUsecsIndex = 0; 00062 } 00063 00064 // Each time we have a full set of iterations, recompute the current 00065 // usage from the latest JACK_ENGINE_ROLLING_COUNT client entries. 00066 if (fRollingClientUsecsCnt && (fRollingClientUsecsIndex == 0)) { 00067 jack_time_t avg_usecs = 0; 00068 jack_time_t max_usecs = 0; 00069 00070 for (int i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) { 00071 avg_usecs += fRollingClientUsecs[i]; // This is really a running total to be averaged later 00072 max_usecs = JACK_MAX(fRollingClientUsecs[i], max_usecs); 00073 } 00074 00075 fMaxUsecs = JACK_MAX(fMaxUsecs, max_usecs); 00076 00077 if (max_usecs < ((fPeriodUsecs * 95) / 100)) { 00078 // Average the values from our JACK_ENGINE_ROLLING_COUNT array 00079 fSpareUsecs = (jack_time_t)(fPeriodUsecs - (avg_usecs / JACK_ENGINE_ROLLING_COUNT)); 00080 } else { 00081 // Use the 'worst case' value (or zero if we exceeded 'fPeriodUsecs') 00082 fSpareUsecs = jack_time_t((max_usecs < fPeriodUsecs) ? fPeriodUsecs - max_usecs : 0); 00083 } 00084 00085 fCPULoad = ((1.f - (float(fSpareUsecs) / float(fPeriodUsecs))) * 50.f + (fCPULoad * 0.5f)); 00086 } 00087 00088 fRollingClientUsecsCnt++; 00089 } 00090 00091 void JackEngineControl::ResetRollingUsecs() 00092 { 00093 memset(fRollingClientUsecs, 0, sizeof(fRollingClientUsecs)); 00094 fRollingClientUsecsIndex = 0; 00095 fRollingClientUsecsCnt = 0; 00096 fSpareUsecs = 0; 00097 fRollingInterval = int(floor((JACK_ENGINE_ROLLING_INTERVAL * 1000.f) / fPeriodUsecs)); 00098 } 00099 00100 void JackEngineControl::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) 00101 { 00102 ResetFrameTime(callback_usecs); 00103 fXrunDelayedUsecs = delayed_usecs; 00104 if (delayed_usecs > fMaxDelayedUsecs) { 00105 fMaxDelayedUsecs = delayed_usecs; 00106 } 00107 } 00108 00109 } // end of namespace