jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.5KB

  1. /*
  2. Copyright (C) 2004-2006 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "JackEngineTiming.h"
  16. #include "JackClientInterface.h"
  17. #include "JackEngineControl.h"
  18. #include "JackClientControl.h"
  19. #include <math.h>
  20. #include <algorithm>
  21. #include <iostream>
  22. #include <assert.h>
  23. namespace Jack
  24. {
  25. inline jack_time_t MAX(jack_time_t a, jack_time_t b)
  26. {
  27. return (a < b) ? b : a;
  28. }
  29. JackEngineTiming::JackEngineTiming(JackClientInterface** table, JackGraphManager* manager, JackEngineControl* control)
  30. {
  31. fClientTable = table;
  32. fGraphManager = manager;
  33. fEngineControl = control;
  34. fLastTime = 0;
  35. fCurTime = 0;
  36. fProcessTime = 0;
  37. fLastProcessTime = 0;
  38. fSpareUsecs = 0;
  39. fMaxUsecs = 0;
  40. fAudioCycle = 0;
  41. }
  42. void JackEngineTiming::UpdateTiming(jack_time_t callback_usecs)
  43. {
  44. GetTimeMeasure(callback_usecs);
  45. CalcCPULoad();
  46. }
  47. void JackEngineTiming::CalcCPULoad()
  48. {
  49. jack_time_t lastCycleEnd = fLastProcessTime;
  50. for (int i = REAL_REFNUM; i < CLIENT_NUM; i++) {
  51. JackClientInterface* client = fClientTable[i];
  52. JackClientTiming* timing = fGraphManager->GetClientTiming(i);
  53. if (client && client->GetClientControl()->fActive && timing->fStatus == Finished) {
  54. lastCycleEnd = MAX(lastCycleEnd, timing->fFinishedAt);
  55. }
  56. }
  57. /* store the execution time for later averaging */
  58. fRollingClientUsecs[fRollingClientUsecsIndex++] = lastCycleEnd - fLastTime;
  59. if (fRollingClientUsecsIndex >= JACK_ENGINE_ROLLING_COUNT) {
  60. fRollingClientUsecsIndex = 0;
  61. }
  62. /* every so often, recompute the current maximum use over the
  63. last JACK_ENGINE_ROLLING_COUNT client iterations.
  64. */
  65. if (++fRollingClientUsecsCnt % fRollingInterval == 0) {
  66. jack_time_t maxUsecs = 0;
  67. for (int i = 0; i < JACK_ENGINE_ROLLING_COUNT; i++) {
  68. maxUsecs = MAX(fRollingClientUsecs[i], maxUsecs);
  69. }
  70. fMaxUsecs = MAX(fMaxUsecs, maxUsecs);
  71. fSpareUsecs = jack_time_t((maxUsecs < fEngineControl->fPeriodUsecs) ? fEngineControl->fPeriodUsecs - maxUsecs : 0);
  72. fEngineControl->fCPULoad
  73. = ((1.0f - (float(fSpareUsecs) / float(fEngineControl->fPeriodUsecs))) * 50.0f + (fEngineControl->fCPULoad * 0.5f));
  74. }
  75. }
  76. void JackEngineTiming::ResetRollingUsecs()
  77. {
  78. memset(fRollingClientUsecs, 0, sizeof(fRollingClientUsecs));
  79. fRollingClientUsecsIndex = 0;
  80. fRollingClientUsecsCnt = 0;
  81. fSpareUsecs = 0;
  82. fRollingInterval = (int)floor((JACK_ENGINE_ROLLING_INTERVAL * 1000.0f) / fEngineControl->fPeriodUsecs);
  83. }
  84. void JackEngineTiming::GetTimeMeasure(jack_time_t callbackUsecs)
  85. {
  86. int pos = (++fAudioCycle) % TIME_POINTS;
  87. fLastTime = fCurTime;
  88. fCurTime = callbackUsecs;
  89. fLastProcessTime = fProcessTime;
  90. fProcessTime = GetMicroSeconds();
  91. if (fLastTime > 0) {
  92. fMeasure[pos].fEngineTime = fLastTime;
  93. fMeasure[pos].fAudioCycle = fAudioCycle;
  94. for (int i = 0; i < CLIENT_NUM; i++) {
  95. JackClientInterface* client = fClientTable[i];
  96. JackClientTiming* timing = fGraphManager->GetClientTiming(i);
  97. if (client && client->GetClientControl()->fActive) {
  98. fMeasure[pos].fClientTable[i].fRefNum = i;
  99. fMeasure[pos].fClientTable[i].fSignaledAt = timing->fSignaledAt;
  100. fMeasure[pos].fClientTable[i].fAwakeAt = timing->fAwakeAt;
  101. fMeasure[pos].fClientTable[i].fFinishedAt = timing->fFinishedAt;
  102. fMeasure[pos].fClientTable[i].fStatus = timing->fStatus;
  103. }
  104. }
  105. }
  106. }
  107. void JackEngineTiming::ClearTimeMeasures()
  108. {
  109. for (int i = 0; i < TIME_POINTS; i++) {
  110. for (int j = 0; j < CLIENT_NUM; j++) {
  111. fMeasure[i].fClientTable[j].fRefNum = 0;
  112. fMeasure[i].fClientTable[j].fSignaledAt = 0;
  113. fMeasure[i].fClientTable[j].fAwakeAt = 0;
  114. fMeasure[i].fClientTable[j].fFinishedAt = 0;
  115. }
  116. }
  117. fLastTime = fCurTime = 0;
  118. }
  119. } // end of namespace