Browse Source

used segment:offset addressing

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@63 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
pbd 24 years ago
parent
commit
5eea78a924
6 changed files with 119 additions and 92 deletions
  1. +2
    -4
      alsa_driver.c
  2. +77
    -30
      client.c
  3. +2
    -2
      configure.in
  4. +19
    -44
      engine.c
  5. +0
    -1
      jack/internal.h
  6. +19
    -11
      jack/port.h

+ 2
- 4
alsa_driver.c View File

@@ -951,7 +951,7 @@ alsa_driver_process (nframes_t nframes, void *arg)
continue;
}

alsa_driver_read_from_channel (driver, chn, port->shared->buffer, nframes, 0);
alsa_driver_read_from_channel (driver, chn, jack_port_buffer (port), nframes, 0);
}

return 0;
@@ -1002,7 +1002,6 @@ alsa_driver_attach (alsa_driver_t *driver, jack_engine_t *engine)
break;
}
driver->capture_ports = g_slist_append (driver->capture_ports, port);
printf ("registered %s\n", port->shared->name);
}

for (chn = 0; chn < driver->playback_nchannels; chn++) {
@@ -1015,10 +1014,9 @@ alsa_driver_attach (alsa_driver_t *driver, jack_engine_t *engine)
break;
}
driver->playback_ports = g_slist_append (driver->playback_ports, port);
printf ("registered %s\n", port->shared->name);
}

printf ("ports registered, starting client\n");
printf ("ALSA: ports registered, starting driver\n");

jack_activate (driver->client);
}


+ 77
- 30
client.c View File

@@ -37,6 +37,8 @@
#include <jack/pool.h>
#include <jack/error.h>

static jack_port_t *jack_port_new (jack_client_t *client, jack_port_id_t port_id, jack_control_t *control);

static pthread_mutex_t client_lock;
static pthread_cond_t client_ready;
static void *jack_zero_filled_buffer = 0;
@@ -106,13 +108,6 @@ jack_client_alloc ()
return client;
}

static jack_port_shared_t *
jack_port_shared_by_id (jack_client_t *client, jack_port_id_t id)

{
return &client->engine->ports[id];
}

static jack_port_t *
jack_port_by_id (jack_client_t *client, jack_port_id_t id)

@@ -165,7 +160,7 @@ jack_client_invalidate_port_buffers (jack_client_t *client)

if (port->shared->flags & JackPortIsInput) {
/* XXX release buffer */
port->shared->buffer = NULL;
port->client_segment_base = NULL;
}
}
}
@@ -175,28 +170,31 @@ jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event)

{
jack_port_t *control_port;
jack_port_shared_t *shared;
jack_port_t *other;
GSList *node;

switch (event->type) {
case PortConnected:
shared = jack_port_shared_by_id (client, event->y.other_id);
other = jack_port_new (client, event->y.other_id, client->engine);
control_port = jack_port_by_id (client, event->x.self_id);
control_port->connections = g_slist_prepend (control_port->connections, shared);
control_port->connections = g_slist_prepend (control_port->connections, other);
break;

case PortDisconnected:
shared = jack_port_shared_by_id (client, event->y.other_id);
control_port = jack_port_by_id (client, event->x.self_id);

for (node = control_port->connections; node; node = g_slist_next (node)) {
if (((jack_port_shared_t *) node->data) == shared) {

other = (jack_port_t *) node->data;

if (other->shared->id == event->y.other_id) {
printf ("%s DIS-connecting and %s\n", control_port->shared->name, other->shared->name);
control_port->connections = g_slist_remove_link (control_port->connections, node);
g_slist_free_1 (node);
free (other);
break;
}
}
printf ("%s DIS-connected and %s\n", control_port->shared->name, shared->name);
break;

default:
@@ -370,19 +368,19 @@ jack_client_new (const char *client_name)
*/

if ((port_segment_shm_id = shmget (res.port_segment_key, 0, 0)) < 0) {
jack_error ("cannot determine shared memory segment for port segment key 0x%x", res.port_segment_key);
jack_error ("cannot determine shared memory segment for port segment key 0x%x (%s)", res.port_segment_key, strerror (errno));
goto fail;
}

if ((addr = shmat (port_segment_shm_id, res.port_segment_address, 0)) == (void *) -1) {
jack_error ("cannot attached port segment shared memory at 0x%", res.port_segment_address);
if ((addr = shmat (port_segment_shm_id, 0, 0)) == (void *) -1) {
jack_error ("cannot attached port segment shared memory (%s)", strerror (errno));
goto fail;
}

si = (jack_port_segment_info_t *) malloc (sizeof (jack_port_segment_info_t));
si->shm_key = res.port_segment_key;
si->address = addr;
/* the first chunk of the first port segment is always set by the engine
to be a conveniently-sized, zero-filled lump of memory.
*/
@@ -790,13 +788,14 @@ jack_load_client (const char *client_name, const char *path_to_so)

jack_client_t *
jack_driver_become_client (const char *client_name)

{
int fd;
jack_client_connect_request_t req;
jack_client_connect_result_t res;
jack_client_t *client = 0;
int port_segment_shm_id;
jack_port_segment_info_t *si;
void *addr;

if ((fd = server_connect (0)) < 0) {
jack_error ("cannot connect to jack server");
@@ -829,6 +828,34 @@ jack_driver_become_client (const char *client_name)
client->control = res.client_control;
client->engine = res.engine_control;

/* Lookup, attach and register the port/buffer segments in use
right now.
*/

if ((port_segment_shm_id = shmget (res.port_segment_key, 0, 0)) < 0) {
jack_error ("cannot determine shared memory segment for port segment key 0x%x (%s)", res.port_segment_key, strerror (errno));
return NULL;
}

if ((addr = shmat (port_segment_shm_id, 0, 0)) == (void *) -1) {
jack_error ("cannot attached port segment shared memory (%s)", strerror (errno));
return NULL;
}

si = (jack_port_segment_info_t *) malloc (sizeof (jack_port_segment_info_t));
si->shm_key = res.port_segment_key;
si->address = addr;
/* the first chunk of the first port segment is always set by the engine
to be a conveniently-sized, zero-filled lump of memory.
*/

if (client->port_segments == NULL) {
jack_zero_filled_buffer = si->address;
}

client->port_segments = g_slist_prepend (client->port_segments, si);

/* allow the engine to act on the client's behalf
when dealing with in-process clients.
*/
@@ -851,20 +878,41 @@ unsigned long jack_get_sample_rate (jack_client_t *client)
}

static jack_port_t *
jack_port_new (jack_port_id_t port_id, jack_control_t *control)
jack_port_new (jack_client_t *client, jack_port_id_t port_id, jack_control_t *control)

{
jack_port_t *port;
jack_port_shared_t *shared;
jack_port_segment_info_t *si;
GSList *node;

shared = &control->ports[port_id];

port = (jack_port_t *) malloc (sizeof (jack_port_t));

port->client_segment_base = NULL;
port->shared = shared;
port->connections = 0;
port->tied = NULL;

si = NULL;

for (node = client->port_segments; node; node = g_slist_next (node)) {

si = (jack_port_segment_info_t *) node->data;

if (si->shm_key == port->shared->shm_key) {
break;
}
}
if (si == NULL) {
jack_error ("cannot find port segment to match newly registered port\n");
return NULL;
}

port->client_segment_base = si->address;

return port;
}

@@ -913,7 +961,8 @@ jack_port_register (jack_client_t *client,
return NULL;
}

port = jack_port_new (req.x.port_info.port_id, client->engine);
port = jack_port_new (client, req.x.port_info.port_id, client->engine);

client->ports = g_slist_prepend (client->ports, port);

return port;
@@ -1043,7 +1092,7 @@ jack_port_get_buffer (jack_port_t *port, nframes_t nframes)
if (port->tied) {
return jack_port_get_buffer (port->tied, nframes);
}
return port->shared->buffer;
return jack_port_buffer (port);
}

/* Input port.
@@ -1062,7 +1111,7 @@ jack_port_get_buffer (jack_port_t *port, nframes_t nframes)
the buffer of the connected (output) port.
*/

return ((jack_port_shared_t *) node->data)->buffer;
return jack_port_buffer (((jack_port_t *) node->data));
}

/* multiple connections. use a local buffer and mixdown
@@ -1071,14 +1120,14 @@ jack_port_get_buffer (jack_port_t *port, nframes_t nframes)
during the connection process.
*/

if (port->shared->buffer == NULL) {
port->shared->buffer = jack_pool_alloc
(port->shared->type_info.buffer_scale_factor * sizeof (sample_t) * nframes);
if (port->client_segment_base == NULL) {
port->client_segment_base = 0;
port->shared->offset = (size_t) jack_pool_alloc (port->shared->type_info.buffer_scale_factor * sizeof (sample_t) * nframes);
}

port->shared->type_info.mixdown (port, nframes);

return port->shared->buffer;
return jack_port_buffer (port);
}

int
@@ -1095,7 +1144,6 @@ jack_port_tie (jack_port_t *dst, jack_port_t *src)
return -1;
}

dst->own_buffer = dst->shared->buffer;
dst->tied = src;
return 0;
}
@@ -1108,7 +1156,6 @@ jack_port_untie (jack_port_t *port)
jack_error ("port \"%s\" is not tied", port->shared->name);
return -1;
}
port->shared->buffer = port->own_buffer;
port->tied = NULL;
return 0;
}


+ 2
- 2
configure.in View File

@@ -4,8 +4,8 @@ AC_INIT(client.c)
AC_CONFIG_AUX_DIR(.)

JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=3
JACK_MICRO_VERSION=5
JACK_MINOR_VERSION=4
JACK_MICRO_VERSION=0

BETA=



+ 19
- 44
engine.c View File

@@ -95,34 +95,6 @@ static int jack_deliver_event (jack_engine_t *, jack_client_internal_t *, jack_

static void jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes);

/* This is a disgusting kludge to work around issues with shmat.
A more robust solution is needed.
*/

static char *top_end_of_unmapped_memory = (char *) (1048576 * 1536); /* 1.5GB */
static char *low_end_of_unmapped_memory = (char *) (1048576 * 1024); /* 1GB */

static char *
fixed_shmat (int shmid, char *shmaddr, int shmflg, size_t size)
{
char *addr;
char *attempt;

if (shmaddr != 0) {
return shmat (shmid, shmaddr, shmflg);
}

attempt = (char *) (top_end_of_unmapped_memory - size);

while (attempt > low_end_of_unmapped_memory) {
if ((addr = (char *) shmat (shmid, attempt, shmflg|SHM_RND)) != (char *) -1) {
top_end_of_unmapped_memory = addr;
return addr;
}
attempt -= size;
}
return (char *) -1;
}

jack_port_type_info_t builtin_port_types[] = {
{ JACK_DEFAULT_AUDIO_TYPE, jack_audio_port_mixdown, 1 },
@@ -290,7 +262,7 @@ jack_add_port_segment (jack_engine_t *engine, unsigned long nports)
return -1;
}
if ((addr = fixed_shmat (id, 0, 0, size)) == (char *) -1) {
if ((addr = shmat (id, 0, 0)) == (char *) -1) {
jack_error ("cannot attach new port segment (%s)", strerror (errno));
shmctl (id, IPC_RMID, 0);
return -1;
@@ -557,7 +529,6 @@ handle_new_client (jack_engine_t *engine, int client_fd)
res.client_key = client->shm_key;
res.control_key = engine->control_key;
res.port_segment_key = engine->port_segment_key;
res.port_segment_address = engine->port_segment_address;
res.realtime = engine->control->real_time;
res.realtime_priority = engine->rtpriority - 1;

@@ -1103,7 +1074,7 @@ jack_engine_new (int realtime, int rtpriority)
return 0;
}
if ((addr = fixed_shmat (engine->control_shm_id, 0, 0, control_size)) == (void *) -1) {
if ((addr = shmat (engine->control_shm_id, 0, 0)) == (void *) -1) {
jack_error ("cannot attach control shared memory segment (%s)", strerror (errno));
shmctl (engine->control_shm_id, IPC_RMID, 0);
return 0;
@@ -1288,7 +1259,7 @@ jack_client_internal_new (jack_engine_t *engine, int fd, jack_client_connect_req
return 0;
}

if ((addr = fixed_shmat (shm_id, 0, 0, sizeof (jack_client_control_t))) == (void *) -1) {
if ((addr = shmat (shm_id, 0, 0)) == (void *) -1) {
jack_error ("cannot attach new client control block");
shmctl (shm_id, IPC_RMID, 0);
return 0;
@@ -2207,7 +2178,7 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
jack_port_segment_info_t *psi;
jack_port_buffer_info_t *bi;

port->shared->buffer = NULL;
port->shared->shm_key = -1;

if (port->shared->flags & JackPortIsInput) {
return 0;
@@ -2227,12 +2198,13 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
psi = (jack_port_segment_info_t *) node->data;

if (bi->shm_key == psi->shm_key) {
port->shared->buffer = psi->address + bi->offset;
port->shared->shm_key = psi->shm_key;
port->shared->offset = bi->offset;
break;
}
}
if (port->shared->buffer) {
if (port->shared->shm_key >= 0) {
engine->port_buffer_freelist = g_slist_remove (engine->port_buffer_freelist, bi);
} else {
jack_error ("port segment info for 0x%x:%d not found!", bi->shm_key, bi->offset);
@@ -2241,7 +2213,7 @@ jack_port_assign_buffer (jack_engine_t *engine, jack_port_internal_t *port)
out:
pthread_mutex_unlock (&engine->buffer_lock);

if (port->shared->buffer == NULL) {
if (port->shared->shm_key < 0) {
return -1;
} else {
return 0;
@@ -2297,8 +2269,9 @@ static void
jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes)
{
GSList *node;
jack_port_shared_t *input;
jack_port_t *input;
nframes_t n;
sample_t *buffer;
sample_t *dst, *src;

/* by the time we've called this, we've already established
@@ -2306,19 +2279,21 @@ jack_audio_port_mixdown (jack_port_t *port, nframes_t nframes)
*/

node = port->connections;
input = (jack_port_shared_t *) node->data;
input = (jack_port_t *) node->data;
buffer = jack_port_buffer (port);

memcpy (port->shared->buffer, input->buffer, sizeof (sample_t) * nframes);
memcpy (buffer, jack_port_buffer (input), sizeof (sample_t) * nframes);
for (node = g_slist_next (node); node; node = g_slist_next (node)) {
input = (jack_port_shared_t *) node->data;

input = (jack_port_t *) node->data;

n = nframes;
dst = port->shared->buffer;
src = input->buffer;
dst = buffer;
src = jack_port_buffer (input);

while (n--) {
*dst++ += *src++;
}
}
}



+ 0
- 1
jack/internal.h View File

@@ -158,7 +158,6 @@ typedef struct {
/* XXX need to be able to use more than one port segment key */

key_t port_segment_key;
void *port_segment_address;

} jack_client_connect_result_t;



+ 19
- 11
jack/port.h View File

@@ -52,16 +52,18 @@ typedef struct _jack_port_type_info {
*/

typedef struct _jack_port_shared {
void *buffer;
unsigned long flags;
unsigned long buffer_size;
jack_port_id_t id;
char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE+2];
jack_port_type_info_t type_info;
jack_client_id_t client_id;

char in_use : 1;
char locked : 1;
int shm_key;
size_t offset;
unsigned long flags;
unsigned long buffer_size;
jack_port_id_t id;
char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE+2];
jack_port_type_info_t type_info;
jack_client_id_t client_id;

char in_use : 1;
char locked : 1;
} jack_port_shared_t;

/* This is the data structure allocated by the client
@@ -70,12 +72,18 @@ typedef struct _jack_port_shared {
*/

struct _jack_port {
char *client_segment_base;
struct _jack_port_shared *shared;
GSList *connections;
struct _jack_port *tied;
void *own_buffer;
};

/* inline would be cleaner, but it needs to be fast even in non-optimized
code.
*/

#define jack_port_buffer(p) ((void *) ((p)->client_segment_base + (p)->shared->offset))

/* this is the structure allocated by the engine in local
memory.
*/


Loading…
Cancel
Save