Re: [LAD] [PD-dev] question about multithreaded externals in Pd

From: Ivica Ico Bukvic <ico@email-addr-hidden>
Date: Sat Oct 02 2010 - 16:41:20 EEST

First of all, my apologies to all for x-posting of the original
matter--I did not realize there was such a major overlap in user base on
pd-list and pd-dev lists making my x-post truly redundant.

> since rPars can't be used by any other thread, you need to make a copy
> for each thread.

This must be it! You are absolutely right as there is no guarantee rPars
won't get destructed (with the end of the constructor function) before
the worker thread is properly instantiated. FWIW, instead of creating a
copy of rPars, I've actually gone with Robin's suggestion to use
sched_yield() and have a wait condition which is cleared once the worker
thread has spawned to ensure it will get the necessary data from rPars
before they are destructed as follows:

void *pd_cwiid_pthreadForAudioUnfriendlyOperations(void *ptr)
{
        threadedFunctionParams *rPars = (threadedFunctionParams*)ptr;
        t_wiimote *x = rPars->wiimote;
        t_float local_led = 0;
        t_float local_rumble = 0;
        unsigned char local_rpt_mode = x->rpt_mode;

        while(x->unsafe > -1) {
                pthread_mutex_lock(&x->unsafe_mutex);
                if ((local_led == x->led) && (local_rumble == x->rumble) &&
(local_rpt_mode == x->rpt_mode)) {
                        if (x->unsafe) x->unsafe = 0; //signal that the thread init is
complete
                        pthread_cond_wait(&x->unsafe_cond, &x->unsafe_mutex);
                }

//snip

static void *pd_cwiid_new(t_symbol* s, int argc, t_atom *argv)
{

        //snip

        // spawn threads for actions known to cause sample drop-outs
        threadedFunctionParams rPars;
        rPars.wiimote = x;
        pthread_mutex_init(&x->unsafe_mutex, NULL);
        pthread_cond_init(&x->unsafe_cond, NULL);
        pthread_create( &x->unsafe_t, NULL, (void *)
&pd_cwiid_pthreadForAudioUnfriendlyOperations, (void *) &rPars);

        // wait until other thread has properly intialized so that
        // rPars do not get destroyed before the thread has gotten its
        // pointer information
        while(x->unsafe) {
                //must use as many yields as necessary as there is no
                //guarantee that one will be enough
                //also on Linux use sched_yield
                //rather than pthread_yield
                sched_yield();
        }

//snip

Many thanks all for your help on this one! Hopefully the existence of
this thread will help others who may be looking for similar solutions.

Best wishes,

Ico

_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@email-addr-hidden
http://lists.linuxaudio.org/listinfo/linux-audio-dev
Received on Sat Oct 2 20:15:02 2010

This archive was generated by hypermail 2.1.8 : Sat Oct 02 2010 - 20:15:02 EEST