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 | |||