Browse Source

macosx port

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@395 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
letz 22 years ago
parent
commit
96562b1a8a
10 changed files with 395 additions and 80 deletions
  1. +9
    -1
      jack/engine.h
  2. +42
    -4
      jack/internal.h
  3. +12
    -1
      jack/time.h
  4. +4
    -0
      jack/types.h
  5. +1
    -1
      jack/version.h.in
  6. +159
    -56
      jackd/engine.c
  7. +1
    -1
      jackd/jackd.c
  8. +148
    -12
      libjack/client.c
  9. +7
    -1
      libjack/local.h
  10. +12
    -3
      libjack/shm.c

+ 9
- 1
jack/engine.h View File

@@ -36,6 +36,7 @@ struct _jack_engine {


int (*set_buffer_size)(struct _jack_engine *, jack_nframes_t frames); int (*set_buffer_size)(struct _jack_engine *, jack_nframes_t frames);
int (*set_sample_rate)(struct _jack_engine *, jack_nframes_t frames); int (*set_sample_rate)(struct _jack_engine *, jack_nframes_t frames);
int (*run_cycle)(struct _jack_engine *, jack_nframes_t nframes, float delayed_usecs);


/* "private" sections starts here */ /* "private" sections starts here */


@@ -85,12 +86,19 @@ struct _jack_engine {
#define JACK_ENGINE_ROLLING_COUNT 32 #define JACK_ENGINE_ROLLING_COUNT 32
#define JACK_ENGINE_ROLLING_INTERVAL 1024 #define JACK_ENGINE_ROLLING_INTERVAL 1024


float rolling_client_usecs[JACK_ENGINE_ROLLING_COUNT];
jack_time_t rolling_client_usecs[JACK_ENGINE_ROLLING_COUNT];
int rolling_client_usecs_cnt; int rolling_client_usecs_cnt;
int rolling_client_usecs_index; int rolling_client_usecs_index;
int rolling_interval; int rolling_interval;
float spare_usecs; float spare_usecs;
float usecs_per_cycle; float usecs_per_cycle;
#if defined(__APPLE__) && defined(__POWERPC__)
/* specific ressources for server/client real-time thread communication */
mach_port_t servertask, bp;
int portnum;
#endif
}; };


/* public functions */ /* public functions */


+ 42
- 4
jack/internal.h View File

@@ -29,6 +29,10 @@
#include <sys/time.h> #include <sys/time.h>
#include <pthread.h> #include <pthread.h>


#if defined(__APPLE__) && defined(__POWERPC__)
#include "mach_port.h"
#endif

#include <jack/jack.h> #include <jack/jack.h>
#include <jack/types.h> #include <jack/types.h>
#include <jack/port.h> #include <jack/port.h>
@@ -39,7 +43,11 @@
#define DEBUG(format,args...) \ #define DEBUG(format,args...) \
printf ("jack:%5d:%Lu %s:%s:%d: " format "\n", getpid(), jack_get_microseconds(), __FILE__, __FUNCTION__, __LINE__ , ## args) printf ("jack:%5d:%Lu %s:%s:%d: " format "\n", getpid(), jack_get_microseconds(), __FILE__, __FUNCTION__, __LINE__ , ## args)
#else #else
#define DEBUG(format,args...)
#if defined(linux)
#define DEBUG(format,args...)
#elif defined(__APPLE__) && defined(__POWERPC__)
#define DEBUG(format...)
#endif
#endif #endif


#ifndef FALSE #ifndef FALSE
@@ -220,6 +228,11 @@ typedef struct {
*/ */


unsigned long n_port_types; unsigned long n_port_types;
#if defined(__APPLE__) && defined(__POWERPC__)
/* specific ressources for server/client real-time thread communication */
int portnum;
#endif


} jack_client_connect_result_t; } jack_client_connect_result_t;


@@ -271,6 +284,34 @@ struct _jack_request {
int status; int status;
}; };


typedef struct _jack_client_internal {

jack_client_control_t *control;

int request_fd;
int event_fd;
int subgraph_start_fd;
int subgraph_wait_fd;
JSList *ports; /* protected by engine->client_lock */
JSList *fed_by; /* protected by engine->client_lock */
shm_name_t shm_name;
unsigned long execution_order;
struct _jack_client_internal *next_client; /* not a linked list! */
dlhandle handle;
int (*initialize)(jack_client_t*, const char*); /* for internal clients only */
void (*finish)(void); /* for internal clients only */
int error;
#if defined(__APPLE__) && defined(__POWERPC__)
/* specific ressources for server/client real-time thread communication */
mach_port_t serverport;
trivial_message message;
int running;
int portnum;
#endif
} jack_client_internal_t;

extern void jack_cleanup_files (); extern void jack_cleanup_files ();


extern int jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event); extern int jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event);
@@ -293,6 +334,3 @@ extern void jack_client_invalidate_port_buffers (jack_client_t *client);


#endif /* __jack_internal_h__ */ #endif /* __jack_internal_h__ */






+ 12
- 1
jack/time.h View File

@@ -38,6 +38,17 @@ static inline jack_time_t jack_get_microseconds (void) {
} }




#endif /* x86 */
#elif defined(__APPLE__) && defined(__POWERPC__)

#include <mach/mach_time.h>

extern double __jack_time_ratio;

static inline jack_time_t jack_get_microseconds(void)
{
return mach_absolute_time () * __jack_time_ratio;
}

#endif


#endif /* __jack_time_h__ */ #endif /* __jack_time_h__ */

+ 4
- 0
jack/types.h View File

@@ -40,7 +40,11 @@ typedef unsigned long jack_nframes_t;
* monotonic clock with units of microseconds. * monotonic clock with units of microseconds.
*/ */


#if defined(linux)
typedef unsigned long long jack_time_t; typedef unsigned long long jack_time_t;
#elif defined(__APPLE__) && defined(__POWERPC__)
typedef double jack_time_t;
#endif


/** /**
* jack_port_t is an opaque type. You may only access it using the API provided. * jack_port_t is an opaque type. You may only access it using the API provided.


+ 1
- 1
jack/version.h.in View File

@@ -16,4 +16,4 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


*/ */
const unsigned int jack_protocol_version = @JACK_PROTOCOL_VERSION@;
#define jack_protocol_version @JACK_PROTOCOL_VERSION@

+ 159
- 56
jackd/engine.c View File

@@ -21,7 +21,14 @@
#include <math.h> #include <math.h>
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/poll.h>

#if defined(linux)
#include <sys/poll.h>
#elif defined(__APPLE__) && defined(__POWERPC__)
#include "fakepoll.h"
#include "ipc.h"
#endif

#include <sys/un.h> #include <sys/un.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
@@ -60,26 +67,6 @@ typedef struct {


} jack_connection_internal_t; } jack_connection_internal_t;


typedef struct _jack_client_internal {

jack_client_control_t *control;

int request_fd;
int event_fd;
int subgraph_start_fd;
int subgraph_wait_fd;
JSList *ports; /* protected by engine->client_lock */
JSList *fed_by; /* protected by engine->client_lock */
shm_name_t shm_name;
unsigned long execution_order;
struct _jack_client_internal *next_client; /* not a linked list! */
dlhandle handle;
int (*initialize)(jack_client_t*, const char*); /* for internal clients only */
void (*finish)(void); /* for internal clients only */
int error;

} jack_client_internal_t;

typedef struct _jack_driver_info { typedef struct _jack_driver_info {
jack_driver_t *(*initialize)(jack_client_t*, int, char**); jack_driver_t *(*initialize)(jack_client_t*, int, char**);
void (*finish); void (*finish);
@@ -123,6 +110,7 @@ static void jack_engine_post_process (jack_engine_t *);
static int internal_client_request (void*, jack_request_t *); static int internal_client_request (void*, jack_request_t *);


static int jack_use_driver (jack_engine_t *engine, jack_driver_t *driver); static int jack_use_driver (jack_engine_t *engine, jack_driver_t *driver);
static int jack_run_cycle (jack_engine_t *engine, jack_nframes_t nframes, float delayed_usecs);


static char *client_state_names[] = { static char *client_state_names[] = {
"Not triggered", "Not triggered",
@@ -300,6 +288,7 @@ jack_resize_port_segment (jack_engine_t *engine, jack_port_type_info_t *port_typ
size_t one_buffer; size_t one_buffer;
size_t size; size_t size;
int shmid; int shmid;
int perm;


if (port_type->buffer_scale_factor < 0) { if (port_type->buffer_scale_factor < 0) {
one_buffer = port_type->buffer_size; one_buffer = port_type->buffer_size;
@@ -308,13 +297,20 @@ jack_resize_port_segment (jack_engine_t *engine, jack_port_type_info_t *port_typ
} }


size = nports * one_buffer; size = nports * one_buffer;
#if defined(linux)
perm = O_RDWR|O_CREAT|O_TRUNC;
#elif defined(__APPLE__) && defined(__POWERPC__)
/* using O_TRUNC option does not work on Darwin */
perm = O_RDWR|O_CREAT;
#endif


if (port_type->shm_info.size == 0) { if (port_type->shm_info.size == 0) {

snprintf (port_type->shm_info.shm_name, sizeof(port_type->shm_info.shm_name), "/jck-[%s]", port_type->type_name);
snprintf (port_type->shm_info.shm_name, sizeof(port_type->shm_info.shm_name), "/jck-[%s]", port_type->type_name);


if ((addr = jack_get_shm (port_type->shm_info.shm_name, size, if ((addr = jack_get_shm (port_type->shm_info.shm_name, size,
(O_RDWR|O_CREAT|O_TRUNC), 0666, PROT_READ|PROT_WRITE, &shmid)) == MAP_FAILED) {
perm, 0666, PROT_READ|PROT_WRITE, &shmid)) == MAP_FAILED) {
jack_error ("cannot create new port segment of %d bytes, shm_name = %s (%s)", jack_error ("cannot create new port segment of %d bytes, shm_name = %s (%s)",
size, port_type->shm_info.shm_name, strerror (errno)); size, port_type->shm_info.shm_name, strerror (errno));
return -1; return -1;
@@ -326,7 +322,7 @@ jack_resize_port_segment (jack_engine_t *engine, jack_port_type_info_t *port_typ
} else { } else {


if ((addr = jack_resize_shm (port_type->shm_info.shm_name, size, if ((addr = jack_resize_shm (port_type->shm_info.shm_name, size,
(O_RDWR|O_CREAT|O_TRUNC), 0666, PROT_READ|PROT_WRITE)) == MAP_FAILED) {
perm, 0666, PROT_READ|PROT_WRITE)) == MAP_FAILED) {
jack_error ("cannot resize port segment to %d bytes, shm_name = %s (%s)", jack_error ("cannot resize port segment to %d bytes, shm_name = %s (%s)",
size, port_type->shm_info.shm_name, strerror (errno)); size, port_type->shm_info.shm_name, strerror (errno));
return -1; return -1;
@@ -444,6 +440,7 @@ jack_process_internal(jack_engine_t *engine, JSList *node, jack_nframes_t nframe
return jack_slist_next (node); return jack_slist_next (node);
} }


#if defined(linux)
static JSList * static JSList *
jack_process_external(jack_engine_t *engine, JSList *node) jack_process_external(jack_engine_t *engine, JSList *node)
{ {
@@ -557,6 +554,31 @@ jack_process_external(jack_engine_t *engine, JSList *node)
return node; return node;
} }


#elif defined(__APPLE__) && defined(__POWERPC__)

static JSList *
jack_process_external(jack_engine_t *engine, JSList *node)
{
jack_client_internal_t * client = (jack_client_internal_t *) node->data;
jack_client_control_t *ctl;
client = (jack_client_internal_t *) node->data;
ctl = client->control;
engine->current_client = client;
ctl->state = Triggered; // a race exists if we do this after the write(2)
ctl->signalled_at = jack_get_microseconds();
ctl->awake_at = 0;
ctl->finished_at = 0;
jack_client_resume(client);
return jack_slist_next (node);
}
#endif


static int static int
jack_engine_process (jack_engine_t *engine, jack_nframes_t nframes) jack_engine_process (jack_engine_t *engine, jack_nframes_t nframes)
{ {
@@ -821,8 +843,13 @@ setup_client (jack_engine_t *engine, int client_fd, jack_client_connect_request_
res->control_size = engine->control_size; res->control_size = engine->control_size;
res->realtime = engine->control->real_time; res->realtime = engine->control->real_time;
res->realtime_priority = engine->rtpriority - 1; res->realtime_priority = engine->rtpriority - 1;
res->n_port_types = engine->control->n_port_types;

res->n_port_types = engine->control->n_port_types;
#if defined(__APPLE__) && defined(__POWERPC__)
/* specific ressources for server/client real-time thread communication */
res->portnum = client->portnum;
#endif
if (jack_client_is_internal(client)) { if (jack_client_is_internal(client)) {
/* set up the pointers necessary for the request system /* set up the pointers necessary for the request system
@@ -1603,7 +1630,15 @@ jack_server_thread (void *arg)
} else if (pfd[i].revents & POLLIN) { } else if (pfd[i].revents & POLLIN) {
if (handle_external_client_request (engine, pfd[i].fd)) { if (handle_external_client_request (engine, pfd[i].fd)) {
jack_error ("could not handle external client request"); jack_error ("could not handle external client request");
}
#if defined(__APPLE__) && defined(__POWERPC__)
/* poll is implemented using select (see the fakepool code). When the socket is closed
select does not return any error, POLLIN is true and the next read will return 0 bytes.
This behaviour is diffrent from the Linux poll behaviour. Thus we use this condition
as a socket error and remove the client.
*/
handle_client_socket_error(engine, pfd[i].fd);
#endif
}
} }
} }
@@ -1663,6 +1698,8 @@ jack_engine_new (int realtime, int rtpriority, int verbose, int client_timeout)
void *addr; void *addr;
unsigned int i; unsigned int i;
int shmid; int shmid;
int perm;
#ifdef USE_CAPABILITIES #ifdef USE_CAPABILITIES
uid_t uid = getuid (); uid_t uid = getuid ();
uid_t euid = geteuid (); uid_t euid = geteuid ();
@@ -1674,6 +1711,7 @@ jack_engine_new (int realtime, int rtpriority, int verbose, int client_timeout)
engine->driver = 0; engine->driver = 0;
engine->set_sample_rate = jack_set_sample_rate; engine->set_sample_rate = jack_set_sample_rate;
engine->set_buffer_size = jack_set_buffer_size; engine->set_buffer_size = jack_set_buffer_size;
engine->run_cycle = jack_run_cycle;
engine->client_timeout_msecs = client_timeout; engine->client_timeout_msecs = client_timeout;


engine->next_client_id = 1; engine->next_client_id = 1;
@@ -1712,9 +1750,16 @@ jack_engine_new (int realtime, int rtpriority, int verbose, int client_timeout)
if (jack_initialize_shm (engine)) { if (jack_initialize_shm (engine)) {
return 0; return 0;
} }
#if defined(linux)
perm = O_RDWR|O_CREAT|O_TRUNC;
#elif defined(__APPLE__) && defined(__POWERPC__)
/* using O_TRUNC option does not work on Darwin */
perm = O_RDWR|O_CREAT;
#endif


if ((addr = jack_get_shm (engine->control_shm_name, engine->control_size, if ((addr = jack_get_shm (engine->control_shm_name, engine->control_size,
O_RDWR|O_CREAT|O_TRUNC, 0644, PROT_READ|PROT_WRITE, &shmid)) == MAP_FAILED) {
perm, 0644, PROT_READ|PROT_WRITE, &shmid)) == MAP_FAILED) {
jack_error ("cannot create engine control shared memory segment (%s)", strerror (errno)); jack_error ("cannot create engine control shared memory segment (%s)", strerror (errno));
return 0; return 0;
} }
@@ -1782,6 +1827,18 @@ jack_engine_new (int realtime, int rtpriority, int verbose, int client_timeout)
engine->control->internal = 0; engine->control->internal = 0;


engine->control->has_capabilities = 0; engine->control->has_capabilities = 0;
#if defined(__APPLE__) && defined(__POWERPC__)
/* specific ressources for server/client real-time thread communication */
engine->servertask = mach_task_self();
if (task_get_bootstrap_port(engine->servertask, &engine->bp)){
jack_error("Jackd: Can't find bootstrap mach port");
return 0;
}
engine->portnum = 0;
#endif
#ifdef USE_CAPABILITIES #ifdef USE_CAPABILITIES
if (uid == 0 || euid == 0) { if (uid == 0 || euid == 0) {
if (engine->verbose) { if (engine->verbose) {
@@ -1829,12 +1886,15 @@ jack_become_real_time (pthread_t thread, int priority)
jack_error ("cannot set thread to real-time priority (FIFO/%d) (%d: %s)", rtparam.sched_priority, x, strerror (errno)); jack_error ("cannot set thread to real-time priority (FIFO/%d) (%d: %s)", rtparam.sched_priority, x, strerror (errno));
return -1; return -1;
} }

if (mlockall (MCL_CURRENT | MCL_FUTURE) != 0) {
#if defined(linux)
if (mlockall (MCL_CURRENT | MCL_FUTURE) != 0) {
jack_error ("cannot lock down memory for RT thread (%s)", strerror (errno)); jack_error ("cannot lock down memory for RT thread (%s)", strerror (errno));
return -1; return -1;
} }

#elif defined(__APPLE__) && defined(__POWERPC__)
// To be implemented
#endif
return 0; return 0;
} }


@@ -2058,6 +2118,8 @@ jack_main_thread (void *arg)
} }


pthread_exit (0); pthread_exit (0);
return 0;
} }


int int
@@ -2075,19 +2137,26 @@ jack_run (jack_engine_t *engine)
#endif /* HAVE_ATEXIT */ #endif /* HAVE_ATEXIT */
#endif /* HAVE_ON_EXIT */ #endif /* HAVE_ON_EXIT */


if (engine->driver == NULL) {
jack_error ("engine driver not set; cannot start");
return -1;
}
if (engine->driver == NULL) {
jack_error ("engine driver not set; cannot start");
return -1;
}

if (engine->driver->start (engine->driver)) {
jack_error ("cannot start driver");
return -1;
}
#if defined(linux)
return pthread_create (&engine->main_thread, 0, jack_main_thread, engine);
#elif defined(__APPLE__) && defined(__POWERPC__)
return 0;
#endif


if (engine->driver->start (engine->driver)) {
jack_error ("cannot start driver");
return -1;
}
return pthread_create (&engine->main_thread, 0, jack_main_thread, engine);
} }



#if defined(linux)
int int
jack_wait (jack_engine_t *engine) jack_wait (jack_engine_t *engine)
{ {
@@ -2112,11 +2181,27 @@ jack_wait (jack_engine_t *engine)
return (int) ((intptr_t)ret); return (int) ((intptr_t)ret);
} }


#elif defined(__APPLE__) && defined(__POWERPC__)

int
jack_wait (jack_engine_t *engine)
{
while(1) sleep(1);
}

#endif

int int
jack_engine_delete (jack_engine_t *engine) jack_engine_delete (jack_engine_t *engine)
{ {
if (engine) { if (engine) {
return pthread_cancel (engine->main_thread);

#if defined(linux)
return pthread_cancel (engine->main_thread);
#elif defined(__APPLE__) && defined(__POWERPC__)
/* the jack_run_cycle function is directly called from the CoreAudo audio callback */
return 0;
#endif
} }


return 0; return 0;
@@ -2128,6 +2213,7 @@ jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_req
jack_client_internal_t *client; jack_client_internal_t *client;
shm_name_t shm_name; shm_name_t shm_name;
int shmid; int shmid;
int perm;
void *addr = 0; void *addr = 0;


switch (req->type) { switch (req->type) {
@@ -2136,17 +2222,24 @@ jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_req
break; break;


case ClientExternal: case ClientExternal:

snprintf (shm_name, sizeof (shm_name), "/jack-c-%s", req->name);
if ((addr = jack_get_shm (shm_name, sizeof (jack_client_control_t),
(O_RDWR|O_CREAT|O_TRUNC), 0666, PROT_READ|PROT_WRITE, &shmid)) == MAP_FAILED) {
jack_error ("cannot create client control block for %s", req->name);
return 0;
}
jack_register_shm (shm_name, addr, shmid);
break;
}

#if defined(linux)
perm = O_RDWR|O_CREAT|O_TRUNC;
#elif defined(__APPLE__) && defined(__POWERPC__)
/* using O_TRUNC option does not work on Darwin */
perm = O_RDWR|O_CREAT;
#endif
snprintf (shm_name, sizeof (shm_name), "/jack-c-%s", req->name);
if ((addr = jack_get_shm (shm_name, sizeof (jack_client_control_t),
perm, 0666, PROT_READ|PROT_WRITE, &shmid)) == MAP_FAILED) {
jack_error ("cannot create client control block for %s", req->name);
return 0;
}
jack_register_shm (shm_name, addr, shmid);
break;
}
client = (jack_client_internal_t *) malloc (sizeof (jack_client_internal_t)); client = (jack_client_internal_t *) malloc (sizeof (jack_client_internal_t));


client->request_fd = fd; client->request_fd = fd;
@@ -2189,7 +2282,12 @@ jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_req
client->control->port_register_arg = NULL; client->control->port_register_arg = NULL;
client->control->graph_order = NULL; client->control->graph_order = NULL;
client->control->graph_order_arg = NULL; client->control->graph_order_arg = NULL;

#if defined(__APPLE__) && defined(__POWERPC__)
/* specific ressources for server/client real-time thread communication */
allocate_mach_serverport(engine, client);
client->running = FALSE;
#endif
if (req->type == ClientInternal) { if (req->type == ClientInternal) {
if (jack_load_client (engine, client, req->object_path)) { if (jack_load_client (engine, client, req->object_path)) {
jack_error ("cannot dynamically load client from \"%s\"", req->object_path); jack_error ("cannot dynamically load client from \"%s\"", req->object_path);
@@ -3128,7 +3226,12 @@ jack_get_fifo_fd (jack_engine_t *engine, unsigned int which_fifo)


if (stat (path, &statbuf)) { if (stat (path, &statbuf)) {
if (errno == ENOENT) { if (errno == ENOENT) {
if (mknod (path, 0666|S_IFIFO, 0) < 0) {
#if defined(linux)
if (mknod (path, 0666|S_IFIFO, 0) < 0) {
#elif defined(__APPLE__) && defined(__POWERPC__)
if (mkfifo(path,0666) < 0){
#endif
jack_error ("cannot create inter-client FIFO [%s] (%s)\n", path, strerror (errno)); jack_error ("cannot create inter-client FIFO [%s] (%s)\n", path, strerror (errno));
return -1; return -1;
} }


+ 1
- 1
jackd/jackd.c View File

@@ -23,9 +23,9 @@
#include <getopt.h> #include <getopt.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <sys/wait.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <wait.h>


#include <config.h> #include <config.h>




+ 148
- 12
libjack/client.c View File

@@ -18,6 +18,14 @@
$Id$ $Id$
*/ */


#if defined(linux)
#include <sys/poll.h>
#elif defined(__APPLE__) && defined(__POWERPC__)
#include "pThreadUtilities.h"
#include "ipc.h"
#include "fakepoll.h"
#endif

#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <pthread.h> #include <pthread.h>
@@ -26,7 +34,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/poll.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <regex.h> #include <regex.h>
@@ -50,7 +58,7 @@
#include <jack/timestamps.h> #include <jack/timestamps.h>
#endif /* WITH_TIMESTAMPS */ #endif /* WITH_TIMESTAMPS */


jack_time_t __jack_cpu_mhz;




#ifdef DEFAULT_TMP_DIR #ifdef DEFAULT_TMP_DIR
@@ -535,8 +543,22 @@ jack_client_new (const char *client_name)
} }


client->event_fd = ev_fd; client->event_fd = ev_fd;

return client;
#if defined(__APPLE__) && defined(__POWERPC__)
/* specific ressources for server/client real-time thread communication */
client->clienttask = mach_task_self();
if (task_get_bootstrap_port(client->clienttask, &client->bp)){
jack_error ("Can't find bootstrap port");
goto fail;
}
if (allocate_mach_clientport(client, res.portnum) < 0) {
jack_error("Can't allocate mach port");
goto fail;
};
#endif
return client;
fail: fail:
if (client->engine) { if (client->engine) {
@@ -670,6 +692,8 @@ jack_client_thread (void *arg)
status = -1; status = -1;
break; break;
} }
pthread_testcancel();


/* get an accurate timestamp on waking from poll for a process() /* get an accurate timestamp on waking from poll for a process()
cycle. cycle.
@@ -837,7 +861,7 @@ jack_client_thread (void *arg)
client->on_shutdown (client->on_shutdown_arg); client->on_shutdown (client->on_shutdown_arg);
} else { } else {
jack_error ("zombified - exiting from JACK"); jack_error ("zombified - exiting from JACK");
jack_client_close (client);
jack_client_close (client); /* Need a fix : possibly make client crash if zombified without shutdown handler */
} }


pthread_exit (0); pthread_exit (0);
@@ -845,6 +869,80 @@ jack_client_thread (void *arg)
return 0; return 0;
} }



#if defined(__APPLE__) && defined(__POWERPC__)
/* real-time thread : separated from the normal client thread, it will communicate with the server using fast mach RPC mechanism */

static void *
jack_client_process_thread (void *arg)
{
jack_client_t *client = (jack_client_t *) arg;
jack_client_control_t *control = client->control;
int err = 0;
client->control->pid = getpid();
DEBUG ("client process thread is now running");
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
while (err == 0) {
if (jack_client_suspend(client) < 0) {
pthread_exit (0);
}
control->awake_at = jack_get_microseconds();
DEBUG ("client resumed");
control->state = Running;

if (control->process) {
if (control->process (control->nframes, control->process_arg) == 0) {
control->state = Finished;
}
} else {
control->state = Finished;
}
control->finished_at = jack_get_microseconds();
#ifdef WITH_TIMESTAMPS
jack_timestamp ("finished");
#endif
DEBUG ("client finished processing at %Lu (elapsed = %f usecs)",
control->finished_at, ((float)(control->finished_at - control->awake_at)));
/* check if we were killed during the process cycle (or whatever) */

if (client->control->dead) {
jack_error ("jack_client_process_thread : client->control->dead");
goto zombie;
}

DEBUG("process cycle fully complete\n");

}
return (void *) ((intptr_t)err);

zombie:
jack_error ("jack_client_process_thread : zombified");
if (client->on_shutdown) {
jack_error ("zombified - calling shutdown handler");
client->on_shutdown (client->on_shutdown_arg);
} else {
jack_error ("zombified - exiting from JACK");
jack_client_close (client); /* Need a fix : possibly make client crash if zombified without shutdown handler */
}

pthread_exit (0);
/*NOTREACHED*/
return 0;
}
#endif
static int static int
jack_start_thread (jack_client_t *client) jack_start_thread (jack_client_t *client)


@@ -884,11 +982,16 @@ jack_start_thread (jack_client_t *client)
jack_error ("Cannot set scheduling priority for RT thread (%s)", strerror (errno)); jack_error ("Cannot set scheduling priority for RT thread (%s)", strerror (errno));
return -1; return -1;
} }

if (mlockall (MCL_CURRENT|MCL_FUTURE)) {
jack_error ("cannot lock down all memory (%s)", strerror (errno));
return -1;
}
#if defined(linux)
if (mlockall (MCL_CURRENT | MCL_FUTURE) != 0) {
jack_error ("cannot lock down memory for RT thread (%s)", strerror (errno));
return -1;
}
#elif defined(__APPLE__) && defined(__POWERPC__)
// To be implemented
#endif
} }


if (pthread_create (&client->thread, attributes, jack_client_thread, client)) { if (pthread_create (&client->thread, attributes, jack_client_thread, client)) {
@@ -902,6 +1005,22 @@ jack_start_thread (jack_client_t *client)
#endif #endif
return -1; return -1;
} }
#if defined(__APPLE__) && defined(__POWERPC__)
/* a spcial real-time thread to call the "process" callback. It will communicate with the server using fast mach RPC mechanism */
if (pthread_create (&client->process_thread, attributes, jack_client_process_thread, client)) {
jack_error("pthread_create failed for process_thread \n");
return -1;
}
if (client->engine->real_time){
/* time constraint thread */
setThreadToPriority(client->process_thread, 96, true, 10000000);
}else{
/* fixed priority thread */
setThreadToPriority(client->process_thread, 63, true, 10000000);
}
#endif
return 0; return 0;


#ifdef USE_CAPABILITIES #ifdef USE_CAPABILITIES
@@ -1001,8 +1120,12 @@ jack_activate (jack_client_t *client)
* actually mapped (more important for mlockall(2) usage in * actually mapped (more important for mlockall(2) usage in
* jack_start_thread()) * jack_start_thread())
*/ */

#define BIG_ENOUGH_STACK 1048576
#if defined(linux)
#define BIG_ENOUGH_STACK 1048576
#elif defined(__APPLE__) && defined(__POWERPC__)
#define BIG_ENOUGH_STACK 10000 // a bigger stack make the application crash...
#endif


char buf[BIG_ENOUGH_STACK]; char buf[BIG_ENOUGH_STACK];
int i; int i;
@@ -1511,9 +1634,22 @@ jack_get_mhz (void)
} }
} }


jack_time_t __jack_cpu_mhz;

void jack_init_time () void jack_init_time ()
{ {
__jack_cpu_mhz = jack_get_mhz (); __jack_cpu_mhz = jack_get_mhz ();
} }


#elif defined(__APPLE__) && defined(__POWERPC__)

double __jack_time_ratio;

void jack_init_time ()
{
mach_timebase_info_data_t info;
mach_timebase_info(&info);
__jack_time_ratio = ((float)info.numer/info.denom) / 1000;
}

#endif #endif

+ 7
- 1
libjack/local.h View File

@@ -17,8 +17,14 @@ struct _jack_client {
void *on_shutdown_arg; void *on_shutdown_arg;
char thread_ok : 1; char thread_ok : 1;
char first_active : 1; char first_active : 1;
float cpu_mhz;
pthread_t thread_id; pthread_t thread_id;
#if defined(__APPLE__) && defined(__POWERPC__)
/* specific ressources for server/client real-time thread communication */
mach_port_t clienttask, bp, serverport, replyport;
trivial_message message;
pthread_t process_thread;
#endif


}; };




+ 12
- 3
libjack/shm.c View File

@@ -29,6 +29,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <config.h>


#include <jack/shm.h> #include <jack/shm.h>
#include <jack/internal.h> #include <jack/internal.h>
@@ -63,6 +64,7 @@ jack_initialize_shm ()
{ {
void *addr; void *addr;
int id; int id;
int perm;


#ifdef USE_POSIX_SHM #ifdef USE_POSIX_SHM
fprintf (stderr, "JACK compiled with POSIX SHM support\n"); fprintf (stderr, "JACK compiled with POSIX SHM support\n");
@@ -79,9 +81,16 @@ jack_initialize_shm ()
if we exit. otherwise, they can get lost in crash if we exit. otherwise, they can get lost in crash
or debugger driven exits. or debugger driven exits.
*/ */
#if defined(linux)
perm = O_RDWR|O_CREAT|O_TRUNC;
#elif defined(__APPLE__) && defined(__POWERPC__)
/* using O_TRUNC option does not work on Darwin */
perm = O_RDWR|O_CREAT;
#endif
if ((addr = jack_get_shm ("/jack-shm-registry", sizeof (jack_shm_registry_entry_t) * MAX_SHM_ID, if ((addr = jack_get_shm ("/jack-shm-registry", sizeof (jack_shm_registry_entry_t) * MAX_SHM_ID,
O_RDWR|O_CREAT|O_TRUNC, 0600, PROT_READ|PROT_WRITE, &id)) == MAP_FAILED) {
perm, 0600, PROT_READ|PROT_WRITE, &id)) == MAP_FAILED) {
return -1; return -1;
} }


@@ -108,7 +117,7 @@ jack_cleanup_shm ()
void void
jack_destroy_shm (const char *shm_name) jack_destroy_shm (const char *shm_name)
{ {
shm_unlink (shm_name);
shm_unlink (shm_name);
} }


void void
@@ -256,7 +265,7 @@ jack_get_shm (const char *shm_name, size_t size, int perm, int mode, int prot, i
return MAP_FAILED; return MAP_FAILED;
} }
} }
snprintf (path, sizeof(path), "%s/jack/shm%s", jack_server_dir, shm_name); snprintf (path, sizeof(path), "%s/jack/shm%s", jack_server_dir, shm_name);
if ((status = stat (path, &statbuf)) < 0) { if ((status = stat (path, &statbuf)) < 0) {
int fd; int fd;


Loading…
Cancel
Save