chanend array raise an exception ET_ILLEGAL_RESOURCE

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
Julien
Member++
Posts: 16
Joined: Mon Feb 22, 2010 4:43 pm
Location: France

chanend array raise an exception ET_ILLEGAL_RESOURCE

Post by Julien »

Hello all,

Attached is a small program which compiles right but fails on execution with an exception ET_ILLEGAL_RESOURCE. The goal of this program is to have one thread (receiver) which handles an I/O port (here PORT_4A) and several other threads (senderX) which send "commands" to that thread, via one channel each.

If I use an array of chanend as argument to the first function and one array element per sender thread, I've got the exception. (see file chanarray.xc).

Code: Select all

void receiver(chanend c[NB_CHAN])
{
    unsigned data;
    while (1) {
        select {
        case (int i = 0; i < NB_CHAN; i++) c[i] :> data: 
            break;
        }

        myport <: data;
    }
}
Program received signal ET_ILLEGAL_RESOURCE, Resource not valid.
0x00010160 in sender1 (c=1026) at chanarray.xc:29
29 c <: 0x1;
If I use a list of chanend for the receiver and one chanend per sender, the program works as expected. (see file chanlist.xc)

Code: Select all

void receiver(chanend c1, chanend c2, chanend c3, chanend c4)
{
    unsigned data;
    while (1) {
        select {
        case c1 :> data: break;
        case c2 :> data: break;
        case c3 :> data: break;
        case c4 :> data: break;
        }

        myport <: data;
    }
}
As you can see, the exception is not in receiver thread but in sender1 here (seen it on sender2 as well), but I can not figure out why the resource is illegal. It seems that I did that already and that it worked, but I can't make it work now.

Does anyone have any ideas?
Cheers,
Julien
You do not have the required permissions to view the files attached to this post.


User avatar
Julien
Member++
Posts: 16
Joined: Mon Feb 22, 2010 4:43 pm
Location: France

Post by Julien »

OK, as a desperate move I changed my main from:

Code: Select all

int main (void)
{
    chan mychan[NB_CHAN];

    par {
        on stdcore[0] : par {
            sender1(mychan[0]);
            sender2(mychan[1]);
            sender3(mychan[2]);
            sender4(mychan[3]);
            receiver(mychan);
        }
    }
    return 0;
}
to:

Code: Select all

int main (void)
{
    chan mychan[NB_CHAN];

    par {
            sender1(mychan[0]);
            sender2(mychan[1]);
            sender3(mychan[2]);
            sender4(mychan[3]);
            receiver(mychan);
    }
    return 0;
}
and now it works... Could anyone explain why the "double" par{} creates such a confusion?

Greetings
Julien
User avatar
Julien
Member++
Posts: 16
Joined: Mon Feb 22, 2010 4:43 pm
Location: France

Post by Julien »

And to be complete, such main also works:

Code: Select all

int main (void)
{
    chan mychan[NB_CHAN];

    par {
        on stdcore[0] : par {
            receiver(mychan);
        }
        on stdcore[0] : par {
            sender1(mychan[0]);
            sender2(mychan[1]);
            sender3(mychan[2]);
            sender4(mychan[3]);
        }
    }
    return 0;
}
But the following one, only 2 senders actually sends (guess which ones...):

Code: Select all

int main (void)
{
    chan mychan[NB_CHAN];

    par {
        on stdcore[0] : par {
            receiver(mychan);
            sender1(mychan[0]);
            sender2(mychan[1]);
        }
        on stdcore[0] : par {
            sender3(mychan[2]);
            sender4(mychan[3]);
        }
    }
    return 0;
}
User avatar
Andy
Respected Member
Posts: 279
Joined: Fri Dec 11, 2009 1:34 pm

Post by Andy »

I'm not sure the double par in main is valid syntax - in your case it's not needed. Every thread inside the par {} in main() is run in parallel on Core 0 if stdcore[0]: is omitted. Otherwise, every thread should have a stdcore: in front, where i is the core ID.
User avatar
paul
XCore Addict
Posts: 169
Joined: Fri Jan 08, 2010 12:13 am

Post by paul »

Andy is correct all you should need to do is shown below:

Code: Select all

int main (void)
{
    chan mychan[NB_CHAN];

    on stdcore[0] : par {
            receiver(mychan);
            sender1(mychan[0]);
            sender2(mychan[1]);
            sender3(mychan[2]);
            sender4(mychan[3]);
        }
    }
    return 0;
}
Regards
Paul

On two occasions I have been asked, 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question.
richard
Respected Member
Posts: 318
Joined: Tue Dec 15, 2009 12:46 am

Post by richard »

This does indeed look like a bug - the two mains you posted shouldn't give different behaviour. For now I would recommend using the form Paul suggested.
User avatar
Julien
Member++
Posts: 16
Joined: Mon Feb 22, 2010 4:43 pm
Location: France

Post by Julien »

richard wrote:This does indeed look like a bug - the two mains you posted shouldn't give different behaviour. For now I would recommend using the form Paul suggested.
Thanks Richard for noting it might be a bug. Hopefully this will be fixed in future tool releases.

Hope this thread will inform other XMOS users about this potential bug.

Enjoy summer holidays if you have this chance!
Julien