Commit 32987ca1 authored by sletz's avatar sletz
Browse files

Merge Solaris branch back on trunk.

git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@3306 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 4117315c
......@@ -25,6 +25,10 @@ Michael Voigt
2009-02-11 Stephane Letz <letz@grame.fr>
* Merge Solaris branch back on trunk.
2009-02-10 Stephane Letz <letz@grame.fr>
* Add a resample quality parameter in netadapter.
2009-02-09 Stephane Letz <letz@grame.fr>
......@@ -76,6 +80,14 @@ Michael Voigt
* Cleanup server starting code for clients directly linked with libjackserver.so.
2009-01-09 Stephane Letz <letz@grame.fr>
* JackProfiler scan already running clients (so can now be added anytime in the graph).
2009-01-09 Stephane Letz <letz@grame.fr>
* New JackProfiler class for real-time server monitoring.
2009-01-07 Stephane Letz <letz@grame.fr>
* Use up to BUFFER_SIZE_MAX frames in midi ports, fix for ticket #117.
......@@ -88,6 +100,8 @@ Michael Voigt
2008-12-18 Stephane Letz <letz@grame.fr>
* For ALSA driver, synchronize with latest jack1 memops functions.
* Use memops functions in JackOSSDriver.
* Use memops functions in JackOSSAdapter.
2008-12-17 Stephane Letz <letz@grame.fr>
......@@ -95,15 +109,37 @@ Michael Voigt
2008-12-16 Stephane Letz <letz@grame.fr>
* Fix JackOSSDriver::SetBufferSize (was crashing when restoring old size), fix ticket #111.
* Force memory page in of profiling array in JackOSSDriver::Open.
* Cleanup profiling code.
* Client and library global context cleanup in case of incorrect shutdown handling (that is applications not correctly closing client after server has shutdown).
2008-12-08 Stephane Letz <letz@grame.fr>
* Forbid JackOSSDriver to run in "aynchronous" mode, correct DSP CPU computation.
2008-12-04 Stephane Letz <letz@grame.fr>
* More profiling in JackOSSDriver: sample conversion duration is measured.
2008-12-02 Stephane Letz <letz@grame.fr>
* Optimize JackOSSDriver: no samples conversion if ports are not connected.
2008-12-01 Stephane Letz <letz@grame.fr>
* Force preload of memory table in JackEngineProfiling.
2008-11-27 Stephane Letz <letz@grame.fr>
* Add timing profiling code in JackOSSDriver.
* Report ringbuffer.c fixes from jack1.
2008-11-21 Stephane Letz <letz@grame.fr>
* Report ringbuffer.c fixes from jack1.
* Better isolation of server and clients system resources to allow starting the server in several user account at the same time.
* Correct ressource cleanup in case of driver open failure.
2008-11-19 Stephane Letz <letz@grame.fr>
......@@ -119,12 +155,13 @@ Michael Voigt
* Fix jackctl_server_unload_internal.
2008-10-30 Stephane Letz <letz@grame.fr>
* Fix Midi port initialization in JackNetDriver.
* Correct JackClient::ShutDown.
* Correct JackClient::ShutDown.
* TimeOut management in JackNetUnixSocket on Solaris.
2008-10-23 Stephane Letz <letz@grame.fr>
* In JackOSSDriver, vmix mode is used by default, exclusif (O_EXCL) mode can be selected with -e option.
* Fix a crash in JackEngine::Close when backend cannot be loaded.
* Tim Blechmann optimization patch.
* Backport of latest Paul alsa_seqmidi changes.
......@@ -147,6 +184,38 @@ Michael Voigt
* Checking for libsamplerate in waf, fix ticket #89."
* Header cleanup, add --clients and --ports options in configure.
2008-09-22 Stephane Letz <letz@grame.fr>
* Socket time out implementation on Solaris.
* Fix a conflict with Audio Hijack in JackCoreAudioDriver.
2008-10-10 Stephane Letz <letz@grame.fr>
* Improve OSS backend : SNDCTL_DSP_SETFRAGMENT must be done before, use of AFMT_S16_LE kind of values.
2008-10-09 Stephane Letz <letz@grame.fr>
* First version of OSS backend.
* Use a mutex to make jack_client_open/jack_client_close thread safe, remove use of jack_init/jack_uninit.
2008-10-08 Stephane Letz <letz@grame.fr>
* Fix a SMP related bug introduced in rev 2957 : remove the __SMP__ flag and define LOCK for SMP in all cases.
2008-10-03 Stephane Letz <letz@grame.fr>
* Add engine profiling tools.
2008-10-02 Stephane Letz <letz@grame.fr>
* Correct file permission for jack-shm-registry POSIX shared memory segment.
* Checking for libsamplerate in waf, fix ticket #89."
* Header cleanup, add --clients and --ports options in configure.
2008-10-01 Stephane Letz <letz@grame.fr>
* First Solaris version.
2008-09-22 Stephane Letz <letz@grame.fr>
* Cleanup jack_port_id_t/jack_port_t mess, should work again on 64 bits machines."
......
......@@ -1098,7 +1098,11 @@ EXPORT jack_port_t* jack_port_register(jack_client_t* ext_client, const char* po
jack_error("jack_port_register called with a NULL port name or a NULL port_type");
return NULL;
} else {
#if defined(__x86_64__) || defined(__ppc64__)
return (jack_port_t *)((uint64_t)client->PortRegister(port_name, port_type, flags, buffer_size));
#else
return (jack_port_t *)client->PortRegister(port_name, port_type, flags, buffer_size);
#endif
}
}
......@@ -1349,7 +1353,11 @@ EXPORT jack_port_t* jack_port_by_name(jack_client_t* ext_client, const char* por
if (!manager)
return NULL;
int res = manager->GetPort(portname); // returns a port index at least > 1
#if defined(__x86_64__) || defined(__ppc64__)
return (res == NO_PORT) ? NULL : (jack_port_t*)((uint64_t)res);
#else
return (res == NO_PORT) ? NULL : (jack_port_t*)res;
#endif
}
}
......@@ -1359,7 +1367,11 @@ EXPORT jack_port_t* jack_port_by_id(jack_client_t* ext_client, jack_port_id_t id
JackLibGlobals::CheckContext();
#endif
/* jack_port_t* type is actually the port index */
#if defined(__x86_64__) || defined(__ppc64__)
return (jack_port_t*)((uint64_t)id);
#else
return (jack_port_t*)id;
#endif
}
EXPORT int jack_engine_takeover_timebase(jack_client_t* ext_client)
......
......@@ -23,8 +23,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <stdlib.h>
#include <assert.h>
#include "driver_interface.h"
#ifdef __linux__
#include "JackAlsaAdapter.h"
#endif
......@@ -37,6 +35,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "JackPortAudioAdapter.h"
#endif
#if defined(__sun__) || defined(sun)
#include "JackOSSAdapter.h"
#endif
#ifdef __cplusplus
extern "C"
{
......@@ -65,6 +67,11 @@ extern "C"
#ifdef __APPLE__
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackCoreAudioAdapter(buffer_size, sample_rate, params));
#endif
#if defined(__sun__) || defined(sun)
adapter = new Jack::JackAudioAdapter(jack_client, new Jack::JackOSSAdapter(buffer_size, sample_rate, params));
#endif
assert(adapter);
if (adapter->Open() == 0)
......
......@@ -33,16 +33,15 @@ namespace Jack
class SERVER_EXPORT JackAudioDriver : public JackDriver
{
private:
protected:
int ProcessAsync();
int ProcessSync();
void ProcessGraphAsync();
void ProcessGraphSync();
void WaitUntilNextCycle();
protected:
virtual int ProcessAsync();
virtual int ProcessSync();
int fCaptureChannels;
int fPlaybackChannels;
......
......@@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#if defined (__APPLE__)
#include <Accelerate/Accelerate.h>
#elif defined (__SSE__)
#elif defined (__SSE__) && !defined (__sun__)
#include <xmmintrin.h>
#endif
......@@ -46,7 +46,7 @@ static inline void MixAudioBuffer(float* mixbuffer, float* buffer, jack_nframes_
frames = frames % 4;
while (frames_group > 0) {
#ifdef __SSE__
#if defined (__SSE__) && !defined (__sun__)
__m128 vec = _mm_add_ps(_mm_load_ps(mixbuffer), _mm_load_ps(buffer));
_mm_store_ps(mixbuffer, vec);
......@@ -97,7 +97,7 @@ static void AudioBufferMixdown(void* mixbuffer, void** src_buffers, int src_coun
void* buffer;
// Copy first buffer
#ifdef __SSE__
#if defined (__SSE__) && !defined (__sun__)
jack_nframes_t frames_group = nframes / 4;
jack_nframes_t remaining_frames = nframes % 4;
......
......@@ -362,7 +362,7 @@ bool JackClient::Execute()
if (GetEngineControl()->fRealTime)
set_threaded_log_function();
if (fThreadFun) {
// Execute a dummy cycle to be sure thread has the correct properties (ensure thread creation is finished)
WaitSync();
......
......@@ -57,17 +57,27 @@
#ifdef WIN32
#define jack_server_dir "server"
#define jack_client_dir "client"
#define ADDON_DIR "jack"
#elif __APPLE__
#define ADDON_DIR "jackmp"
#endif
#ifdef __APPLE__
#define jack_server_dir "/tmp"
#define jack_client_dir "/tmp"
#define JACK_DEFAULT_DRIVER "coreaudio"
#else
#endif
#ifdef __linux__
#define jack_server_dir "/dev/shm"
#define jack_client_dir "/dev/shm"
#define JACK_DEFAULT_DRIVER "alsa"
#endif
#if defined(__sun__) || defined(sun)
#define jack_server_dir "/tmp"
#define jack_client_dir "/tmp"
#define JACK_DEFAULT_DRIVER "oss"
#endif
#define jack_server_entry "jackdmp_entry"
#define jack_client_entry "jack_client"
......
......@@ -21,7 +21,6 @@
*/
#ifndef WIN32
#include <stdbool.h>
#include <stdint.h>
#include <dirent.h>
#include <pthread.h>
......@@ -42,6 +41,7 @@
#include "JackTools.h"
#include "JackControlAPI.h"
#include "JackLockedEngine.h"
#include "JackConstants.h"
using namespace Jack;
......@@ -561,7 +561,11 @@ jackctl_wait_signals(sigset_t signals)
bool waiting = true;
while (waiting) {
#if defined(sun) && !defined(__sun__) // SUN compiler only, to check
sigwait(&signals);
#else
sigwait(&signals, &sig);
#endif
fprintf(stderr, "jack main caught signal %d\n", sig);
switch (sig) {
......
......@@ -467,6 +467,17 @@ int JackEngine::GetClientPID(const char* name)
return 0;
}
int JackEngine::GetClientRefNum(const char* name)
{
for (int i = 0; i < CLIENT_NUM; i++) {
JackClientInterface* client = fClientTable[i];
if (client && (strcmp(client->GetClientControl()->fName, name) == 0))
return client->GetClientControl()->fRefNum;
}
return -1;
}
// Used for external clients
int JackEngine::ClientExternalOpen(const char* name, int pid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager)
{
......
......@@ -91,6 +91,7 @@ class SERVER_EXPORT JackEngine
int ClientDeactivate(int refnum);
int GetClientPID(const char* name);
int GetClientRefNum(const char* name);
// Internal client management
int GetInternalClientName(int int_ref, char* name_res);
......
......@@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
namespace Jack
{
static inline _jack_time_t JACK_MAX(_jack_time_t a, _jack_time_t b)
static inline jack_time_t JACK_MAX(jack_time_t a, jack_time_t b)
{
return (a < b) ? b : a;
}
......@@ -46,6 +46,9 @@ void JackEngineControl::CycleBegin(JackClientInterface** table,
{
fTransport.CycleBegin(fSampleRate, cur_cycle_begin);
CalcCPULoad(table, manager, cur_cycle_begin, prev_cycle_end);
#ifdef JACK_MONITOR
fProfiler.Profile(table, manager, fPeriodUsecs, cur_cycle_begin, prev_cycle_end);
#endif
}
void JackEngineControl::CycleEnd(JackClientInterface** table)
......
......@@ -24,9 +24,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "JackShmMem.h"
#include "JackFrameTimer.h"
#include "JackTransportEngine.h"
#include "JackConstants.h"
#include "types.h"
#include <stdio.h>
#ifdef JACK_MONITOR
#include "JackEngineProfiling.h"
#endif
namespace Jack
{
......@@ -78,6 +83,10 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem
// Timer
JackFrameTimer fFrameTimer;
#ifdef JACK_MONITOR
JackEngineProfiling fProfiler;
#endif
JackEngineControl(bool sync, bool temporary, long timeout, bool rt, long priority, bool verbose, const char* server_name)
{
......@@ -105,6 +114,7 @@ struct SERVER_EXPORT JackEngineControl : public JackShmMem
fMaxDelayedUsecs = 0.f;
fXrunDelayedUsecs = 0.f;
}
~JackEngineControl()
{}
......
/*
Copyright (C) 2008 Grame & RTL
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 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
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "JackEngineProfiling.h"
#include "JackGraphManager.h"
#include "JackClientControl.h"
#include "JackClientInterface.h"
#include "JackTime.h"
namespace Jack
{
JackEngineProfiling::JackEngineProfiling():fAudioCycle(0)
{
jack_info("Engine profiling activated, beware %ld MBytes are needed to record profiling points...", sizeof(fProfileTable) / (1024 * 1024));
// Force memory page in
memset(fProfileTable, 0, sizeof(fProfileTable));
}
JackEngineProfiling::~JackEngineProfiling()
{
// Window monitoring
int max_client = 0;
char buffer[1024];
char* nameTable[CLIENT_NUM];
FILE* file = fopen("JackEngineProfiling.log", "w");
jack_info("Write server and clients timing data...");
if (file == NULL) {
jack_error("JackEngineProfiling::Save cannot open JackEngineProfiling.log file");
} else {
for (int i = 2; i < TIME_POINTS; i++) {
bool header = true;
bool printed = false;
int count = 0;
for (int j = REAL_REFNUM; j < CLIENT_NUM; j++) {
if (fProfileTable[i].fClientTable[j].fRefNum > 0) {
long d1 = long(fProfileTable[i - 1].fCurCycleBegin - fProfileTable[i - 2].fCurCycleBegin);
long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin);
if (d1 > 0 && fProfileTable[i].fClientTable[j].fStatus != NotTriggered) { // Valid cycle
count++;
nameTable[count] = fNameTable[fProfileTable[i].fClientTable[j].fRefNum];
// driver delta and end cycle
if (header) {
fprintf(file, "%ld \t %ld \t", d1, d2);
header = false;
}
long d5 = long(fProfileTable[i].fClientTable[j].fSignaledAt - fProfileTable[i - 1].fCurCycleBegin);
long d6 = long(fProfileTable[i].fClientTable[j].fAwakeAt - fProfileTable[i - 1].fCurCycleBegin);
long d7 = long(fProfileTable[i].fClientTable[j].fFinishedAt - fProfileTable[i - 1].fCurCycleBegin);
// ref, signal, start, end, scheduling, duration, status
fprintf(file, "%d \t %ld \t %ld \t %ld \t %ld \t %ld \t %d \t",
fProfileTable[i].fClientTable[j].fRefNum,
((d5 > 0) ? d5 : 0),
((d6 > 0) ? d6 : 0),
((d7 > 0) ? d7 : 0),
((d6 > 0 && d5 > 0) ? (d6 - d5) : 0),
((d7 > 0 && d6 > 0) ? (d7 - d6) : 0),
fProfileTable[i].fClientTable[j].fStatus);
printed = true;
}
}
max_client = (count > max_client) ? count : max_client;
}
if (printed) {
fprintf(file, "\n");
} else if (fProfileTable[i].fAudioCycle > 0) { // Driver timing only
long d1 = long(fProfileTable[i].fCurCycleBegin - fProfileTable[i - 1].fCurCycleBegin);
long d2 = long(fProfileTable[i].fPrevCycleEnd - fProfileTable[i - 1].fCurCycleBegin);
if (d1 > 0) { // Valid cycle
fprintf(file, "%ld \t %ld \n", d1, d2);
}
}
}
fclose(file);
}
// Driver period
file = fopen("Timing1.plot", "w");
if (file == NULL) {
jack_error("JackEngineProfiling::Save cannot open Timing1.log file");
} else {
fprintf(file, "set grid\n");
fprintf(file, "set title \"Audio driver timing\"\n");
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"usec\"\n");
fprintf(file, "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n");
fprintf(file, "set output 'Timing1.pdf\n");
fprintf(file, "set terminal pdf\n");
fprintf(file, "set grid\n");
fprintf(file, "set title \"Audio driver timing\"\n");
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"usec\"\n");
fprintf(file, "plot \"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines \n");
fclose(file);
}
// Driver end date
file = fopen("Timing2.plot", "w");
if (file == NULL) {
jack_error("JackEngineProfiling::Save cannot open Timing2.log file");
} else {
fprintf(file, "set grid\n");
fprintf(file, "set title \"Driver end date\"\n");
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"usec\"\n");
fprintf(file, "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n");
fprintf(file, "set output 'Timing2.pdf\n");
fprintf(file, "set terminal pdf\n");
fprintf(file, "set grid\n");
fprintf(file, "set title \"Driver end date\"\n");
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"usec\"\n");
fprintf(file, "plot \"JackEngineProfiling.log\" using 2 title \"Driver end date\" with lines \n");
fclose(file);
}
// Clients end date
if (max_client > 0) {
file = fopen("Timing3.plot", "w");
if (file == NULL) {
jack_error("JackEngineProfiling::Save cannot open Timing3.log file");
} else {
fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n");
fprintf(file, "set title \"Clients end date\"\n");
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"usec\"\n");
fprintf(file, "plot ");
for (int i = 0; i < max_client; i++) {
if (i == 0) {
if ((i + 1) == max_client) {
sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines",
((i + 1) * 7) - 1 , nameTable[(i + 1)]);
} else {
sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,",
((i + 1) * 7) - 1 , nameTable[(i + 1)]);
}
} else if ((i + 1) == max_client) { // Last client
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , nameTable[(i + 1)]);
} else {
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, nameTable[(i + 1)]);
}
fprintf(file, buffer);
}
fprintf(file, "\n unset multiplot\n");
fprintf(file, "set output 'Timing3.pdf\n");
fprintf(file, "set terminal pdf\n");
fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n");
fprintf(file, "set title \"Clients end date\"\n");
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"usec\"\n");
fprintf(file, "plot ");
for (int i = 0; i < max_client; i++) {
if (i == 0) {
if ((i + 1) == max_client) {
sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines",
((i + 1) * 7) - 1 , nameTable[(i + 1)]);
} else {
sprintf(buffer, "\"JackEngineProfiling.log\" using 1 title \"Audio period\" with lines,\"JackEngineProfiling.log\" using %d title \"%s\" with lines,",
((i + 1) * 7) - 1 , nameTable[(i + 1)]);
}
} else if ((i + 1) == max_client) { // Last client
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7) - 1 , nameTable[(i + 1)]);
} else {
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines,", ((i + 1) * 7) - 1, nameTable[(i + 1)]);
}
fprintf(file, buffer);
}
fclose(file);
}
}
// Clients scheduling
if (max_client > 0) {
file = fopen("Timing4.plot", "w");
if (file == NULL) {
jack_error("JackEngineProfiling::Save cannot open Timing4.log file");
} else {
fprintf(file, "set multiplot\n");
fprintf(file, "set grid\n");
fprintf(file, "set title \"Clients scheduling latency\"\n");
fprintf(file, "set xlabel \"audio cycles\"\n");
fprintf(file, "set ylabel \"usec\"\n");
fprintf(file, "plot ");
for (int i = 0; i < max_client; i++) {
if ((i + 1) == max_client) // Last client
sprintf(buffer, "\"JackEngineProfiling.log\" using %d title \"%s\" with lines", ((i + 1) * 7), nameTable[(i + 1)]);