Hi zhy44th,
Regarding structure pointer and array transfer, it depends :-)
Arrays and references will implicitly use memcpy type functions (remote_memcpy for when code is on another tile) and optimise them.
Also, if it can't be done at compile time, array access will be range checked too.
Pointers (smart and unsafe) will only work for shared memory and you control every action.
The value and reference semantics will be slightly different too - you get what you ask for.
Regarding the code, there are a couple of problems.
First, the function task2 will complete and exit, unwinding its stack and hence leave the sent pointer 'test' dangling - not nice!
To fix this you need to handshake with task1 the ownership of 'rx_buffer' - see earlier answer.
The second is more unfortunate.
The compiler will look at your code and decide that rx_buffer's address is used to initialise a pointer, but the pointer is never dereferenced.
Hence, there is no need to do the initialisation of the structure - and your set up code is promptly optimised away.
This is a bug in the compiler - passing a pointer over a channel suggests it will be dereferenced, hence the optimisation should be prevented.
The work around is to prevent the compiler doing the optimisation by:
1. Build with -O0 (bad idea)
2. pass the structure's pointer to a function (as you do with print_msg) AND make sure it can't see how the pointer is used (compilers can be very sneaky).
#2 may be achieved by placing the creation and initiation of the structure in one file (compilation unit) and the use/sending in another file viz:
// file1.xc
Code: Select all
void task1(streaming chanend c_to) {
...
c_to :> test;
print_msg(test, "received: ");
c_to <: test;
}
// Can only see that the structure 'might' be dereferenced in sendBuffer() - hence no optimisation of fields allowed.
unsafe void sendBuffer(streaming chanend c_to, my_struct * unsafe test);
void task2(streaming chanend c_to){
my_struct rx_buff;
unsafe{
my_struct * unsafe test = &rx_buff;
test->id1 = 0;
...
sendBuffer(c_to, test);
}
}
//file2.xc
Code: Select all
unsafe void sendBuffer(treaming chanend c_to, my_struct * unsafe test) {
c_to <: test;
c_to :> test;
}
The downside is the extra file and the overhead of a function call.
You can't inline the function as this would allow the compiler to see and hence optimise!
I'm sure there are other imaginative ways you could solve your original problem if you don't like the above.
robert