passing unsafe pointers via channels

New to XMOS and XCore? Get started here.
Post Reply
moh_algoblan
Member++
Posts: 17
Joined: Tue Jun 18, 2019 11:39 am

passing unsafe pointers via channels

Post by moh_algoblan »

I'm testing the performance of having multiple threads working together at the same time. so what i'm trying to do is, creating one thread that will distribute blocks of data (16B each block) to multiple threads. each thread will encrypt the whole block of data, and it will keep receiving more blocks until there's no more unencrypted blocks of data. the whole data is represented as a matrix of 10*16, so we have 10 blocks of data, each one has 16B. I tried to pass one row of the matrix (one block of data) via the channel to another thread to test my idea, but I got this error:
xrun: Program received signal ET_ILLEGAL_RESOURCE, Resource exception.
main_task_1 (frame=0x7fe7c) at ../src/test.xc:98
98 c[0]:> *data;
my code:

Code: Select all

int main(void){
    uint8_t data [160];
    int counter =0;
    for(int i=0; i<160; i++){
        data[i]=i;
    }
    uint8_t mat[10][16];
    for(int i=0 ; i<10 ; i++){
        for(int j=0 ; j<16 ; j++){
            mat[i][j]=data[16*i+j];
        }
    }
    
    chan c[7];
    par{
        unsafe{//thread0
            for(int i=0; i<10 ; i++){//will loop 10 times since we have 10 blocks of data
                //uint8_t* unsafe p=mat[i]; //pointer to a single block of data
                c[counter]<:(uint8_t* unsafe) &mat[i];//passing a single block of data as a reference through the channel
                counter=(counter+1)%7;//we have 7 threads for encryption, but we'r using one just to test
            }//finish of loop
        }//finish thread0
        unsafe{//thread1
            uint8_t data[16];
            c[0]:> *data;//one block of data should be placed in this array
            for(int i=0; i <16; i++)
                printf("%d \n", data[i]);//just to make sure that the whole block of data is transferred successfully  
        }//finish thread1
    }
Last edited by moh_algoblan on Tue Oct 29, 2019 9:14 am, edited 1 time in total.


User avatar
mon2
XCore Legend
Posts: 1913
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Post by mon2 »

Often caused by out of range access.

Please review this thread on some great debugging tips:

https://www.xcore.com/viewtopic.php?t=2440

and

Code: Select all

xrun --dumpstate your_binary_here.xe
moh_algoblan
Member++
Posts: 17
Joined: Tue Jun 18, 2019 11:39 am

Post by moh_algoblan »

mon2 wrote: Tue Oct 29, 2019 4:10 am Often caused by out of range access.

Please review this thread on some great debugging tips:

https://www.xcore.com/viewtopic.php?t=2440

and

Code: Select all

xrun --dumpstate your_binary_here.xe
I've tried to debug the code and it looks the exception rises when the micro controller execute this line:

Code: Select all

            c[0]:> *data;
I've tried to pass an integer value instead of passing a pointer, the code works just fine. so I guess the problem is with passing the pointer. I'm not that good at C so I'm not sure if my code is correct or not. (the pointers part to be specific).
I've tried to preform the command that you told me about:

Code: Select all

xrun --dumpstate your_binary_here.xe
and here's the result:

Code: Select all

***** Active Cores *****
  2  tile[1] core[0]  0xfff004c8 in ?? ()
* 1  tile[0] core[0]  0xfff004c8 in ?? ()

Thread 2 (tile[1] core[0]):

***** Call Stack *****
#0  0xfff004c8 in ?? ()
#1  0xfff00342 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

***** Disassembly *****
0xfff004c8:     waiteu (0r)      *
0xfff004ca:     ldw (ru6)       r11, dp[0x5]
0xfff004cc:     setc (ru6)      res[r11], 0x0 *
0xfff004ce:     ldc (ru6)       r11, 0x6
0xfff004d0:     setc (ru6)      res[r11], 0x0 *

***** Registers *****
r0             0x0      0
r1             0x0      0
r2             0x0      0
r3             0x0      0
r4             0x200100 2097408
r5             0x100200 1049088
r6             0x100300 1049344
r7             0x80a    2058
r8             0x0      0
r9             0x10027  65575
r10            0x5      5
r11            0x40b    1035
cp             0x0      0
dp             0xfff01eb0       -1040720
sp             0x7ff7c  524156
lr             0xfff00342       -1047742
pc             0xfff004c8       -1047352
sr             0x41     65
spc            0x0      0
ssr            0x0      0
et             0x0      0
ed             0x0      0
sed            0x0      0
kep            0xfff00400       -1047552
ksp            0x0      0

Thread 1 (tile[0] core[0]):

***** Call Stack *****
#0  0xfff004c8 in ?? ()
#1  0xfff00342 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

***** Disassembly *****
0xfff004c8:     waiteu (0r)      *
0xfff004ca:     ldw (ru6)       r11, dp[0x5]
0xfff004cc:     setc (ru6)      res[r11], 0x0 *
0xfff004ce:     ldc (ru6)       r11, 0x6
0xfff004d0:     setc (ru6)      res[r11], 0x0 *

***** Registers *****
r0             0x0      0
r1             0x0      0
r2             0x0      0
r3             0x0      0
r4             0x200100 2097408
r5             0x100200 1049088
r6             0x100300 1049344
r7             0x80a    2058
r8             0x0      0
r9             0x27     39
r10            0x5      5
r11            0x40b    1035
cp             0x0      0
dp             0xfff01eb0       -1040720
sp             0x7ff7c  524156
lr             0xfff00342       -1047742
pc             0xfff004c8       -1047352
sr             0x41     65
spc            0x0      0
ssr            0x0      0
et             0x0      0
ed             0x0      0
sed            0x0      0
kep            0xfff00400       -1047552
ksp            0x0      0

I'm not quiet sure what does this command do, because the pc in my code (according to Xtime composer's dissembler) never exceeded 0x00042630, but here it looks the pc reaches far big numbers.
but what I've found more interesting is what the console window showed me when I debugged the code by the IDE:

Code: Select all

Program stopped at 0x40000.
It stopped with signal SIGTRAP, Trace/breakpoint trap.
Type "info stack" or "info registers" for more information.
mi_cmd_var_create: unable to create variable object
mi_cmd_var_create: unable to create variable object
mi_cmd_var_create: unable to create variable object
the console will keep repeating this phrase "mi_cmd_var_create: unable to create variable object". and this one too: "mi_cmd_var_create: Usage: NAME FRAME EXPRESSION."
it tells me to type "info stack" or "info registers" for more information, so I did, and here's the result, but I'm not quiet sure what does it mean so I'm asking for your help:

Code: Select all

info stack
#0  main_task_1 (frame=0x7fe6c) at ../src/test.xc:101
#1  0x000405d4 in __start_other_cores ()
#2  0x000403d1 in main () at ../src/test.xc:86
info registers 
r0             0xc0	192
r1             0x425e0	271840
r2             0x7fbf0	523248
r3             0x104	260
r4             0x7fe6c	523884
r5             0x3	3
r6             0x7fe68	523880
r7             0x10	16
r8             0x0	0
r9             0x0	0
r10            0x40000	262144
r11            0x4046c	263276
cp             0x41fd0	270288
dp             0x425b8	271800
sp             0x7fd98	523672
lr             0x405d4	263636	 __start_other_cores + 64
pc             0x40480	263296	 main_task_1 + 20
sr             0x100	256
spc            0x0	0
ssr            0x0	0
et             0x0	0
ed             0x0	0
sed            0x0	0
kep            0x40080	262272
ksp            0x0	0
sorry for this long reply.
moh_algoblan
Member++
Posts: 17
Joined: Tue Jun 18, 2019 11:39 am

Post by moh_algoblan »

i think i've found the problem. the second pointer inside the second thread wasn't unsafe, so I think the compiler has some problems with storing an unsafe pointer inside a safe pointer. so I changed the par function into that and it works just fine:

Code: Select all

par{
        unsafe{//thread0
            for(int i=0; i<10 ; i++){//will loop 10 times since we have 10 blocks of data
                //uint8_t* unsafe p=mat[i]; //pointer to a single block of data
                c[counter]<:(uint8_t* unsafe) &mat[i];//passing a single block of data as a reference through the channel
                counter=(counter+1)%7;//we have 7 threads for encryption, but we'r using one just to test
            }//finish of loop
        }//finish thread0
        unsafe{//thread1
            uint8_t* unsafe data;
            c[0] :> data;
            for(int i=0 ; i<16 ; i++)
                printf("%d \n" , data[i]);
        }//finish thread1
    }
User avatar
fabriceo
XCore Addict
Posts: 181
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

hi, strange, normally the "unsafe" statement is just to remove some compiler types checks and to remove code generation for out of bounds checks... a safe or unsafe pointer is still a 4 bytes memory location containing a destination address. This would be different with the "movable" pointer which contains complementary informations and therefore use 12bytes.
you might consider using C instead of XC for the main code of your application encryption, this will give you the flexibility of using shared memory location and to build a simple 2 dimension aray that could be accessed by each task
Post Reply