Browse Source

Implement thread.h API

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1349 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.61
sletz 18 years ago
parent
commit
6eff0aaf2d
8 changed files with 239 additions and 146 deletions
  1. +28
    -6
      common/JackAPI.cpp
  2. +36
    -22
      common/JackPosixThread.cpp
  3. +5
    -1
      common/JackPosixThread.h
  4. +4
    -4
      linux/alsa/JackAlsaDriver.cpp
  5. +16
    -17
      macosx/JackMachThread.cpp
  6. +3
    -0
      macosx/JackMachThread.h
  7. +142
    -96
      windows/JackWinThread.cpp
  8. +5
    -0
      windows/JackWinThread.h

+ 28
- 6
common/JackAPI.cpp View File

@@ -26,6 +26,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackGlobals.h"
#include "JackTime.h"
#include "JackExports.h"
#ifdef __APPLE__
#include "JackMachThread.h"
#elif WIN32
#include "JackWinThread.h"
#else
#include "JackPosixThread.h"
#endif
#include <math.h>

using namespace Jack;
@@ -1073,8 +1080,13 @@ EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client)

EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority)
{
JackLog("jack_acquire_real_time_scheduling: not yet implemented\n");
return -1;
#ifdef __APPLE__
return JackMachThread::AcquireRealTimeImp(thread, 0, 500 * 1000, 500 * 1000);
#elif WIN32
return JackWinThread::AcquireRealTimeImp(thread, priority);
#else
return JackPosixThread::AcquireRealTimeImp(thread, priority);
#endif
}

EXPORT int jack_client_create_thread(jack_client_t* client,
@@ -1084,14 +1096,24 @@ EXPORT int jack_client_create_thread(jack_client_t* client,
void *(*start_routine)(void*),
void *arg)
{
JackLog("jack_client_create_thread: not yet implemented\n");
return -1;
#ifdef __APPLE__
return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg);
#elif WIN32
return JackWinThread::StartImp(thread, priority, realtime, start_routine, arg);
#else
return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg);
#endif
}

EXPORT int jack_drop_real_time_scheduling(pthread_t thread)
{
JackLog("jack_drop_real_time_scheduling: not yet implemented\n");
return -1;
#ifdef __APPLE__
return JackMachThread::DropRealTimeImp(thread);
#elif WIN32
return JackWinThread::DropRealTimeImp(thread);
#else
return JackPosixThread::DropRealTimeImp(thread);
#endif
}

// intclient.h


+ 36
- 22
common/JackPosixThread.cpp View File

@@ -56,10 +56,22 @@ void* JackPosixThread::ThreadHandler(void* arg)

int JackPosixThread::Start()
{
int res;
fRunning = true;
fRunning = true;
// Check if the thread was correctly started
if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) {
fRunning = false;
return -1;
} else {
return 0;
}
}

if (fRealTime) {
int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg)
{
int res;
if (realtime) {

JackLog("Create RT thread\n");

@@ -98,14 +110,14 @@ int JackPosixThread::Start()
}

memset(&rt_param, 0, sizeof(rt_param));
rt_param.sched_priority = fPriority;
rt_param.sched_priority = priority;

if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) {
jack_error("Cannot set scheduling priority for RT thread %d %s", res, strerror(errno));
return -1;
}

if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) {
if ((res = pthread_create(thread, &attributes, start_routine, arg))) {
jack_error("Cannot set create thread %d %s", res, strerror(errno));
return -1;
}
@@ -114,7 +126,7 @@ int JackPosixThread::Start()
} else {
JackLog("Create non RT thread\n");

if ((res = pthread_create(&fThread, 0, ThreadHandler, this))) {
if ((res = pthread_create(thread, 0, start_routine, arg))) {
jack_error("Cannot set create thread %d %s", res, strerror(errno));
return -1;
}
@@ -159,18 +171,25 @@ int JackPosixThread::Stop()

int JackPosixThread::AcquireRealTime()
{
struct sched_param rtparam;
int res;
return (fThread) ? AcquireRealTimeImp(fThread, fPriority) : -1;
}

if (!fThread)
return -1;
int JackPosixThread::AcquireRealTime(int priority)
{
fPriority = priority;
return AcquireRealTime();
}

int JackPosixThread::AcquireRealTimeImp(pthread_t thread, int priority)
{
struct sched_param rtparam;
int res;
memset(&rtparam, 0, sizeof(rtparam));
rtparam.sched_priority = fPriority;
rtparam.sched_priority = priority;

//if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) {

if ((res = pthread_setschedparam(fThread, SCHED_RR, &rtparam)) != 0) {
if ((res = pthread_setschedparam(thread, SCHED_RR, &rtparam)) != 0) {
jack_error("Cannot use real-time scheduling (FIFO/%d) "
"(%d: %s)", rtparam.sched_priority, res,
strerror(res));
@@ -179,24 +198,19 @@ int JackPosixThread::AcquireRealTime()
return 0;
}

int JackPosixThread::AcquireRealTime(int priority)
int JackPosixThread::DropRealTime()
{
fPriority = priority;
return AcquireRealTime();
return (fThread) ? DropRealTimeImp(fThread) : -1;
}

int JackPosixThread::DropRealTime()
int JackPosixThread::DropRealTimeImp(pthread_t thread)
{
struct sched_param rtparam;
struct sched_param rtparam;
int res;

if (!fThread)
return -1;

memset(&rtparam, 0, sizeof(rtparam));
rtparam.sched_priority = 0;

if ((res = pthread_setschedparam(fThread, SCHED_OTHER, &rtparam)) != 0) {
if ((res = pthread_setschedparam(thread, SCHED_OTHER, &rtparam)) != 0) {
jack_error("Cannot switch to normal scheduling priority(%s)\n", strerror(errno));
return -1;
}


+ 5
- 1
common/JackPosixThread.h View File

@@ -37,7 +37,6 @@ class JackPosixThread : public JackThread
protected:

pthread_t fThread;

static void* ThreadHandler(void* arg);

public:
@@ -65,6 +64,11 @@ class JackPosixThread : public JackThread
virtual int DropRealTime();

pthread_t GetThreadID();
static int AcquireRealTimeImp(pthread_t thread, int priority);
static int DropRealTimeImp(pthread_t thread);
static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg);

};

} // end of namespace


+ 4
- 4
linux/alsa/JackAlsaDriver.cpp View File

@@ -2567,7 +2567,7 @@ extern "C"
capture = TRUE;
if (strcmp (param->value.str, "none") != 0) {
capture_pcm_name = strdup (param->value.str);
printf("capture device %s\n", capture_pcm_name);
printf("capture device %s\n", capture_pcm_name);
}
break;

@@ -2575,7 +2575,7 @@ extern "C"
playback = TRUE;
if (strcmp (param->value.str, "none") != 0) {
playback_pcm_name = strdup (param->value.str);
printf("playback device %s\n", playback_pcm_name);
printf("playback device %s\n", playback_pcm_name);
}
break;

@@ -2587,8 +2587,8 @@ extern "C"
case 'd':
playback_pcm_name = strdup (param->value.str);
capture_pcm_name = strdup (param->value.str);
printf("playback device %s\n", playback_pcm_name);
printf("capture device %s\n", capture_pcm_name);
printf("playback device %s\n", playback_pcm_name);
printf("capture device %s\n", capture_pcm_name);
break;

case 'H':


+ 16
- 17
macosx/JackMachThread.cpp View File

@@ -152,34 +152,33 @@ int JackMachThread::Kill()
}
}

/*
int JackMachThread::AcquireRealTime()
{
JackLog("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld\n",
long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000));
return (fThread) ? SetThreadToPriority(fThread, 96, true, fPeriod, fComputation, fConstraint) : -1;

return (fThread) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1;
}
*/

int JackMachThread::AcquireRealTime()
int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint)
{
JackLog("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld\n",
long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000));
if (fThread) {
SetThreadToPriority(fThread, 96, true, fPeriod, fComputation, fConstraint);
UInt64 fPeriod;
UInt64 fComputation;
UInt64 fConstraint;
GetParams(&fPeriod, &fComputation, &fConstraint);
return 0;
} else
return -1;
SetThreadToPriority(thread, 96, true, period, computation, constraint);
UInt64 int_period;
UInt64 int_computation;
UInt64 int_constraint;
GetParams(&int_period, &int_computation, &int_constraint);
return 0;
}

int JackMachThread::DropRealTime()
{
//return (fThread) ? SetThreadToPriority(fThread, 31, false, 0, 0, 0) : -1;
return (fThread) ? SetThreadToPriority(fThread, 63, false, 0, 0, 0) : -1;
return (fThread) ? DropRealTimeImp(fThread) : -1;
}

int JackMachThread::DropRealTimeImp(pthread_t thread)
{
SetThreadToPriority(thread, 63, false, 0, 0, 0);
return 0;
}

void JackMachThread::SetParams(UInt64 period, UInt64 computation, UInt64 constraint)


+ 3
- 0
macosx/JackMachThread.h View File

@@ -114,6 +114,9 @@ class JackMachThread : public JackPosixThread
void SetParams(UInt64 period, UInt64 computation, UInt64 constraint);
static int GetParams(UInt64* period, UInt64* computation, UInt64* constraint);
static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint);
static int AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint);
static int DropRealTimeImp(pthread_t thread);
};

} // end of namespace


+ 142
- 96
windows/JackWinThread.cpp View File

@@ -68,98 +68,109 @@ JackWinThread::~JackWinThread()
CloseHandle(fEvent);
}

int JackWinThread::Start()
{
DWORD id;
fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (fEvent == NULL) {
jack_error("Cannot create event error = %d", GetLastError());
return -1;
}
fRunning = true;
if (fRealTime) {
JackLog("Create RT thread\n");
fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
if (fThread == NULL) {
jack_error("Cannot create thread error = %d", GetLastError());
return -1;
}
if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) {
jack_error("Cannot set priority class = %d", GetLastError());
return -1;
}
return 0;
} else {
JackLog("Create non RT thread\n");
fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
if (fThread == NULL) {
jack_error("Cannot create thread error = %d", GetLastError());
return -1;
}
return 0;
}
}
int JackWinThread::StartSync()
{
DWORD id;
fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (fEvent == NULL) {
jack_error("Cannot create event error = %d", GetLastError());
return -1;
}
if (fRealTime) {
JackLog("Create RT thread\n");
fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
if (fThread == NULL) {
jack_error("Cannot create thread error = %d", GetLastError());
return -1;
}
if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec
jack_error("Thread has not started");
return -1;
}
if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) {
jack_error("Cannot set priority class = %d", GetLastError());
return -1;
}
return 0;
} else {
JackLog("Create non RT thread\n");
fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);
if (fThread == NULL) {
jack_error("Cannot create thread error = %d", GetLastError());
return -1;
}
if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec
jack_error("Thread has not started");
return -1;
}
return 0;
}
int JackWinThread::Start()
{
fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (fEvent == NULL) {
jack_error("Cannot create event error = %d", GetLastError());
return -1;
}

fRunning = true;
// Check if the thread was correctly started
if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) {
fRunning = false;
return -1;
} else {
return 0;
}
}

int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg);
{
DWORD id;

if (realtime) {

JackLog("Create RT thread\n");
*thread = CreateThread(NULL, 0, start_routine, arg, 0, &id);

if (*thread == NULL) {
jack_error("Cannot create thread error = %d", GetLastError());
return -1;
}

if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) {
jack_error("Cannot set priority class = %d", GetLastError());
return -1;
}

return 0;

} else {

JackLog("Create non RT thread\n");
*thread = CreateThread(NULL, 0, start_routine, arg, 0, &id);

if (fThread == NULL) {
jack_error("Cannot create thread error = %d", GetLastError());
return -1;
}

return 0;
}
}

int JackWinThread::StartSync()
{
DWORD id;

fEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (fEvent == NULL) {
jack_error("Cannot create event error = %d", GetLastError());
return -1;
}

if (fRealTime) {

JackLog("Create RT thread\n");
fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);

if (fThread == NULL) {
jack_error("Cannot create thread error = %d", GetLastError());
return -1;
}

if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec
jack_error("Thread has not started");
return -1;
}

if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) {
jack_error("Cannot set priority class = %d", GetLastError());
return -1;
}

return 0;

} else {

JackLog("Create non RT thread\n");
fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id);

if (fThread == NULL) {
jack_error("Cannot create thread error = %d", GetLastError());
return -1;
}

if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec
jack_error("Thread has not started");
return -1;
}

return 0;
}
}

// voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx
@@ -167,9 +178,9 @@ int JackWinThread::StartSync()
int JackWinThread::Kill()
{
if (fThread) { // If thread has been started
TerminateThread(fThread, 0);
TerminateThread(fThread, 0);
WaitForSingleObject(fThread, INFINITE);
CloseHandle(fThread);
CloseHandle(fThread);
JackLog("JackWinThread::Kill 2\n");
fThread = NULL;
fRunning = false;
@@ -195,6 +206,7 @@ int JackWinThread::Stop()

int JackWinThread::AcquireRealTime()
{
/*
JackLog("JackWinThread::AcquireRealTime\n");

if (fThread) {
@@ -207,14 +219,33 @@ int JackWinThread::AcquireRealTime()
} else {
return -1;
}
*/
return (fThread) ? AcquireRealTimeImp(fThread, fPriority) : -1;
}

int JackWinThread::AcquireRealTime(int priority)
{
JackLog("JackWinThread::AcquireRealTime priority = %ld\n", priority);
return AcquireRealTime();
//JackLog("JackWinThread::AcquireRealTime priority = %ld\n", priority);
//return AcquireRealTime();
fPriority = priority;
return AcquireRealTime();
}

int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority)
{
JackLog("JackWinThread::AcquireRealTime\n");

if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) {
JackLog("JackWinThread::AcquireRealTime OK\n");
return 0;
} else {
jack_error("Cannot set thread priority = %d", GetLastError());
return -1;
}
}

/*
int JackWinThread::DropRealTime()
{
if (fThread) {
@@ -227,6 +258,21 @@ int JackWinThread::DropRealTime()
return -1;
}
}
*/
int JackWinThread::DropRealTime()
{
return DropRealTime(fThread);
}

int JackWinThread::DropRealTime(pthread_t thread)
{
if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) {
return 0;
} else {
jack_error("Cannot set thread priority = %d", GetLastError());
return -1;
}
}

pthread_t JackWinThread::GetThreadID()
{


+ 5
- 0
windows/JackWinThread.h View File

@@ -57,6 +57,11 @@ class JackWinThread : public JackThread
int DropRealTime();

pthread_t GetThreadID();
static int AcquireRealTimeImp(pthread_t thread, int priority);
static int DropRealTimeImp(pthread_t thread);
static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg);

};

} // end of namespace


Loading…
Cancel
Save