Jack2 1.9.6

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     // Store the execution time for later averaging 
00056     fRollingClientUsecs[fRollingClientUsecsIndex++] = last_cycle_end - fPrevCycleTime;
00057     if (fRollingClientUsecsIndex >= JACK_ENGINE_ROLLING_COUNT) 
00058         fRollingClientUsecsIndex = 0;
00059   
00060     // Every so often, recompute the current maximum use over the
00061     // last JACK_ENGINE_ROLLING_COUNT client iterations.
00062  
00063     if (++fRollingClientUsecsCnt % fRollingInterval == 0) {
00064 
00065         jack_time_t max_usecs = 0;
00066         for (int i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) 
00067             max_usecs = JACK_MAX(fRollingClientUsecs[i], max_usecs);
00068     
00069         fMaxUsecs = JACK_MAX(fMaxUsecs, max_usecs);
00070         fSpareUsecs = jack_time_t((max_usecs < fPeriodUsecs) ? fPeriodUsecs - max_usecs : 0);
00071         fCPULoad = ((1.f - (float(fSpareUsecs) / float(fPeriodUsecs))) * 50.f + (fCPULoad * 0.5f));
00072     }
00073 }
00074 
00075 void JackEngineControl::ResetRollingUsecs()
00076 {
00077     memset(fRollingClientUsecs, 0, sizeof(fRollingClientUsecs));
00078     fRollingClientUsecsIndex = 0;
00079     fRollingClientUsecsCnt = 0;
00080     fSpareUsecs = 0;
00081     fRollingInterval = int(floor((JACK_ENGINE_ROLLING_INTERVAL * 1000.f) / fPeriodUsecs));
00082 }
00083     
00084 void JackEngineControl::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs)
00085 {
00086     ResetFrameTime(callback_usecs);
00087     fXrunDelayedUsecs = delayed_usecs;
00088     if (delayed_usecs > fMaxDelayedUsecs)
00089         fMaxDelayedUsecs = delayed_usecs;
00090 }
00091     
00092 } // end of namespace