git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4119 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.7
@@ -34,6 +34,10 @@ Valerio Pilo | |||
Jackdmp changes log | |||
--------------------------- | |||
2011-02-07 Stephane Letz <letz@grame.fr> | |||
* Valerio Pilo second CAS for ARMv7 patch. | |||
2011-02-03 Stephane Letz <letz@grame.fr> | |||
* Valerio Pilo CAS for ARMv7 patch. | |||
@@ -90,7 +90,7 @@ int JackEngine::Close() | |||
return 0; | |||
} | |||
void JackEngine::NotifyQuit() | |||
{ | |||
fChannel.NotifyQuit(); | |||
@@ -137,8 +137,10 @@ void JackEngine::ReleaseRefnum(int ref) | |||
void JackEngine::ProcessNext(jack_time_t cur_cycle_begin) | |||
{ | |||
fLastSwitchUsecs = cur_cycle_begin; | |||
if (fGraphManager->RunNextGraph()) // True if the graph actually switched to a new state | |||
fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0); | |||
if (fGraphManager->RunNextGraph()) { // True if the graph actually switched to a new state | |||
//fChannel.Notify(ALL_CLIENTS, kGraphOrderCallback, 0); | |||
NotifyGraphReorder(); | |||
} | |||
fSignal.Signal(); // Signal for threads waiting for next cycle | |||
} | |||
@@ -194,12 +196,14 @@ void JackEngine::CheckXRun(jack_time_t callback_usecs) // REVOIR les conditions | |||
if (status != NotTriggered && status != Finished) { | |||
jack_error("JackEngine::XRun: client = %s was not run: state = %ld", client->GetClientControl()->fName, status); | |||
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients | |||
//fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients | |||
NotifyXRun(ALL_CLIENTS); | |||
} | |||
if (status == Finished && (long)(finished_date - callback_usecs) > 0) { | |||
jack_error("JackEngine::XRun: client %s finished after current callback", client->GetClientControl()->fName); | |||
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients | |||
//fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); // Notify all clients | |||
NotifyXRun(ALL_CLIENTS); | |||
} | |||
} | |||
} | |||
@@ -215,7 +219,7 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, const char* messa | |||
// The client may be notified by the RT thread while closing | |||
if (client) { | |||
if (client && client->GetClientControl()->fCallback[event]) { | |||
/* | |||
Important for internal clients : unlock before calling the notification callbacks. | |||
@@ -225,7 +229,7 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, const char* messa | |||
jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2); | |||
if (res) | |||
fMutex.Lock(); | |||
} else { | |||
jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); | |||
} | |||
@@ -276,7 +280,8 @@ void JackEngine::NotifyXRun(jack_time_t callback_usecs, float delayed_usecs) | |||
{ | |||
// Use the audio thread => request thread communication channel | |||
fEngineControl->NotifyXRun(callback_usecs, delayed_usecs); | |||
fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); | |||
//fChannel.Notify(ALL_CLIENTS, kXRunCallback, 0); | |||
NotifyXRun(ALL_CLIENTS); | |||
} | |||
void JackEngine::NotifyXRun(int refnum) | |||
@@ -307,7 +312,7 @@ void JackEngine::NotifyFailure(int code, const char* reason) | |||
{ | |||
NotifyClients(kShutDownCallback, false, reason, code, 0); | |||
} | |||
void JackEngine::NotifyFreewheel(bool onoff) | |||
{ | |||
if (onoff) { | |||
@@ -689,7 +694,7 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) | |||
{ | |||
JackClientInterface* client = fClientTable[refnum]; | |||
jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); | |||
if (is_real_time) | |||
fGraphManager->Activate(refnum); | |||
@@ -702,7 +707,7 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) | |||
jack_int_t output_ports[PORT_NUM_FOR_CLIENT]; | |||
fGraphManager->GetInputPorts(refnum, input_ports); | |||
fGraphManager->GetOutputPorts(refnum, output_ports); | |||
// First add port state to JackPortIsActive | |||
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { | |||
fGraphManager->ActivatePort(input_ports[i]); | |||
@@ -710,10 +715,10 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time) | |||
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) { | |||
fGraphManager->ActivatePort(output_ports[i]); | |||
} | |||
// Notify client | |||
NotifyActivate(refnum); | |||
// Then issue port registration notification | |||
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { | |||
NotifyPortRegistation(input_ports[i], true); | |||
@@ -746,7 +751,7 @@ int JackEngine::ClientDeactivate(int refnum) | |||
PortDisconnect(refnum, output_ports[i], ALL_PORTS); | |||
fGraphManager->DeactivatePort(output_ports[i]); | |||
} | |||
// Then issue port registration notification | |||
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { | |||
NotifyPortRegistation(input_ports[i], false); | |||
@@ -867,7 +872,7 @@ int JackEngine::PortDisconnect(int refnum, const char* src, const char* dst) | |||
int JackEngine::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) | |||
{ | |||
jack_log("JackEngine::PortDisconnect src = %d dst = %d", src, dst); | |||
if (dst == ALL_PORTS) { | |||
jack_int_t connections[CONNECTION_NUM_FOR_PORT]; | |||
@@ -940,11 +945,11 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even | |||
char path_buf[JACK_PORT_NAME_SIZE]; | |||
snprintf( path_buf, sizeof(path_buf), "%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR ); | |||
int res = JackTools::MkDir(path_buf); | |||
if (res) | |||
if (res) | |||
jack_error( "JackEngine::SessionNotify: can not create session directory '%s'", path_buf ); | |||
int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path_buf, (int) type, 0); | |||
if (result == 2) { | |||
@@ -952,9 +957,9 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even | |||
} else if (result == 1) { | |||
char uuid_buf[JACK_UUID_SIZE]; | |||
snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); | |||
fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, | |||
fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, | |||
client->GetClientControl()->fName, | |||
client->GetClientControl()->fSessionCommand, | |||
client->GetClientControl()->fSessionCommand, | |||
client->GetClientControl()->fSessionFlags )); | |||
} | |||
} | |||
@@ -974,9 +979,9 @@ void JackEngine::SessionReply(int refnum) | |||
JackClientInterface* client = fClientTable[refnum]; | |||
char uuid_buf[JACK_UUID_SIZE]; | |||
snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); | |||
fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, | |||
fSessionResult->fCommandList.push_back( JackSessionCommand( uuid_buf, | |||
client->GetClientControl()->fName, | |||
client->GetClientControl()->fSessionCommand, | |||
client->GetClientControl()->fSessionCommand, | |||
client->GetClientControl()->fSessionFlags )); | |||
fSessionPendingReplies -= 1; | |||
@@ -71,54 +71,13 @@ static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* ad | |||
#if defined(__thumb__) | |||
/* | |||
* This Compare And Swap code is based off the version found | |||
* in MutekH, http://www.mutekh.org/trac/mutekh | |||
* | |||
* Copyright Alexandre Becoulet <alexandre.becoulet@lip6.fr> (c) 2006 | |||
*/ | |||
static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) | |||
{ | |||
UInt32 tmp, loaded; | |||
UInt32 thumb_tmp; | |||
asm volatile( | |||
".align 2 \n\t" | |||
"mov %[adr], pc \n\t" | |||
"add %[adr], %[adr], #4 \n\t" | |||
"bx %[adr] \n\t" | |||
"nop \n\t" | |||
".arm \n\t" | |||
"1: \n\t" | |||
"ldrex %[loaded], [%[atomic]] \n\t" | |||
"cmp %[loaded], %[value] \n\t" | |||
"bne 2f \n\t" | |||
"strex %[tmp], %[newvalue], [%[atomic]] \n\t" | |||
"tst %[tmp], #1 \n\t" | |||
"bne 1b \n\t" | |||
"2: \n\t" | |||
"add %[adr], pc, #1 \n\t" | |||
"bx %[adr] \n\t" | |||
: [tmp] "=&r" (tmp), [loaded] "=&r" (loaded), "=m" (*(volatile UInt32*)addr) | |||
, [adr] "=&l" (thumb_tmp) | |||
: [value] "r" (value), [newvalue] "r" (newvalue), [atomic] "r" (addr) | |||
); | |||
return loaded == value; | |||
} | |||
#endif | |||
#if !defined(__i386__) && !defined(__x86_64__) && !defined(__PPC__) | |||
#if !defined(__i386__) && !defined(__x86_64__) && !defined(__PPC__) && !defined(__thumb__) | |||
#warning using builtin gcc (version > 4.1) atomic | |||
static inline char CAS(volatile UInt32 value, UInt32 newvalue, volatile void* addr) | |||
{ | |||
return __sync_bool_compare_and_swap (&addr, value, newvalue); | |||
return __sync_bool_compare_and_swap ((UInt32*)addr, value, newvalue); | |||
} | |||
#endif | |||
@@ -12,7 +12,7 @@ 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. | |||
*/ | |||
@@ -45,12 +45,12 @@ void JackClientSocket::SetReadTimeOut(long sec) | |||
{ | |||
int flags; | |||
fTimeOut = sec; | |||
if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { | |||
jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_GETFL"); | |||
return; | |||
} | |||
flags |= O_NONBLOCK; | |||
if (fcntl(fSocket, F_SETFL, flags) < 0) { | |||
jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_SETFL"); | |||
@@ -62,12 +62,12 @@ void JackClientSocket::SetWriteTimeOut(long sec) | |||
{ | |||
int flags; | |||
fTimeOut = sec; | |||
if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { | |||
jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_GETFL"); | |||
return; | |||
} | |||
flags |= O_NONBLOCK; | |||
if (fcntl(fSocket, F_SETFL, flags) < 0) { | |||
jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_SETFL"); | |||
@@ -100,7 +100,7 @@ void JackClientSocket::SetWriteTimeOut(long sec) | |||
#endif | |||
void JackClientSocket::SetNonBlocking(bool onoff) | |||
{ | |||
{ | |||
if (onoff) { | |||
long flags = 0; | |||
if (fcntl(fSocket, F_SETFL, flags | O_NONBLOCK) < 0) { | |||
@@ -140,7 +140,7 @@ int JackClientSocket::Connect(const char* dir, const char* name, int which) // A | |||
int JackClientSocket::Close() | |||
{ | |||
jack_log("JackClientSocket::Close"); | |||
jack_log("JackClientSocket::Close"); | |||
if (fSocket > 0) { | |||
shutdown(fSocket, SHUT_RDWR); | |||
close(fSocket); | |||
@@ -161,17 +161,17 @@ int JackClientSocket::Read(void* data, int len) | |||
struct timeval tv; | |||
fd_set fdset; | |||
ssize_t res; | |||
tv.tv_sec = fTimeOut; | |||
tv.tv_usec = 0; | |||
FD_ZERO(&fdset); | |||
FD_SET(fSocket, &fdset); | |||
do { | |||
res = select(fSocket + 1, &fdset, NULL, NULL, &tv); | |||
} while (res < 0 && errno == EINTR); | |||
if (res < 0) { | |||
return res; | |||
} else if (res == 0) { | |||
@@ -179,9 +179,9 @@ int JackClientSocket::Read(void* data, int len) | |||
} | |||
} | |||
#endif | |||
if ((res = read(fSocket, data, len)) != len) { | |||
if (errno == EWOULDBLOCK) { | |||
if (errno == EWOULDBLOCK || errno == EAGAIN) { | |||
jack_error("JackClientSocket::Read time out"); | |||
return 0; // For a non blocking socket, a read failure is not considered as an error | |||
} else if (res != 0) { | |||
@@ -201,21 +201,21 @@ int JackClientSocket::Write(void* data, int len) | |||
#if defined(__sun__) || defined(sun) | |||
if (fTimeOut > 0) { | |||
struct timeval tv; | |||
fd_set fdset; | |||
ssize_t res; | |||
tv.tv_sec = fTimeOut; | |||
tv.tv_usec = 0; | |||
FD_ZERO(&fdset); | |||
FD_SET(fSocket, &fdset); | |||
do { | |||
res = select(fSocket + 1, NULL, &fdset, NULL, &tv); | |||
} while (res < 0 && errno == EINTR); | |||
if (res < 0) { | |||
return res; | |||
} else if (res == 0) { | |||
@@ -225,7 +225,7 @@ int JackClientSocket::Write(void* data, int len) | |||
#endif | |||
if ((res = write(fSocket, data, len)) != len) { | |||
if (errno == EWOULDBLOCK) { | |||
if (errno == EWOULDBLOCK || errno == EAGAIN) { | |||
jack_log("JackClientSocket::Write time out"); | |||
return 0; // For a non blocking socket, a write failure is not considered as an error | |||
} else if (res != 0) { | |||
@@ -251,7 +251,7 @@ int JackServerSocket::Bind(const char* dir, const char* name, int which) // A re | |||
addr.sun_family = AF_UNIX; | |||
BuildName(name, fName, dir, which); | |||
strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1); | |||
jack_log("Bind: addr.sun_path %s", addr.sun_path); | |||
unlink(fName); // Security... | |||
@@ -12,7 +12,7 @@ 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. | |||
*/ | |||
@@ -41,7 +41,7 @@ class JackSocketServerChannel : public JackRunnableInterface | |||
JackServerSocket fRequestListenSocket; // Socket to create request socket for the client | |||
JackThread fThread; // Thread to execute the event loop | |||
JackServer* fServer; | |||
JackServer* fServer; | |||
pollfd* fPollTable; | |||
bool fRebuild; | |||
std::map<int, std::pair<int, JackClientSocket*> > fSocketTable; | |||
@@ -61,7 +61,7 @@ class JackSocketServerChannel : public JackRunnableInterface | |||
int Open(const char* server_name, JackServer* server); // Open the Server/Client connection | |||
void Close(); // Close the Server/Client connection | |||
int Start(); | |||
// JackRunnableInterface interface | |||