2 Copyright (C) 2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "JackClientInterface.h"
22 #include "JackEngineControl.h"
23 #include "JackGraphManager.h"
24 #include "JackClientControl.h"
31 static inline jack_time_t
JACK_MAX(jack_time_t a
, jack_time_t b
)
33 return (a
< b
) ? b
: a
;
36 void JackEngineControl::CalcCPULoad(JackClientInterface
** table
,
37 JackGraphManager
* manager
,
38 jack_time_t cur_cycle_begin
,
39 jack_time_t prev_cycle_end
)
41 fPrevCycleTime
= fCurCycleTime
;
42 fCurCycleTime
= cur_cycle_begin
;
43 jack_time_t last_cycle_end
= prev_cycle_end
;
45 // In Asynchronous mode, last cycle end is the max of client end dates
47 for (int i
= fDriverNum
; i
< CLIENT_NUM
; i
++) {
48 JackClientInterface
* client
= table
[i
];
49 JackClientTiming
* timing
= manager
->GetClientTiming(i
);
50 if (client
&& client
->GetClientControl()->fActive
&& timing
->fStatus
== Finished
) {
51 last_cycle_end
= JACK_MAX(last_cycle_end
, timing
->fFinishedAt
);
56 // Store the execution time for later averaging
57 if (last_cycle_end
> 0) {
58 fRollingClientUsecs
[fRollingClientUsecsIndex
++] = last_cycle_end
- fPrevCycleTime
;
60 if (fRollingClientUsecsIndex
>= JACK_ENGINE_ROLLING_COUNT
) {
61 fRollingClientUsecsIndex
= 0;
64 // Each time we have a full set of iterations, recompute the current
65 // usage from the latest JACK_ENGINE_ROLLING_COUNT client entries.
66 if (fRollingClientUsecsCnt
&& (fRollingClientUsecsIndex
== 0)) {
67 jack_time_t avg_usecs
= 0;
68 jack_time_t max_usecs
= 0;
70 for (int i
= 0; i
< JACK_ENGINE_ROLLING_COUNT
; i
++) {
71 avg_usecs
+= fRollingClientUsecs
[i
]; // This is really a running total to be averaged later
72 max_usecs
= JACK_MAX(fRollingClientUsecs
[i
], max_usecs
);
75 fMaxUsecs
= JACK_MAX(fMaxUsecs
, max_usecs
);
77 if (max_usecs
< ((fPeriodUsecs
* 95) / 100)) {
78 // Average the values from our JACK_ENGINE_ROLLING_COUNT array
79 fSpareUsecs
= (jack_time_t
)(fPeriodUsecs
- (avg_usecs
/ JACK_ENGINE_ROLLING_COUNT
));
81 // Use the 'worst case' value (or zero if we exceeded 'fPeriodUsecs')
82 fSpareUsecs
= jack_time_t((max_usecs
< fPeriodUsecs
) ? fPeriodUsecs
- max_usecs
: 0);
85 fCPULoad
= ((1.f
- (float(fSpareUsecs
) / float(fPeriodUsecs
))) * 50.f
+ (fCPULoad
* 0.5f
));
88 fRollingClientUsecsCnt
++;
91 void JackEngineControl::ResetRollingUsecs()
93 memset(fRollingClientUsecs
, 0, sizeof(fRollingClientUsecs
));
94 fRollingClientUsecsIndex
= 0;
95 fRollingClientUsecsCnt
= 0;
97 fRollingInterval
= int(floor((JACK_ENGINE_ROLLING_INTERVAL
* 1000.f
) / fPeriodUsecs
));
100 void JackEngineControl::NotifyXRun(jack_time_t callback_usecs
, float delayed_usecs
)
102 ResetFrameTime(callback_usecs
);
103 fXrunDelayedUsecs
= delayed_usecs
;
104 if (delayed_usecs
> fMaxDelayedUsecs
) {
105 fMaxDelayedUsecs
= delayed_usecs
;
109 } // end of namespace