Page 1 of 1

Crashing on port as parameter in interface call

Posted: Wed Feb 21, 2018 1:50 pm
by aclassifier
This code crashes when i_my.x_crashes is called. The original SW instead uses p_spi_aux_in_call in i_my.y (not shown here), which works.

I didn't think it would be illegal to send a port along in an interface call?

Another thing, if I only call i_my.y (); the stack size calculation fails!?

Code: Select all

#include <platform.h>
#include <xs1.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <iso646.h>
#include <xccompat.h> // REFERENCE_PARAMs

typedef enum {false,true} bool;
typedef interface my_if {

    void x_crashes (out port p_spi_aux_in_call);
    void y (void);

} my_if;

[[combinable]]
void my_client (client my_if i_my, out port p_spi_aux_in_call) {
    timer    tmr;
    unsigned current_time;
    bool     now = true;

    tmr :> current_time;
    while (1) {
        select {
            case tmr when timerafter(current_time) :> void: {
                current_time += XS1_TIMER_HZ; // Once per second
                if (now) {
                    i_my.y (); // This first run always succeeds
                } else {
                    // i_my.y (); // If only this here, it's confused as to stack size calculations:
                    // ../src/main.xc:(.dp.data+0x4): Error: Meta information ("my_client.nstackwords") for function "my_client" cannot be determined.
                    // ../src/main.xc:(.dp.data+0x4): Error:   lower bound could not be calculated (function is recursive?)
                    
                    i_my.x_crashes (p_spi_aux_in_call);
                    // tile[0] core[1]  (Suspended: Signal 'ET_ILLEGAL_RESOURCE' received. Description: Resource exception.)   
                    //    3 my_server() main.xc:646 0x0001021e    
                    //    2 __main__main_tile_0_combined_tile_0_u0() main.xc:664 0x00010298   
                    //    1 __start_core()  0x00010b72    
                }
                now = not now;
            } break;
        }
    }
}

[[combinable]]
void my_server (server my_if i_my, out port p_spi_aux_in_init) {
    while (1) {
        select {
            case i_my.x_crashes (out port p_spi_aux_in_call): {
                printf("i_my.x crashes in line above\n"); // So never gets here
                break;
            }
            case i_my.y (void): {
                printf("i_my.y here\n");
                break;
            }
        }
    }
}

out port p_spi_aux_in_init = XS1_PORT_4C;
out port p_spi_aux_in_call = XS1_PORT_4D;

int main() {
    my_if i_my;
    par {
        on tile[0].core[0]: my_server (i_my, p_spi_aux_in_init);
        on tile[0].core[1]: my_client (i_my, p_spi_aux_in_call);
    }
    return 0;
}

Re: Crashing on port as parameter in interface call

Posted: Thu Feb 22, 2018 12:47 pm
by robertxmos
I didn't think it would be illegal to send a port along in an interface call?
Hmmm, this looks like a bug.
Give me some time.

Re: Crashing on port as parameter in interface call

Posted: Thu Feb 22, 2018 12:50 pm
by robertxmos
Another thing, if I only call i_my.y (); the stack size calculation fails!?
I have not be able to reproduce this error.
Could you tell me which version of tools you are using.

Re: Crashing on port as parameter in interface call

Posted: Thu Feb 22, 2018 2:17 pm
by aclassifier
About the "another thing" point (that I also have filed as Issue 10862), this is a clean situation that causes this miscalculation. I have
Version: Community_14.3.2 (build 25550, Sep-30-2017)
Copyright 2015 Xmos Ltd.
Here is the code, where the if(now) has to do with it:

Code: Select all

#include <platform.h>
#include <xs1.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <iso646.h>
#include <xccompat.h> // REFERENCE_PARAMs

typedef enum {false,true} bool;
typedef interface my_if {
    void y (void);
} my_if;

[[combinable]]
void my_client (client my_if i_my, out port p_spi_aux_in_call) {
    timer    tmr;
    unsigned current_time;
    bool     now = true;

    tmr :> current_time;
    while (1) {
        select {
            case tmr when timerafter(current_time) :> void: {
                current_time += XS1_TIMER_HZ; // Once per second
                if (now) {
                    i_my.y (); // This first run always succeeds
                } else {
                    i_my.y (); // If only this here, it's confused as to stack size calculations:
                    // ../src/main.xc:(.dp.data+0x4): Error: Meta information ("my_client.nstackwords") for function "my_client" cannot be determined.
                    // ../src/main.xc:(.dp.data+0x4): Error:   lower bound could not be calculated (function is recursive?)
                }
                now = not now;
            } break;
        }
    }
}

[[combinable]]
void my_server (server my_if i_my, out port p_spi_aux_in_init) {
    while (1) {
        select {
            case i_my.y (void): {
                printf("i_my.y here\n");
                break;
            }
        }
    }
}

out port p_spi_aux_in_init = XS1_PORT_4C;
out port p_spi_aux_in_call = XS1_PORT_4D;

int main() {
    my_if i_my;
    par {
        on tile[0].core[0]: my_server (i_my, p_spi_aux_in_init);
        on tile[0].core[1]: my_client (i_my, p_spi_aux_in_call);
    }
    return 0;
}
here is the log:

Code: Select all

14:11:19 **** Incremental Build of configuration Default for project _xmos_issues ****
xmake CONFIG=Default all 
Checking build modules
No build modules used.
Analyzing main.xc
Propagating analysis
Creating dependencies for main.xc
Compiling main.xc
Creating xmos_issues_nnnm.xe
../src/main.xc:(.dp.data+0x4): Error: Meta information ("my_client.nstackwords") for function "my_client" cannot be determined.
../src/main.xc:(.dp.data+0x4): Error:   lower bound could not be calculated (function is recursive?).
xmake[1]: *** [bin//xmos_issues_nnnm.xe] Error 1
xmake: *** [bin//xmos_issues_nnnm.xe] Error 2

and here is the makefile:

Code: Select all

# The TARGET variable determines what target system the application is
# compiled for. It either refers to an XN file in the source directories
# or a valid argument for the --target option when compiling
TARGET = STARTKIT
# TARGET = XCORE-200-EXPLORER

# The APP_NAME variable determines the name of the final .xe file. It should
# not include the .xe postfix. If left blank the name will default to
# the project name
APP_NAME = xmos_issues_nnnm

# The USED_MODULES variable lists other module used by the application.
USED_MODULES = 

# The flags passed to xcc when building the application
# You can also set the following to override flags for a particular language:
# XCC_XC_FLAGS, XCC_C_FLAGS, XCC_ASM_FLAGS, XCC_CPP_FLAGS
# If the variable XCC_MAP_FLAGS is set it overrides the flags passed to
# xcc for the final link (mapping) stage.

XCC_FLAGS = -O2 -g -fxscope -save-temps
# -DXASSERT_ENABLE_ASSERTIONS=1   is default
# -DXASSERT_ENABLE_LINE_NUMBERS=1 very expensive
# -DXASSERT_ENABLE_DEBUG=1        very expensive
XCC_MAP_FLAGS = -Xmapper --map -Xmapper _Aquarium_map.txt -Xmapper -report

# The XCORE_ARM_PROJECT variable, if set to 1, configures this
# project to create both xCORE and ARM binaries.
XCORE_ARM_PROJECT = 0

# The VERBOSE variable, if set to 1, enables verbose output from the make system.
VERBOSE = 0

XMOS_MAKE_PATH ?= ../..
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common

Re: Crashing on port as parameter in interface call

Posted: Thu Feb 22, 2018 4:37 pm
by robertxmos
I can confirm that the stack size calculation failing is another bug.
(it is interesting to note that it does not happen with -O0)
I think this one will take more time...

Re: Crashing on port as parameter in interface call

Posted: Thu Feb 22, 2018 4:45 pm
by aclassifier
So I assume then, that you have counted up two problems that is set on the xTIMEcomposer TODO list. So I just close this. Thanks and your welcome!-)

Re: Crashing on port as parameter in interface call

Posted: Thu Feb 22, 2018 5:01 pm
by robertxmos
I'm afraid so.
Thank you for the report.