Select function cases not being hit

Technical questions regarding the XTC tools and programming with XMOS.
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm

Select function cases not being hit

Post by cjameshuff »

I have a simple select function that exchanges a block of data for a fresh one:

Code: Select all

select bfifo_select(server interface block_fifo_if consumer, block_fifo_t & fifo)
{
    case (fifo.filled_blocks > 0) =>
            consumer.exchange(fifo_block_t * movable & block):
        bfifo_pop(fifo, block);
        break;
}

Code: Select all

    while(1) {
        select {
// Doesn't work, cases apparently never hit:
          case bfifo_select(sig_out, fifo);
// Works as expected:
          case (fifo.filled_blocks > 0) =>
                sig_out.exchange(fifo_block_t * movable & block):
            bfifo_pop(fifo, block);
            break;...
        }
    }
Is there something I need to do to get it to set up the guards properly? Anything else I'm missing?
Gothmag
XCore Addict
Posts: 129
Joined: Wed May 11, 2016 3:50 pm

Post by Gothmag »

The case in the second block, the one you say doesnt work, isn't how you should be doing that. And the first code blocks select isn't how that's done either. I'm assuming these aren't the actual code. Either way there is no way for either of those guards to be evaluated true with this code, is that data changed somewhere?

Could you post your main, both thread definitions, and the interface definition at least? Someone more knowledgeable might be able to say with what you've posted but I'm not sure what you're actually running. When calling a case, the syntax is the same as any function in c, you don't call it using case f(); Typically if you need something to be called before a thread is running you do it before the while, select bit. Otherwise since it's event driven you need something to call that code from elsewhere.
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm

Post by cjameshuff »

Gothmag wrote:The case in the second block, the one you say doesnt work, isn't how you should be doing that. And the first code blocks select isn't how that's done either. I'm assuming these aren't the actual code. Either way there is no way for either of those guards to be evaluated true with this code, is that data changed somewhere?

Could you post your main, both thread definitions, and the interface definition at least? Someone more knowledgeable might be able to say with what you've posted but I'm not sure what you're actually running. When calling a case, the syntax is the same as any function in c, you don't call it using case f(); Typically if you need something to be called before a thread is running you do it before the while, select bit. Otherwise since it's event driven you need something to call that code from elsewhere.
Can you give more detail than "that's now how you're supposed to do that"?

Here is a complete working example. If the producer.foo1(); call is uncommented, execution never progresses past it. Your suggestion of using "my_select_function(consumer, x);" instead of "case my_select_function(consumer, x);" simply produces a parse error. Commenting the call to the select function and copying the case directly into the select{} block produces the results I expect.

Code: Select all


typedef interface my_interface_if {
    [[guarded]] void foo1();
    [[guarded]] void foo2();
} my_interface_if;

select my_select_function(server interface my_interface_if consumer, int & x)
{
    case (x > 4) =>
            consumer.foo1():
        debug_printf("foo1() hit, x = %d\n", x);
        --x;
        break;
}

void server_task(server interface my_interface_if consumer)
{
    int x = 0;
    while(1)
    {
        select {
            case my_select_function(consumer, x);
            case (x > 0) =>
                    consumer.foo2():
                debug_printf("foo2() hit, x = %d\n", x);
                --x;
                break;
            (x < 8) => default:
                debug_printf("++x\n");
                ++x;
                break;
        }
    }
}

void client_task(client interface my_interface_if producer)
{
    debug_printf("start\n");
    producer.foo1();
    while(1)
    {
        producer.foo2();
        delay_milliseconds(1000);
    }
}

int main()
{
    my_interface_if my_interface;
    par {
        on tile[0]: server_task(my_interface);
        on tile[0]: client_task(my_interface);
    }
    return 0;
}
Gothmag
XCore Addict
Posts: 129
Joined: Wed May 11, 2016 3:50 pm

Post by Gothmag »

Yea, I'm sorry, I didn't have much time to post and nobody else had so I thought I'd ask for more info but didn't have time to explain much. I can see a little better what you're doing now. It was also my mistake because I didn't notice it WAS a select.

Since you have two selects I think you might need to manually handle the guard, breaking if your condition isnt met. I have a feeling its some issue with control tokens, possibly it's not going anywhere, and keeps looking. Either that or it may be ignoring the one ofnthe selects. Alternatively I'd just put that case within the main select for the thread. If you were doing that for cleanliness you could also just have your guards and create functions for the cases and call those in the body.

I've never actually used two selects before so I just can't say for sure, and don't have time to try it right now. I think not using the select function and having the case in the body of the thread like the others, and how you said worked is the best way to go. Or you could just have 1 big macro if its just down to how the code looks. Sorry I can't be of more help.
User avatar
larry
Respected Member
Posts: 275
Joined: Fri Mar 12, 2010 6:03 pm

Post by larry »

I suspect the xC compiler is not handling correctly the combination of a select function and a regular select case when both are guarded.

I will submit an internal engineering report about this.

Will you be able to avoid using a select function? Without it both functions execute fine in this code snippet.
cjameshuff
Member++
Posts: 22
Joined: Mon Sep 26, 2016 6:08 pm

Post by cjameshuff »

larry wrote:I suspect the xC compiler is not handling correctly the combination of a select function and a regular select case when both are guarded.

I will submit an internal engineering report about this.

Will you be able to avoid using a select function? Without it both functions execute fine in this code snippet.
I eventually resorted to using a macro to insert the select cases...not ideal, but it worked.