Jack2 1.9.10

JackEngineControl.cpp

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