diff --git a/ChangeLog b/ChangeLog index 86c71d16..f097bee0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20,6 +20,10 @@ Fernando Lopez-Lezcano Jackdmp changes log --------------------------- +2008-05-28 Stephane Letz + + * New testMutex test, correct timing in drivers. + 2008-05-27 Stephane Letz * Correct timing in drivers : frame time has to be incremented before Read. diff --git a/common/JackAudioDriver.cpp b/common/JackAudioDriver.cpp index 519ff5a7..80fa5900 100644 --- a/common/JackAudioDriver.cpp +++ b/common/JackAudioDriver.cpp @@ -270,9 +270,4 @@ jack_default_audio_sample_t* JackAudioDriver::GetMonitorBuffer(int port_index) return (jack_default_audio_sample_t*)fGraphManager->GetBuffer(fMonitorPortList[port_index], fEngineControl->fBufferSize); } -void JackAudioDriver::CycleIncTime() -{ - fEngineControl->CycleIncTime(fLastWaitUst); -} - } // end of namespace diff --git a/common/JackAudioDriver.h b/common/JackAudioDriver.h index 6ba929ec..6ffdf8c3 100644 --- a/common/JackAudioDriver.h +++ b/common/JackAudioDriver.h @@ -50,8 +50,6 @@ class EXPORT JackAudioDriver : public JackDriver jack_default_audio_sample_t* GetOutputBuffer(int port_index); jack_default_audio_sample_t* GetMonitorBuffer(int port_index); - void CycleIncTime(); - private: int ProcessAsync(); diff --git a/common/JackDriver.cpp b/common/JackDriver.cpp index ee3a097c..746eeb75 100644 --- a/common/JackDriver.cpp +++ b/common/JackDriver.cpp @@ -175,6 +175,16 @@ bool JackDriver::IsRealTime() return fEngineControl->fRealTime; } +void JackDriver::CycleIncTime() +{ + fEngineControl->CycleIncTime(fLastWaitUst); +} +void JackDriver::CycleTakeTime() +{ + fLastWaitUst = GetMicroSeconds(); // Take callback date here + fEngineControl->CycleIncTime(fLastWaitUst); +} + JackClientControl* JackDriver::GetClientControl() const { return fClientControl; diff --git a/common/JackDriver.h b/common/JackDriver.h index 41eb6dd3..7c1e9e55 100644 --- a/common/JackDriver.h +++ b/common/JackDriver.h @@ -157,6 +157,9 @@ class EXPORT JackDriver : public JackDriverClient JackClientControl* fClientControl; JackClientControl* GetClientControl() const; + + void CycleIncTime(); + void CycleTakeTime(); public: diff --git a/common/JackDummyDriver.cpp b/common/JackDummyDriver.cpp index 42773636..7a8c5d17 100644 --- a/common/JackDummyDriver.cpp +++ b/common/JackDummyDriver.cpp @@ -60,8 +60,7 @@ int JackDummyDriver::Open(jack_nframes_t nframes, int JackDummyDriver::Process() { - fLastWaitUst = GetMicroSeconds(); // Take callback date here - fEngineControl->CycleIncTime(fLastWaitUst); + JackDriver::CycleTakeTime(); JackAudioDriver::Process(); usleep(std::max(0L, long(fWaitTime - (GetMicroSeconds() - fLastWaitUst)))); return 0; diff --git a/common/JackFreewheelDriver.cpp b/common/JackFreewheelDriver.cpp index 5b965653..97dd1a26 100644 --- a/common/JackFreewheelDriver.cpp +++ b/common/JackFreewheelDriver.cpp @@ -33,7 +33,7 @@ int JackFreewheelDriver::Process() { if (fIsMaster) { jack_log("JackFreewheelDriver::Process master %lld", fEngineControl->fTimeOutUsecs); - fLastWaitUst = GetMicroSeconds(); + JackDriver::CycleTakeTime(); fEngine->Process(fLastWaitUst); fGraphManager->ResumeRefNum(fClientControl, fSynchroTable); // Signal all clients if (fGraphManager->SuspendRefNum(fClientControl, fSynchroTable, FREEWHEEL_DRIVER_TIMEOUT * 1000000) < 0) { // Wait for all clients to finish for 10 sec diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 841db673..973aebf7 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -2294,7 +2294,7 @@ int JackAlsaDriver::Read() jack_log("JackAlsaDriver::Read nframes = %ld", nframes); // Has to be done before read - JackAudioDriver::CycleIncTime(); + JackDriver::CycleIncTime(); return alsa_driver_read((alsa_driver_t *)fDriver, fEngineControl->fBufferSize); } diff --git a/linux/firewire/JackFFADODriver.cpp b/linux/firewire/JackFFADODriver.cpp index ee36f59c..756abb88 100644 --- a/linux/firewire/JackFFADODriver.cpp +++ b/linux/firewire/JackFFADODriver.cpp @@ -747,7 +747,7 @@ int JackFFADODriver::Read() jack_log("JackFFADODriver::Read nframes = %ld", nframes); // Has to be done before read - JackAudioDriver::CycleIncTime(); + JackDriver::CycleIncTime(); printExit(); return ffado_driver_read((ffado_driver_t *)fDriver, fEngineControl->fBufferSize); diff --git a/linux/freebob/JackFreebobDriver.cpp b/linux/freebob/JackFreebobDriver.cpp index b91642d8..c198c9ea 100644 --- a/linux/freebob/JackFreebobDriver.cpp +++ b/linux/freebob/JackFreebobDriver.cpp @@ -879,7 +879,7 @@ int JackFreebobDriver::Read() jack_log("JackFreebobDriver::Read nframes = %ld", nframes); // Has to be done before read - JackAudioDriver::CycleIncTime(); + JackDriver::CycleIncTime(); printExit(); return freebob_driver_read((freebob_driver_t *)fDriver, fEngineControl->fBufferSize); diff --git a/macosx/JackCoreAudioDriver.cpp b/macosx/JackCoreAudioDriver.cpp index 14cfeaf1..84976d97 100644 --- a/macosx/JackCoreAudioDriver.cpp +++ b/macosx/JackCoreAudioDriver.cpp @@ -169,11 +169,10 @@ OSStatus JackCoreAudioDriver::Render(void *inRefCon, AudioBufferList *ioData) { JackCoreAudioDriver* driver = (JackCoreAudioDriver*)inRefCon; - driver->fLastWaitUst = GetMicroSeconds(); // Take callback date here driver->fActionFags = ioActionFlags; driver->fCurrentTime = (AudioTimeStamp *)inTimeStamp; driver->fDriverOutputData = ioData; - driver->CycleIncTime(); + driver->CycleTakeTime(); return driver->Process(); } diff --git a/macosx/Jackdmp.xcodeproj/project.pbxproj b/macosx/Jackdmp.xcodeproj/project.pbxproj index 0ee19c1c..718b1e80 100644 --- a/macosx/Jackdmp.xcodeproj/project.pbxproj +++ b/macosx/Jackdmp.xcodeproj/project.pbxproj @@ -537,6 +537,8 @@ 4BF520540CB8D0E80037470E /* timestamps.c in Sources */ = {isa = PBXBuildFile; fileRef = 4BF520520CB8D0E80037470E /* timestamps.c */; }; 4BF520590CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4BF5205A0CB8D1010037470E /* timestamps.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF520580CB8D1010037470E /* timestamps.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4BFA5E920DEC4D9C00FA4CDB /* Jackservermp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BA7BDCB0DC22F4500AA3457 /* Jackservermp.framework */; }; + 4BFA5E9F0DEC4DD900FA4CDB /* testMutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */; }; 4BFA99AA0AAAF40C009E916C /* jdelay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFA99A90AAAF40C009E916C /* jdelay.cpp */; }; /* End PBXBuildFile section */ @@ -1207,6 +1209,8 @@ 4BF8D2470834F20600C94B91 /* testSem.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = testSem.cpp; path = ../tests/testSem.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0D08AC88EF00D1A344 /* JackFrameTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = JackFrameTimer.cpp; path = ../common/JackFrameTimer.cpp; sourceTree = SOURCE_ROOT; }; 4BF8FB0E08AC88EF00D1A344 /* JackFrameTimer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFrameTimer.h; path = ../common/JackFrameTimer.h; sourceTree = SOURCE_ROOT; }; + 4BFA5E980DEC4D9C00FA4CDB /* testMutex */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testMutex; sourceTree = BUILT_PRODUCTS_DIR; }; + 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testMutex.cpp; path = ../tests/testMutex.cpp; sourceTree = SOURCE_ROOT; }; 4BFA99A20AAAF3B0009E916C /* jdelay */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jdelay; sourceTree = BUILT_PRODUCTS_DIR; }; 4BFA99A90AAAF40C009E916C /* jdelay.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = jdelay.cpp; path = ../tests/jdelay.cpp; sourceTree = SOURCE_ROOT; }; 4BFB297708AF44ED00D450D4 /* JackMachServerNotifyChannel.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JackMachServerNotifyChannel.cpp; sourceTree = ""; }; @@ -1667,6 +1671,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BFA5E910DEC4D9C00FA4CDB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFA5E920DEC4D9C00FA4CDB /* Jackservermp.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFA999C0AAAF3B0009E916C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1785,6 +1797,7 @@ 4B363F1E0DEB0A6A001F72D9 /* jack_monitor_client */, 4B363F350DEB0BD1001F72D9 /* jack_showtime */, 4B363F720DEB0D4E001F72D9 /* jack_impulse_grabber */, + 4BFA5E980DEC4D9C00FA4CDB /* testMutex */, ); name = Products; sourceTree = ""; @@ -1854,6 +1867,7 @@ 4BA577BC08BF8BE200F82DE1 /* testSynchroClient.cpp */, 4BA577FB08BF8E4600F82DE1 /* testSynchroServer.cpp */, 4BBD13CC08C71EB40079F7FF /* testSynchroServerClient.cpp */, + 4BFA5E9E0DEC4DD900FA4CDB /* testMutex.cpp */, 4BE6C6AC0A3E0A65005A203A /* jack_test.cpp */, ); name = Tests; @@ -2772,6 +2786,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BFA5E8C0DEC4D9C00FA4CDB /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFA99990AAAF3B0009E916C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3927,6 +3948,25 @@ productReference = 4BE99D300AD7A04800C59091 /* jack_cpu */; productType = "com.apple.product-type.tool"; }; + 4BFA5E8B0DEC4D9C00FA4CDB /* testMutex Universal */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4BFA5E940DEC4D9C00FA4CDB /* Build configuration list for PBXNativeTarget "testMutex Universal" */; + buildPhases = ( + 4BFA5E8C0DEC4D9C00FA4CDB /* Headers */, + 4BFA5E8D0DEC4D9C00FA4CDB /* Sources */, + 4BFA5E910DEC4D9C00FA4CDB /* Frameworks */, + 4BFA5E930DEC4D9C00FA4CDB /* Rez */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "testMutex Universal"; + productInstallPath = /usr/local/bin; + productName = testSem; + productReference = 4BFA5E980DEC4D9C00FA4CDB /* testMutex */; + productType = "com.apple.product-type.tool"; + }; 4BFA99980AAAF3B0009E916C /* jdelay Universal */ = { isa = PBXNativeTarget; buildConfigurationList = 4BFA999E0AAAF3B0009E916C /* Build configuration list for PBXNativeTarget "jdelay Universal" */; @@ -3975,6 +4015,7 @@ 4B699D03097D421600A18468 /* jack_external_metro Universal */, 4B699D13097D421600A18468 /* testAtomic Universal */, 4B699D27097D421600A18468 /* testSem Universal */, + 4BFA5E8B0DEC4D9C00FA4CDB /* testMutex Universal */, 4B699D3F097D421600A18468 /* zombie Universal */, 4BE6C6910A3E096F005A203A /* jack_test Universal */, 4BA7FEB90D8E76270017FF73 /* jack_server_control Universal */, @@ -4429,6 +4470,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BFA5E930DEC4D9C00FA4CDB /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFA999D0AAAF3B0009E916C /* Rez */ = { isa = PBXRezBuildPhase; buildActionMask = 2147483647; @@ -5099,6 +5147,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 4BFA5E8D0DEC4D9C00FA4CDB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4BFA5E9F0DEC4DD900FA4CDB /* testMutex.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 4BFA999A0AAAF3B0009E916C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -12363,6 +12419,111 @@ }; name = Default; }; + 4BFA5E950DEC4D9C00FA4CDB /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = testSem; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = YES; + }; + name = Development; + }; + 4BFA5E960DEC4D9C00FA4CDB /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 3; + HEADER_SEARCH_PATHS = ../common; + MACOSX_DEPLOYMENT_TARGET = 10.4; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = testMutex; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + ZERO_LINK = NO; + }; + name = Deployment; + }; + 4BFA5E970DEC4D9C00FA4CDB /* Default */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + i386, + ppc, + ); + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SRCROOT)/build/Development\""; + GCC_OPTIMIZATION_LEVEL = 3; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + AudioToolBox, + "-framework", + CoreAudio, + ); + OTHER_REZFLAGS = ""; + PRODUCT_NAME = testSem; + REZ_EXECUTABLE = YES; + SDKROOT = ""; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = ( + "-Wmost", + "-Wno-four-char-constants", + "-Wno-unknown-pragmas", + ); + }; + name = Default; + }; 4BFA999F0AAAF3B0009E916C /* Development */ = { isa = XCBuildConfiguration; buildSettings = { @@ -13097,6 +13258,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Default; }; + 4BFA5E940DEC4D9C00FA4CDB /* Build configuration list for PBXNativeTarget "testMutex Universal" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4BFA5E950DEC4D9C00FA4CDB /* Development */, + 4BFA5E960DEC4D9C00FA4CDB /* Deployment */, + 4BFA5E970DEC4D9C00FA4CDB /* Default */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Default; + }; 4BFA999E0AAAF3B0009E916C /* Build configuration list for PBXNativeTarget "jdelay Universal" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/tests/testMutex.cpp b/tests/testMutex.cpp new file mode 100644 index 00000000..25fa965c --- /dev/null +++ b/tests/testMutex.cpp @@ -0,0 +1,129 @@ +/* + Copyright (C) 2004-2008 Grame + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +#include "JackMachSemaphore.h" +#include "JackMachThread.h" +#endif + +#include "JackPosixThread.h" +#include "JackMutex.h" + + +using namespace Jack; + +struct LockedObject : public JackLockAble { + + JackThread* fThread; + int fCount; + + LockedObject():fCount(0) + {} + + virtual ~LockedObject() + { + fThread->Kill(); + delete fThread; + } + + void LockedMethod1() + { + JackLock lock(this); + fCount++; + //printf("LockedMethod1 self %x fCount %ld\n", pthread_self(), fCount); + } + + void LockedMethod2() + { + JackLock lock(this); + fCount--; + //printf("LockedMethod2 self %x fCount %ld\n", pthread_self(), fCount); + } + + void LockedMethod3() + { + JackLock lock(this); + fCount--; + //printf("LockedMethod3 self %x fCount %ld\n", pthread_self(), fCount); + } + +}; + +struct TestThread : public JackRunnableInterface { + + JackThread* fThread; + LockedObject* fObject; + int fNum; + + TestThread(LockedObject* obj, int num) + { + fThread = new JackMachThread(this); + fObject = obj; + fNum = num; + fThread->StartSync(); + } + + virtual ~TestThread() + { + fThread->Kill(); + delete fThread; + } + + bool Execute() + { + //printf("TestThread Execute\n"); + switch (fNum) { + + case 1: + fObject->LockedMethod1(); + break; + + case 2: + fObject->LockedMethod2(); + break; + + case 3: + fObject->LockedMethod3(); + break; + }; + + //usleep(fNum * 1000); + return true; + } + +}; + +int main (int argc, char * const argv[]) +{ + char c; + + LockedObject* obj = new LockedObject(); + TestThread* th1 = new TestThread(obj, 1); + TestThread* th2 = new TestThread(obj,3); + TestThread* th3 = new TestThread(obj, 2); + + while ((c = getchar()) != 'q')) {} + +} diff --git a/windows/JackPortAudioDriver.cpp b/windows/JackPortAudioDriver.cpp index 438cfa06..a819aa31 100644 --- a/windows/JackPortAudioDriver.cpp +++ b/windows/JackPortAudioDriver.cpp @@ -218,12 +218,11 @@ int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer, void* userData) { JackPortAudioDriver* driver = (JackPortAudioDriver*)userData; - driver->fLastWaitUst = GetMicroSeconds(); // Take callback date here driver->fInputBuffer = (float**)inputBuffer; driver->fOutputBuffer = (float**)outputBuffer; // Setup threadded based log function set_threaded_log_function(); - driver->CycleIncTime(); + driver->CycleTakeTime(); return (driver->Process() == 0) ? paContinue : paAbort; }