Browse Source

[0.83.1] more port buffer changes

git-svn-id: svn+ssh://jackaudio.org/trunk/jack@512 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
joq 21 years ago
parent
commit
3a766bd87c
7 changed files with 95 additions and 78 deletions
  1. +1
    -1
      configure.in
  2. +1
    -0
      jack/engine.h
  3. +25
    -24
      jack/port.h
  4. +26
    -17
      jackd/engine.c
  5. +13
    -9
      libjack/client.c
  6. +7
    -1
      libjack/local.h
  7. +22
    -26
      libjack/port.c

+ 1
- 1
configure.in View File

@@ -14,7 +14,7 @@ dnl changes are made
dnl ---
JACK_MAJOR_VERSION=0
JACK_MINOR_VERSION=83
JACK_MICRO_VERSION=0
JACK_MICRO_VERSION=1

dnl ---
dnl HOWTO: updating the jack protocal version


+ 1
- 0
jack/engine.h View File

@@ -38,6 +38,7 @@ typedef struct {
jack_shmsize_t offset;
} jack_port_buffer_info_t;

/* The engine keeps an array of these in its local memory. */
typedef struct _jack_port_internal {
struct _jack_port_shared *shared;
JSList *connections;


+ 25
- 24
jack/port.h View File

@@ -46,24 +46,22 @@ typedef int32_t jack_port_type_id_t;

typedef struct {
shm_name_t shm_name;
char *address; /* JOQ: no longer set globally */
jack_shmsize_t size;
} jack_port_segment_info_t;

/* Port type structure. Has several uses:
/* Port type structure.
*
* (1) One for each port type is part of the engine's jack_control_t
* shared memory structure.
*
* (2) One for each port type is appended to the engine's
* jack_client_connect_result_t response.
*
* (3) The client reads these into its local memory, and uses them to
* attach the corresponding shared memory segments.
* jack_client_connect_result_t response. The client reads them into
* its local memory, using them to attach the corresponding shared
* memory segments.
*/
typedef struct _jack_port_type_info {

jack_port_type_id_t type_id;
jack_port_type_id_t ptype_id;
const char type_name[JACK_PORT_TYPE_SIZE];

/* If == 1, then a buffer to handle nframes worth of data has
@@ -82,17 +80,12 @@ typedef struct _jack_port_type_info {

} jack_port_type_info_t;

/* This is the data structure allocated in shared memory
* by the engine.
*/
/* Allocated by the engine in shared memory. */
typedef struct _jack_port_shared {
jack_port_type_info_t type_info;
/* location of buffer as an offset from the start of the port's
* type-specific shared memory region. */
jack_shmsize_t offset;
/* index into engine port array for this port */
jack_port_id_t id;
int8_t has_mixdown; /* port has a mixdown function */

jack_port_type_id_t ptype_id; /* index into port type array */
jack_shmsize_t offset; /* buffer offset in shm segment */
jack_port_id_t id; /* index into engine port array */
enum JackPortFlags flags;
char name[JACK_CLIENT_NAME_SIZE+JACK_PORT_NAME_SIZE+2];
jack_client_id_t client_id; /* who owns me */
@@ -101,6 +94,7 @@ typedef struct _jack_port_shared {
volatile jack_nframes_t total_latency;
volatile uint8_t monitor_requests;

int8_t has_mixdown; /* port has a mixdown function */
char in_use : 1;
char locked : 1;

@@ -115,20 +109,27 @@ typedef struct _jack_port_functions {

} jack_port_functions_t;

/* This port structure is allocated by the client in local memory. */
/* Allocated by the client in local memory. */
struct _jack_port {
char *client_segment_base;
void **client_segment_base;
void *mix_buffer;
jack_port_type_info_t *type_info; /* shared memory type info */
struct _jack_port_shared *shared; /* corresponding shm struct */
struct _jack_port *tied; /* locally tied source port */
jack_port_functions_t fptr; /* local port functions */
pthread_mutex_t connection_lock;
jack_port_functions_t fptr;
pthread_mutex_t connection_lock;
JSList *connections;
};

/* Inline would be cleaner, but it needs to be fast even in
* non-optimized code. */
/* Inline would be cleaner, but it needs to be fast even in
* non-optimized code. jack_output_port_buffer() only handles output
* ports. jack_port_buffer() works for both input and output ports.
*/
#define jack_port_buffer(p) \
((void *) ((p)->client_segment_base + (p)->shared->offset))
((void *) ((p)->mix_buffer? (p)->mix_buffer: \
*(p)->client_segment_base + (p)->shared->offset))
#define jack_output_port_buffer(p) \
((void *) (*(p)->client_segment_base + (p)->shared->offset))

#endif /* __jack_port_h__ */


+ 26
- 17
jackd/engine.c View File

@@ -171,14 +171,14 @@ jack_global_port_type_info (jack_engine_t *engine, jack_port_internal_t *port)
{
/* Returns a pointer to the port type information in the
engine's shared control structure. */
return &engine->control->port_types[port->shared->type_info.type_id];
return &engine->control->port_types[port->shared->ptype_id];
}

static inline jack_port_type_internal_t *
jack_local_port_type_info (jack_engine_t *engine, jack_port_internal_t *port)
{
/* Points to the engine's private port type struct. */
return &engine->port_type[port->shared->type_info.type_id];
return &engine->port_type[port->shared->ptype_id];
}

static int
@@ -311,8 +311,9 @@ jack_resize_port_segment (jack_engine_t *engine,
int shmid;
int perm;
jack_port_buffer_info_t *bi;
jack_port_type_id_t ptid = port_type->type_id;
jack_port_type_id_t ptid = port_type->ptype_id;
jack_port_type_internal_t *pti = &engine->port_type[ptid];
jack_port_id_t i;

if (port_type->buffer_scale_factor < 0) {
one_buffer = port_type->buffer_size;
@@ -369,8 +370,8 @@ jack_resize_port_segment (jack_engine_t *engine,
pthread_mutex_unlock (&pti->buffer_lock);

} else {

/* resize existing buffer segment */

if ((addr = jack_resize_shm (port_type->shm_info.shm_name,
size, perm, 0666,
PROT_READ|PROT_WRITE))
@@ -391,6 +392,15 @@ jack_resize_port_segment (jack_engine_t *engine,
offset += one_buffer;
++bi;
}

/* update any existing output port offsets */
for (i = 0; i < engine->port_max; i++) {
if (engine->control->ports[i].flags|JackPortIsOutput &&
engine->control->ports[i].ptype_id == ptid) {
bi = engine->internal_ports[i].buffer_info;
engine->control->ports[i].offset = bi->offset;
}
}
pthread_mutex_unlock (&pti->buffer_lock);
}

@@ -401,7 +411,7 @@ jack_resize_port_segment (jack_engine_t *engine,
event.type = AttachPortSegment;
strcpy (event.x.shm_name, port_type->shm_info.shm_name);
event.y.ptid = ptid;
event.z.size = size; /* JOQ: why wasn't this set before? */
event.z.size = size;
jack_deliver_event_to_all (engine, &event);
}

@@ -2025,8 +2035,8 @@ jack_engine_new (int realtime, int rtpriority, int verbose, int client_timeout)
&jack_builtin_port_types[i],
sizeof (jack_port_type_info_t));

/* set offset into port_types array */
engine->control->port_types[i].type_id = i;
/* the port type id is index into port_types array */
engine->control->port_types[i].ptype_id = i;

/* be sure to initialize mutex correctly */
pthread_mutex_init (&engine->port_type[i].buffer_lock, NULL);
@@ -3388,7 +3398,7 @@ void jack_dump_configuration(jack_engine_t *engine, int take_lock)
jack_slist_length(client->fed_by),
client->subgraph_start_fd,
client->subgraph_wait_fd);
for(m = 0, portnode = client->ports; portnode;
portnode = jack_slist_next (portnode)) {
port = (jack_port_internal_t *) portnode->data;
@@ -3472,8 +3482,7 @@ jack_port_do_connect (jack_engine_t *engine,
return -1;
}

if (srcport->shared->type_info.type_id
!= dstport->shared->type_info.type_id) {
if (srcport->shared->ptype_id != dstport->shared->ptype_id) {
jack_error ("ports used in attemped connection are not of "
"the same data type");
return -1;
@@ -3508,7 +3517,8 @@ jack_port_do_connect (jack_engine_t *engine,
}

for (it = srcport->connections; it; it = it->next) {
if (((jack_connection_internal_t *)it->data)->destination == dstport) {
if (((jack_connection_internal_t *)it->data)->destination
== dstport) {
return EEXIST;
}
}
@@ -3524,11 +3534,11 @@ jack_port_do_connect (jack_engine_t *engine,

jack_lock_graph (engine);

if (dstport->connections &&
!dstport->shared->has_mixdown) {
if (dstport->connections && !dstport->shared->has_mixdown) {
jack_port_type_info_t *port_type =
jack_global_port_type_info (engine, dstport);
jack_error ("cannot make multiple connections to a port of"
" type [%s]",
dstport->shared->type_info.type_name);
" type [%s]", port_type->type_name);
free (connection);
jack_unlock_graph (engine);
return -1;
@@ -3900,8 +3910,7 @@ jack_port_do_register (jack_engine_t *engine, jack_request_t *req)
shared = &engine->control->ports[port_id];

strcpy (shared->name, req->x.port_info.name);
memcpy (&shared->type_info, &engine->control->port_types[i],
sizeof (jack_port_type_info_t));
shared->ptype_id = engine->control->port_types[i].ptype_id;
shared->client_id = req->x.port_info.client_id;
shared->flags = req->x.port_info.flags;
shared->latency = 0;


+ 13
- 9
libjack/client.c View File

@@ -202,11 +202,9 @@ jack_client_invalidate_port_buffers (jack_client_t *client)
port = (jack_port_t *) node->data;

if (port->shared->flags & JackPortIsInput) {
if (port->client_segment_base == 0) {
jack_pool_release (
(void *) port->shared->offset);
port->client_segment_base = 0;
port->shared->offset = 0;
if (port->mix_buffer) {
jack_pool_release (port->mix_buffer);
port->mix_buffer = NULL;
}
}
}
@@ -1527,16 +1525,19 @@ jack_get_ports (jack_client_t *client,
engine = client->engine;

if (port_name_pattern && port_name_pattern[0]) {
regcomp (&port_regex, port_name_pattern, REG_EXTENDED|REG_NOSUB);
regcomp (&port_regex, port_name_pattern,
REG_EXTENDED|REG_NOSUB);
}
if (type_name_pattern && type_name_pattern[0]) {
regcomp (&type_regex, type_name_pattern, REG_EXTENDED|REG_NOSUB);
regcomp (&type_regex, type_name_pattern,
REG_EXTENDED|REG_NOSUB);
}

psp = engine->ports;
match_cnt = 0;

matching_ports = (const char **) malloc (sizeof (char *) * engine->port_max);
matching_ports = (const char **)
malloc (sizeof (char *) * engine->port_max);

for (i = 0; i < engine->port_max; i++) {
matching = 1;
@@ -1558,7 +1559,10 @@ jack_get_ports (jack_client_t *client,
}

if (matching && type_name_pattern && type_name_pattern[0]) {
if (regexec (&type_regex, psp[i].type_info.type_name, 0, NULL, 0)) {
jack_port_type_id_t ptid = psp[i].ptype_id;
if (regexec (&type_regex,
engine->port_types[ptid].type_name,
0, NULL, 0)) {
matching = 0;
}
}


+ 7
- 1
libjack/local.h View File

@@ -10,9 +10,15 @@ struct _jack_client {
int pollmax;
int graph_next_fd;
int request_fd;

jack_port_type_id_t n_port_types;
jack_port_segment_info_t port_segment[JACK_MAX_PORT_TYPES];
struct {
shm_name_t shm_name;
void *address;
jack_shmsize_t size;
} port_segment[JACK_MAX_PORT_TYPES];
JSList *ports;

pthread_t thread;
char fifo_prefix[PATH_MAX+1];
void (*on_shutdown)(void *arg);


+ 22
- 26
libjack/port.c View File

@@ -61,11 +61,13 @@ jack_port_new (const jack_client_t *client, jack_port_id_t port_id,
jack_control_t *control)
{
jack_port_shared_t *shared = &control->ports[port_id];
jack_port_type_id_t ptid = shared->type_info.type_id;
jack_port_type_id_t ptid = shared->ptype_id;
jack_port_t *port = (jack_port_t *) malloc (sizeof (jack_port_t));

port->client_segment_base = 0;
port->mix_buffer = NULL;
port->client_segment_base = NULL;
port->shared = shared;
port->type_info = &client->engine->port_types[ptid];
pthread_mutex_init (&port->connection_lock, NULL);
port->connections = 0;
port->tied = NULL;
@@ -76,7 +78,7 @@ jack_port_new (const jack_client_t *client, jack_port_id_t port_id,
* functions within this address space. These builtin
* definitions can be overridden by the client. */

if (port->shared->type_info.type_id == JACK_AUDIO_PORT_TYPE) {
if (ptid == JACK_AUDIO_PORT_TYPE) {

port->fptr = jack_builtin_audio_functions;
port->shared->has_mixdown = TRUE;
@@ -94,7 +96,8 @@ jack_port_new (const jack_client_t *client, jack_port_id_t port_id,
port->offset can change if the buffer size or port counts
are changed.
*/
port->client_segment_base = client->port_segment[ptid].address;
port->client_segment_base =
(void *) &client->port_segment[ptid].address;
return port;
}
@@ -371,7 +374,7 @@ jack_port_get_buffer (jack_port_t *port, jack_nframes_t nframes)
if (port->tied) {
return jack_port_get_buffer (port->tied, nframes);
}
return jack_port_buffer (port);
return jack_output_port_buffer (port);
}

/* Input port. Since this can only be called from the
@@ -394,28 +397,20 @@ jack_port_get_buffer (jack_port_t *port, jack_nframes_t nframes)
nframes);
}

/* Multiple connections. Use a local buffer and mixdown the
incoming data to that buffer. we have already established
the existence of a mixdown function during the connection
process.

No port can have an offset of 0, that offset refers to the
zero-filled area at the start of a shared port segment
area. So, use the offset to store the location of a
locally allocated buffer, and reset the client_segment_base
so that the jack_port_buffer() computation works correctly.
/* Multiple connections. Use a local buffer and mix the
incoming data into that buffer. We have already
established the existence of a mixdown function during the
connection process.
*/

if (port->shared->offset == 0) {
port->shared->offset = (size_t)
if (port->mix_buffer == NULL) {
port->mix_buffer =
jack_pool_alloc (
port->shared->type_info.buffer_scale_factor
port->type_info->buffer_scale_factor
* sizeof (jack_default_audio_sample_t)
* nframes);
port->client_segment_base = 0;
}
port->fptr.mixdown (port, nframes);
return (jack_default_audio_sample_t *) port->shared->offset;
return (jack_default_audio_sample_t *) port->mix_buffer;
}

int
@@ -565,7 +560,7 @@ jack_port_flags (const jack_port_t *port)
const char *
jack_port_type (const jack_port_t *port)
{
return port->shared->type_info.type_name;
return port->type_info->type_name;
}

int
@@ -604,7 +599,8 @@ jack_audio_port_mixdown (jack_port_t *port, jack_nframes_t nframes)
jack_default_audio_sample_t *dst, *src;

/* by the time we've called this, we've already established
the existence of more than 1 connection to this input port.
the existence of more than one connection to this input
port and allocated a mix_buffer.
*/

/* no need to take connection lock, since this is called
@@ -615,9 +611,9 @@ jack_audio_port_mixdown (jack_port_t *port, jack_nframes_t nframes)

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

memcpy (buffer, jack_port_buffer (input),
memcpy (buffer, jack_output_port_buffer (input),
sizeof (jack_default_audio_sample_t) * nframes);

for (node = jack_slist_next (node); node;
@@ -627,7 +623,7 @@ jack_audio_port_mixdown (jack_port_t *port, jack_nframes_t nframes)

n = nframes;
dst = buffer;
src = jack_port_buffer (input);
src = jack_output_port_buffer (input);

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


Loading…
Cancel
Save