Browse Source

Correct TopologicalSort.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4169 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.7
sletz 14 years ago
parent
commit
2eeb1f0ad3
8 changed files with 71 additions and 58 deletions
  1. +1
    -0
      ChangeLog
  2. +8
    -15
      common/JackClient.cpp
  3. +30
    -18
      common/JackConnectionManager.cpp
  4. +13
    -5
      common/JackConnectionManager.h
  5. +4
    -3
      common/JackEngine.cpp
  6. +2
    -2
      common/JackGraphManager.cpp
  7. +0
    -1
      common/JackGraphManager.h
  8. +13
    -14
      common/JackMessageBuffer.cpp

+ 1
- 0
ChangeLog View File

@@ -37,6 +37,7 @@ Valerio Pilo
2011-03-10 Stephane Letz <letz@grame.fr>

* Latency callback must always be activated.
* Correct TopologicalSort.

2011-03-09 Stephane Letz <letz@grame.fr>



+ 8
- 15
common/JackClient.cpp View File

@@ -319,8 +319,7 @@ int JackClient::HandleLatencyCallback(int status)

for (it = fPortList.begin(); it != fPortList.end(); it++) {
JackPort* port = GetGraphManager()->GetPort(*it);

if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) {
if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) {
GetGraphManager()->RecalculateLatency(*it, mode);
}
if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) {
@@ -339,10 +338,8 @@ int JackClient::HandleLatencyCallback(int status)
*/
for (it = fPortList.begin(); it != fPortList.end(); it++) {
JackPort* port = GetGraphManager()->GetPort(*it);

if (port->GetFlags() & JackPortIsOutput) {
if (port->GetFlags() & JackPortIsOutput) {
jack_latency_range_t other_latency;

port->GetLatencyRange(mode, &other_latency);
if (other_latency.max > latency.max)
latency.max = other_latency.max;
@@ -358,8 +355,7 @@ int JackClient::HandleLatencyCallback(int status)
*/
for (it = fPortList.begin(); it != fPortList.end(); it++) {
JackPort* port = GetGraphManager()->GetPort(*it);

if (port->GetFlags() & JackPortIsInput) {
if (port->GetFlags() & JackPortIsInput) {
port->SetLatencyRange(mode, &latency);
}
}
@@ -369,11 +365,9 @@ int JackClient::HandleLatencyCallback(int status)
*/
for (it = fPortList.begin(); it != fPortList.end(); it++) {
JackPort* port = GetGraphManager()->GetPort(*it);

if (port->GetFlags() & JackPortIsInput) {
jack_latency_range_t other_latency;

port->GetLatencyRange(mode, &other_latency);
port->GetLatencyRange(mode, &other_latency);
if (other_latency.max > latency.max)
latency.max = other_latency.max;
if (other_latency.min < latency.min)
@@ -388,8 +382,7 @@ int JackClient::HandleLatencyCallback(int status)
*/
for (it = fPortList.begin(); it != fPortList.end(); it++) {
JackPort* port = GetGraphManager()->GetPort(*it);

if (port->GetFlags() & JackPortIsOutput) {
if (port->GetFlags() & JackPortIsOutput) {
port->SetLatencyRange(mode, &latency);
}
}
@@ -1246,9 +1239,9 @@ int JackClient::SessionReply(jack_session_event_t* ev)

jack_log("JackClient::SessionReply... out of cb");

int res;
fChannel->SessionReply(GetClientControl()->fRefNum, &res);
return res;
int result = -1;
fChannel->SessionReply(GetClientControl()->fRefNum, &result);
return result;
}

char* JackClient::GetUUIDForClientName(const char* client_name)


+ 30
- 18
common/JackConnectionManager.cpp View File

@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "JackEngineControl.h"
#include "JackGlobals.h"
#include "JackError.h"
#include <set>
#include <iostream>
#include <assert.h>

@@ -272,31 +273,42 @@ int JackConnectionManager::ResumeRefNum(JackClientControl* control, JackSynchro*
return res;
}

void JackConnectionManager::Visit(jack_int_t refnum, bool visited[CLIENT_NUM], std::vector<jack_int_t>& res)
static bool HasNoConnection(jack_int_t* table)
{
if (!visited[refnum]) {
visited[refnum] = true;
jack_int_t output_ref[CLIENT_NUM];
fConnectionRef.GetOutputTable1(refnum, output_ref);

//const jack_int_t* output_ref = fConnectionRef.GetItems(refnum);
for (int i = 0; i < CLIENT_NUM; i++) {
if (output_ref[i] > 0)
Visit(i, visited, res);
}
res.push_back(refnum);
for (int ref = 0; ref < CLIENT_NUM; ref++) {
if (table[ref] > 0) return false;
}
return true;
}

// Using http://en.wikipedia.org/wiki/Topological_sorting

void JackConnectionManager::TopologicalSort(std::vector<jack_int_t>& sorted)
{
bool visited[CLIENT_NUM];
for (int i = 0; i < CLIENT_NUM; i++) {
visited[i] = false;
JackFixedMatrix<CLIENT_NUM> tmp;
std::set<jack_int_t> level;

fConnectionRef.Copy(tmp);

// Inputs of the graph
level.insert(AUDIO_DRIVER_REFNUM);
level.insert(FREEWHEEL_DRIVER_REFNUM);

while (level.size() > 0) {
jack_int_t refnum = *level.begin();
sorted.push_back(refnum);
level.erase(level.begin());
const jack_int_t* output_ref1 = tmp.GetItems(refnum);
for (int dst = 0; dst < CLIENT_NUM; dst++) {
if (output_ref1[dst] > 0) {
tmp.ClearItem(refnum, dst);
jack_int_t output_ref2[CLIENT_NUM];
tmp.GetOutputTable1(dst, output_ref2);
if (HasNoConnection(output_ref2))
level.insert(dst);
}
}
}

Visit(AUDIO_DRIVER_REFNUM, visited, sorted);
Visit(FREEWHEEL_DRIVER_REFNUM, visited, sorted);
}

/*!


+ 13
- 5
common/JackConnectionManager.h View File

@@ -24,7 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "JackActivationCount.h"
#include "JackError.h"
#include "JackCompilerDeps.h"

#include <vector>
#include <assert.h>

@@ -201,6 +200,11 @@ class JackFixedMatrix
return fTable[index1][index2];
}

void ClearItem(jack_int_t index1, jack_int_t index2)
{
fTable[index1][index2] = 0;
}

/*!
\brief Get the output indexes of a given index.
*/
@@ -235,6 +239,14 @@ class JackFixedMatrix
return false;
}

void Copy(JackFixedMatrix& copy)
{
for (int i = 0; i < SIZE; i++) {
memcpy(copy.fTable[i], fTable[i], sizeof(jack_int_t) * SIZE);
}
}


} POST_PACKED_STRUCTURE;

/*!
@@ -383,11 +395,9 @@ struct JackClientTiming

<UL>
<LI>The <B>fConnection</B> array contains the list (array line) of connected ports for a given port.
<LI>The <B>fConnectionCount</B> array contains the number of connected ports to a given port.
<LI>The <B>fInputPort</B> array contains the list (array line) of input connected ports for a given client.
<LI>The <B>fOutputPort</B> array contains the list (array line) of ouput connected ports for a given client.
<LI>The <B>fConnectionRef</B> array contains the number of ports connected between two clients.
<LI>The <B>fInputRef</B> array contains the number of input clients connected to a given client.
<LI>The <B>fInputCounter</B> array contains the number of input clients connected to a given for activation purpose.
</UL>
*/
@@ -406,8 +416,6 @@ class SERVER_EXPORT JackConnectionManager

bool IsLoopPathAux(int ref1, int ref2) const;

void Visit(jack_int_t refnum, bool visited[CLIENT_NUM], std::vector<jack_int_t>& res);

public:

JackConnectionManager();


+ 4
- 3
common/JackEngine.cpp View File

@@ -19,6 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include <iostream>
#include <fstream>
#include <set>
#include <assert.h>

#include "JackSystemDeps.h"
@@ -222,11 +223,11 @@ int JackEngine::ComputeTotalLatencies()
*/

for (it = sorted.begin(); it != sorted.end(); it++) {
jack_log("ComputeTotalLatencies %d", *it);
jack_log("Sorted %d", *it);
NotifyClient(*it, kLatencyCallback, true, "", 0, 0);
}

/* now issue playback latency callbacks in reverse graph order
/* now issue playback latency callbacks in reverse graph order.
*/
for (rit = sorted.rbegin(); rit != sorted.rend(); rit++) {
NotifyClient(*rit, kLatencyCallback, true, "", 1, 0);
@@ -554,7 +555,7 @@ int JackEngine::ClientExternalOpen(const char* name, int pid, int uuid, int* ref

if (uuid < 0) {
uuid = GetNewUUID();
strncpy( real_name, name, JACK_CLIENT_NAME_SIZE );
strncpy(real_name, name, JACK_CLIENT_NAME_SIZE);
} else {
std::map<int,std::string>::iterator res = fReservationMap.find(uuid);
if (res != fReservationMap.end()) {


+ 2
- 2
common/JackGraphManager.cpp View File

@@ -134,8 +134,8 @@ void JackGraphManager::TopologicalSort(std::vector<jack_int_t>& sorted)

do {
cur_index = GetCurrentIndex();
JackConnectionManager* manager = ReadCurrentState();
manager->TopologicalSort(sorted);
sorted.clear();
ReadCurrentState()->TopologicalSort(sorted);
next_index = GetCurrentIndex();
} while (cur_index != next_index); // Until a coherent state has been read
}


+ 0
- 1
common/JackGraphManager.h View File

@@ -29,7 +29,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "JackPlatformPlug.h"
#include "JackSystemDeps.h"


namespace Jack
{



+ 13
- 14
common/JackMessageBuffer.cpp View File

@@ -2,19 +2,19 @@
* Copyright (C) 2004 Rui Nuno Capela, Steve Harris
* Copyright (C) 2008 Nedko Arnaudov
* Copyright (C) 2008 Grame
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
@@ -34,7 +34,7 @@ JackMessageBuffer::JackMessageBuffer()

JackMessageBuffer::~JackMessageBuffer()
{}
void JackMessageBuffer::Start()
{
fRunning = true;
@@ -44,9 +44,9 @@ void JackMessageBuffer::Start()
void JackMessageBuffer::Stop()
{
if (fOverruns > 0) {
jack_error("WARNING: %d message buffer overruns!", fOverruns);
jack_error("WARNING: %d message buffer overruns!", fOverruns);
} else {
jack_log("no message buffer overruns");
jack_log("no message buffer overruns");
}
fGuard.Lock();
fRunning = false;
@@ -55,7 +55,7 @@ void JackMessageBuffer::Stop()
fThread.Stop();
Flush();
}
void JackMessageBuffer::Flush()
{
while (fOutBuffer != fInBuffer) {
@@ -76,7 +76,7 @@ void JackMessageBuffer::AddMessage(int level, const char *message)
INC_ATOMIC(&fOverruns);
}
}
bool JackMessageBuffer::Execute()
{
while (fRunning) {
@@ -94,10 +94,10 @@ bool JackMessageBuffer::Execute()
Flush();
fGuard.Unlock();
}
return false;
return false;
}

void JackMessageBuffer::Create()
void JackMessageBuffer::Create()
{
if (fInstance == NULL) {
fInstance = new JackMessageBuffer();
@@ -105,7 +105,7 @@ void JackMessageBuffer::Create()
}
}

void JackMessageBuffer::Destroy()
void JackMessageBuffer::Destroy()
{
if (fInstance != NULL) {
fInstance->Stop();
@@ -114,7 +114,7 @@ void JackMessageBuffer::Destroy()
}
}

void JackMessageBufferAdd(int level, const char *message)
void JackMessageBufferAdd(int level, const char *message)
{
if (Jack::JackMessageBuffer::fInstance == NULL) {
/* Unable to print message with realtime safety. Complain and print it anyway. */
@@ -137,7 +137,6 @@ void JackMessageBuffer::SetInitCallback(JackThreadInitCallback callback, void *a
/* and we're done */
fGuard.Unlock();
}

};


Loading…
Cancel
Save