Browse Source

Valerio Pilo second CAS for ARMv7 patch.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4119 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/1.9.7
sletz 14 years ago
parent
commit
5af8cff85a
5 changed files with 56 additions and 88 deletions
  1. +4
    -0
      ChangeLog
  2. +27
    -22
      common/JackEngine.cpp
  3. +2
    -43
      linux/JackAtomic_os.h
  4. +20
    -20
      posix/JackSocket.cpp
  5. +3
    -3
      posix/JackSocketServerChannel.h

+ 4
- 0
ChangeLog View File

@@ -34,6 +34,10 @@ Valerio Pilo
Jackdmp changes log 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> 2011-02-03 Stephane Letz <letz@grame.fr>


* Valerio Pilo CAS for ARMv7 patch. * Valerio Pilo CAS for ARMv7 patch.


+ 27
- 22
common/JackEngine.cpp View File

@@ -90,7 +90,7 @@ int JackEngine::Close()


return 0; return 0;
} }
void JackEngine::NotifyQuit() void JackEngine::NotifyQuit()
{ {
fChannel.NotifyQuit(); fChannel.NotifyQuit();
@@ -137,8 +137,10 @@ void JackEngine::ReleaseRefnum(int ref)
void JackEngine::ProcessNext(jack_time_t cur_cycle_begin) void JackEngine::ProcessNext(jack_time_t cur_cycle_begin)
{ {
fLastSwitchUsecs = 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 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) { if (status != NotTriggered && status != Finished) {
jack_error("JackEngine::XRun: client = %s was not run: state = %ld", client->GetClientControl()->fName, status); 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) { if (status == Finished && (long)(finished_date - callback_usecs) > 0) {
jack_error("JackEngine::XRun: client %s finished after current callback", client->GetClientControl()->fName); 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 // The client may be notified by the RT thread while closing
if (client) { if (client) {
if (client && client->GetClientControl()->fCallback[event]) { if (client && client->GetClientControl()->fCallback[event]) {
/* /*
Important for internal clients : unlock before calling the notification callbacks. 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); jack_error("NotifyClient fails name = %s event = %ld val1 = %ld val2 = %ld", client->GetClientControl()->fName, event, value1, value2);
if (res) if (res)
fMutex.Lock(); fMutex.Lock();
} else { } else {
jack_log("JackEngine::NotifyClient: no callback for event = %ld", event); 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 // Use the audio thread => request thread communication channel
fEngineControl->NotifyXRun(callback_usecs, delayed_usecs); 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) void JackEngine::NotifyXRun(int refnum)
@@ -307,7 +312,7 @@ void JackEngine::NotifyFailure(int code, const char* reason)
{ {
NotifyClients(kShutDownCallback, false, reason, code, 0); NotifyClients(kShutDownCallback, false, reason, code, 0);
} }
void JackEngine::NotifyFreewheel(bool onoff) void JackEngine::NotifyFreewheel(bool onoff)
{ {
if (onoff) { if (onoff) {
@@ -689,7 +694,7 @@ int JackEngine::ClientActivate(int refnum, bool is_real_time)
{ {
JackClientInterface* client = fClientTable[refnum]; JackClientInterface* client = fClientTable[refnum];
jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName); jack_log("JackEngine::ClientActivate ref = %ld name = %s", refnum, client->GetClientControl()->fName);
if (is_real_time) if (is_real_time)
fGraphManager->Activate(refnum); 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]; jack_int_t output_ports[PORT_NUM_FOR_CLIENT];
fGraphManager->GetInputPorts(refnum, input_ports); fGraphManager->GetInputPorts(refnum, input_ports);
fGraphManager->GetOutputPorts(refnum, output_ports); fGraphManager->GetOutputPorts(refnum, output_ports);
// First add port state to JackPortIsActive // First add port state to JackPortIsActive
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) {
fGraphManager->ActivatePort(input_ports[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++) { for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (output_ports[i] != EMPTY); i++) {
fGraphManager->ActivatePort(output_ports[i]); fGraphManager->ActivatePort(output_ports[i]);
} }
// Notify client // Notify client
NotifyActivate(refnum); NotifyActivate(refnum);
// Then issue port registration notification // Then issue port registration notification
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) {
NotifyPortRegistation(input_ports[i], true); NotifyPortRegistation(input_ports[i], true);
@@ -746,7 +751,7 @@ int JackEngine::ClientDeactivate(int refnum)
PortDisconnect(refnum, output_ports[i], ALL_PORTS); PortDisconnect(refnum, output_ports[i], ALL_PORTS);
fGraphManager->DeactivatePort(output_ports[i]); fGraphManager->DeactivatePort(output_ports[i]);
} }
// Then issue port registration notification // Then issue port registration notification
for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) { for (int i = 0; (i < PORT_NUM_FOR_CLIENT) && (input_ports[i] != EMPTY); i++) {
NotifyPortRegistation(input_ports[i], false); 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) 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); jack_log("JackEngine::PortDisconnect src = %d dst = %d", src, dst);
if (dst == ALL_PORTS) { if (dst == ALL_PORTS) {


jack_int_t connections[CONNECTION_NUM_FOR_PORT]; 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]; char path_buf[JACK_PORT_NAME_SIZE];
snprintf( path_buf, sizeof(path_buf), "%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR ); snprintf( path_buf, sizeof(path_buf), "%s%s%c", path, client->GetClientControl()->fName, DIR_SEPARATOR );
int res = JackTools::MkDir(path_buf); int res = JackTools::MkDir(path_buf);
if (res)
if (res)
jack_error( "JackEngine::SessionNotify: can not create session directory '%s'", path_buf ); 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); int result = client->ClientNotify(i, client->GetClientControl()->fName, kSessionCallback, true, path_buf, (int) type, 0);


if (result == 2) { if (result == 2) {
@@ -952,9 +957,9 @@ void JackEngine::SessionNotify(int refnum, const char *target, jack_session_even
} else if (result == 1) { } else if (result == 1) {
char uuid_buf[JACK_UUID_SIZE]; char uuid_buf[JACK_UUID_SIZE];
snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); 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()->fName,
client->GetClientControl()->fSessionCommand,
client->GetClientControl()->fSessionCommand,
client->GetClientControl()->fSessionFlags )); client->GetClientControl()->fSessionFlags ));
} }
} }
@@ -974,9 +979,9 @@ void JackEngine::SessionReply(int refnum)
JackClientInterface* client = fClientTable[refnum]; JackClientInterface* client = fClientTable[refnum];
char uuid_buf[JACK_UUID_SIZE]; char uuid_buf[JACK_UUID_SIZE];
snprintf( uuid_buf, sizeof(uuid_buf), "%d", client->GetClientControl()->fSessionID ); 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()->fName,
client->GetClientControl()->fSessionCommand,
client->GetClientControl()->fSessionCommand,
client->GetClientControl()->fSessionFlags )); client->GetClientControl()->fSessionFlags ));
fSessionPendingReplies -= 1; fSessionPendingReplies -= 1;




+ 2
- 43
linux/JackAtomic_os.h View File

@@ -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) 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 #endif




+ 20
- 20
posix/JackSocket.cpp View File

@@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.


You should have received a copy of the GNU Lesser General Public License 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. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.


*/ */
@@ -45,12 +45,12 @@ void JackClientSocket::SetReadTimeOut(long sec)
{ {
int flags; int flags;
fTimeOut = sec; fTimeOut = sec;
if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) {
jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_GETFL"); jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_GETFL");
return; return;
} }
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
if (fcntl(fSocket, F_SETFL, flags) < 0) { if (fcntl(fSocket, F_SETFL, flags) < 0) {
jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_SETFL"); jack_error("JackClientSocket::SetReadTimeOut error in fcntl F_SETFL");
@@ -62,12 +62,12 @@ void JackClientSocket::SetWriteTimeOut(long sec)
{ {
int flags; int flags;
fTimeOut = sec; fTimeOut = sec;
if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) { if ((flags = fcntl(fSocket, F_GETFL, 0)) < 0) {
jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_GETFL"); jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_GETFL");
return; return;
} }
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
if (fcntl(fSocket, F_SETFL, flags) < 0) { if (fcntl(fSocket, F_SETFL, flags) < 0) {
jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_SETFL"); jack_error("JackClientSocket::SetWriteTimeOut error in fcntl F_SETFL");
@@ -100,7 +100,7 @@ void JackClientSocket::SetWriteTimeOut(long sec)
#endif #endif


void JackClientSocket::SetNonBlocking(bool onoff) void JackClientSocket::SetNonBlocking(bool onoff)
{
{
if (onoff) { if (onoff) {
long flags = 0; long flags = 0;
if (fcntl(fSocket, F_SETFL, flags | O_NONBLOCK) < 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() int JackClientSocket::Close()
{ {
jack_log("JackClientSocket::Close");
jack_log("JackClientSocket::Close");
if (fSocket > 0) { if (fSocket > 0) {
shutdown(fSocket, SHUT_RDWR); shutdown(fSocket, SHUT_RDWR);
close(fSocket); close(fSocket);
@@ -161,17 +161,17 @@ int JackClientSocket::Read(void* data, int len)
struct timeval tv; struct timeval tv;
fd_set fdset; fd_set fdset;
ssize_t res; ssize_t res;
tv.tv_sec = fTimeOut; tv.tv_sec = fTimeOut;
tv.tv_usec = 0; tv.tv_usec = 0;
FD_ZERO(&fdset); FD_ZERO(&fdset);
FD_SET(fSocket, &fdset); FD_SET(fSocket, &fdset);
do { do {
res = select(fSocket + 1, &fdset, NULL, NULL, &tv); res = select(fSocket + 1, &fdset, NULL, NULL, &tv);
} while (res < 0 && errno == EINTR); } while (res < 0 && errno == EINTR);
if (res < 0) { if (res < 0) {
return res; return res;
} else if (res == 0) { } else if (res == 0) {
@@ -179,9 +179,9 @@ int JackClientSocket::Read(void* data, int len)
} }
} }
#endif #endif
if ((res = read(fSocket, data, len)) != len) { if ((res = read(fSocket, data, len)) != len) {
if (errno == EWOULDBLOCK) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
jack_error("JackClientSocket::Read time out"); jack_error("JackClientSocket::Read time out");
return 0; // For a non blocking socket, a read failure is not considered as an error return 0; // For a non blocking socket, a read failure is not considered as an error
} else if (res != 0) { } else if (res != 0) {
@@ -201,21 +201,21 @@ int JackClientSocket::Write(void* data, int len)


#if defined(__sun__) || defined(sun) #if defined(__sun__) || defined(sun)
if (fTimeOut > 0) { if (fTimeOut > 0) {
struct timeval tv; struct timeval tv;
fd_set fdset; fd_set fdset;
ssize_t res; ssize_t res;
tv.tv_sec = fTimeOut; tv.tv_sec = fTimeOut;
tv.tv_usec = 0; tv.tv_usec = 0;
FD_ZERO(&fdset); FD_ZERO(&fdset);
FD_SET(fSocket, &fdset); FD_SET(fSocket, &fdset);
do { do {
res = select(fSocket + 1, NULL, &fdset, NULL, &tv); res = select(fSocket + 1, NULL, &fdset, NULL, &tv);
} while (res < 0 && errno == EINTR); } while (res < 0 && errno == EINTR);
if (res < 0) { if (res < 0) {
return res; return res;
} else if (res == 0) { } else if (res == 0) {
@@ -225,7 +225,7 @@ int JackClientSocket::Write(void* data, int len)
#endif #endif


if ((res = write(fSocket, data, len)) != len) { if ((res = write(fSocket, data, len)) != len) {
if (errno == EWOULDBLOCK) {
if (errno == EWOULDBLOCK || errno == EAGAIN) {
jack_log("JackClientSocket::Write time out"); jack_log("JackClientSocket::Write time out");
return 0; // For a non blocking socket, a write failure is not considered as an error return 0; // For a non blocking socket, a write failure is not considered as an error
} else if (res != 0) { } 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; addr.sun_family = AF_UNIX;
BuildName(name, fName, dir, which); BuildName(name, fName, dir, which);
strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1); strncpy(addr.sun_path, fName, sizeof(addr.sun_path) - 1);
jack_log("Bind: addr.sun_path %s", addr.sun_path); jack_log("Bind: addr.sun_path %s", addr.sun_path);
unlink(fName); // Security... unlink(fName); // Security...




+ 3
- 3
posix/JackSocketServerChannel.h View File

@@ -12,7 +12,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.


You should have received a copy of the GNU Lesser General Public License 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. 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 JackServerSocket fRequestListenSocket; // Socket to create request socket for the client
JackThread fThread; // Thread to execute the event loop JackThread fThread; // Thread to execute the event loop
JackServer* fServer;
JackServer* fServer;
pollfd* fPollTable; pollfd* fPollTable;
bool fRebuild; bool fRebuild;
std::map<int, std::pair<int, JackClientSocket*> > fSocketTable; 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 int Open(const char* server_name, JackServer* server); // Open the Server/Client connection
void Close(); // Close the Server/Client connection void Close(); // Close the Server/Client connection
int Start(); int Start();


// JackRunnableInterface interface // JackRunnableInterface interface


Loading…
Cancel
Save