« Return to Thread: new patch to help jackd along

Re: new patch to help jackd along

by Pieter Palmers :: Rate this Message:

Reply to Author | View in Thread

Rui Nuno Capela wrote:

> On Fri, May 9, 2008 03:24, Paul Davis wrote:
>> Changes:
>>
>> * use poll+read, not just read, when waiting for clients to finish up
>> non-process "event" handling
>> * mark clients as Finished after their process callback has executed
>> * remove clients that failed to respond to events
>> * add new -r option to completely remove the JACK shm registry
>> at startup (orthogonal to everything else, but in my codebase for months)
>>
>> I would commit this directly, but I'm trying to be cautious for once. It
>> works much better for me now. Note that I believe there may be some
>> locking issues still to address in the code (insufficient locking,
>> that is, not deadlocks).
>>
>
> sorry to tell, but it still fails on the jack_test2.c crash tester (the
> very same at stake on that last night in Cologne:)
>
> fyi, this is just one simple client that, after a while, enters into an
> endless loop and tests for jackd being able to detect and remove it from
> the graph. what happens is that jackd gets severely stuck and
> jack_watchdog kicks in and bang! everything is thrown to the floor
>
> funny thing, and it might just be relevant to the case, is that this
> meltdown behavior seems to be most evident when, and only when, the bad
> client shares the graph with any other client. when left alone, everything
> seems to work just fine. puzzled ;)
For me it seems to be working fine. I'm on a dual core machine though so
this might be the reason.

I've attached a slightly modified version of your tester that also
displays a loop counter for when the process callback enters the stuck
loop. for me this gives the following:

ppalmers@ox-D820:~/programming/jack/tests$ ./jack_test2 2> log
seconds to run: 30
num.of ports: 2
client_name: jack_test2-32116
jack_test2-32116: client_new
jack_test2-32116: port_register
jack_test2-32116: set_process_callback
jack_test2-32116: on_shutdown
jack_test2-32116: activate
jack_test2-32116: connect: jack_test2-32116:out_0 -> system:playback_1
jack_test2-32116: connect: jack_test2-32116:out_1 -> system:playback_2
jack_test2-32116: running(0, 0)...  1
jack_test2-32116: mark!
jack_test2-32116: running(1, 2071971914)... 54
*** shutdown ***
jack_test2-32116: running(1, 2147483647)... 48
ppalmers@ox-D820:~/programming/jack/tests$

after the shutdown message, the counter stops increasing, so the process
callback is dead. The client itself stays alive, as I would expect it to
be. This is both with and without other clients in the graph.

Greets,

Pieter

/* jack_test2.c */
/****************************************************************************
   Copyright (C) 2007, rncbc aka Rui Nuno Capela.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2
   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 General Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <jack/jack.h>


jack_client_t *client;
jack_port_t  **iports;
jack_port_t  **oports;

unsigned int  seconds_to_run = 30;
unsigned int  num_of_ports   = 2;

float         mixer_gain     = 1.0f;

int           ret = 0;
long int      loop_count = 0;
/* shutdown process.. */
void shutdown_0 (void *arg)
{
    fprintf(stdout, "\n*** shutdown ***\n");
//    ret = 0;
}


/* stand-alone process. mix all the input ports to each output port. */
int process_0 (jack_nframes_t frames, void *arg)
{
    jack_default_audio_sample_t *ibuf;
    jack_default_audio_sample_t *obuf;
    jack_nframes_t k;
    int i, j, n;

    if (ret > 0)
        for (n = 0; n < 0x7fffffff; ++n) {
            loop_count++;
        }
    for (i = 0; i < num_of_ports; i++) {
        obuf = (jack_default_audio_sample_t*)
            jack_port_get_buffer(oports[i], frames);
        for (j = 0; j < num_of_ports; j++) {
            ibuf = (jack_default_audio_sample_t*)
                jack_port_get_buffer(iports[j], frames);
            for (k = 0; k < frames; k++) {
                if (j == 0)
                    obuf[k] = 0.0;
                if (ibuf[k] < -1E-6f || ibuf[k] > +1E-6f)
                    obuf[k] += ibuf[k];
                if (j == num_of_ports - 1)
                    obuf[k] *= mixer_gain;
            }
        }
    }

    return 0; // ret;
}

int main(int argc, char *argv[])
{
    char client_name[33];
    char iport_name[33];
    char oport_name[33];
    const char **pports;
    int i;

    /* seconds_to_run: default = 60 seconds. */
    if (argc > 1)
        seconds_to_run = (unsigned int) atoi(argv[1]);
    fprintf(stdout, "seconds to run: %u\n", seconds_to_run);

    /* num_of_ports: default = 2 ports. */
    if (argc > 2)
        num_of_ports = (unsigned int) atoi(argv[2]);
    fprintf(stdout, "num.of ports: %u\n", num_of_ports);

    sprintf(client_name, "jack_test2-%u", getpid());
    fprintf(stdout, "client_name: %s\n", client_name);

    fprintf(stdout, "%s: client_new\n", client_name);
    client = jack_client_new(client_name);
    if (!client) {
        fprintf(stdout, "%s: jackd not running?\n", client_name);
        return 1;
    }

    mixer_gain = 1.0f / (float) num_of_ports;
   
    iports = (jack_port_t **) malloc(num_of_ports * sizeof(jack_port_t *));
    oports = (jack_port_t **) malloc(num_of_ports * sizeof(jack_port_t *));

    fprintf(stdout, "%s: port_register\n", client_name);
    for (i = 0; i < num_of_ports; i++) {
        sprintf(iport_name, "in_%d", i);
        iports[i] = jack_port_register(client, iport_name,
            JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
        if (iports[i] == NULL) {
            fprintf(stdout, "%s:%s port registration failed\n",
                client_name, iport_name);
            goto exit1;
        }
        sprintf(oport_name, "out_%d", i);
        oports[i] = jack_port_register(client, oport_name,
            JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
        if (oports[i] == NULL) {
            fprintf(stdout, "%s:%s port registration failed\n",
                client_name, oport_name);
            goto exit1;
        }
    }

    fprintf(stdout, "%s: set_process_callback\n", client_name);
    jack_set_process_callback(client, process_0, 0);

    fprintf(stdout, "%s: on_shutdown\n", client_name);
    jack_on_shutdown(client, shutdown_0, 0);

    fprintf(stdout, "%s: activate\n", client_name);
    jack_activate(client);

    /* try to connect to available physical outputs. */
    pports = jack_get_ports(client, 0, 0,
        JackPortIsInput | JackPortIsPhysical);
    if (pports) {
        for (i = 0; i < num_of_ports && pports[i]; i++) {
            sprintf(oport_name, "%s:out_%d", client_name, i);
            fprintf(stdout, "%s: connect: %s -> %s\n",
                client_name, oport_name, pports[i]);
            if (jack_connect(client, oport_name, pports[i]) != 0) {
                fprintf(stdout, "%s: connect failed\n");
                goto exit2;
            }
        }
        free(pports);
    }

    /* ok, we're up and running... */
    for (i = seconds_to_run; i > 0; --i) {
        fprintf(stdout, "%s: running(%d, %ld)...%3d\r", client_name, ret, loop_count, i);
        fflush(stdout);
        sleep(1);
    }

    /* make it blast... */
    fprintf(stdout, "\n%s: mark!\n", client_name);
    ret = 1;

    /* duh?, still here... */
    for (i = seconds_to_run*2; i > 0; --i) {
        fprintf(stdout, "%s: running(%d, %ld)...%3d\r", client_name, ret, loop_count, i);
        fflush(stdout);
        sleep(1);
    }

exit2:

    fprintf(stdout, "%s: deactivate\n", client_name);
    jack_deactivate(client);

exit1:

    fprintf(stdout, "%s: close\n", client_name);
    jack_client_close(client);

    free(iports);
    free(oports);

    return 0;
}

/* end of jack_test2.c */

_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

 « Return to Thread: new patch to help jackd along