PiJohn
Posts: 32
Joined: Sun Jan 31, 2021 11:19 am

Corrupted struct variables when using multicore

Mon Jun 14, 2021 4:59 pm

Hello!

I've been trying to get the following working for myself locally as part of a larger program:
https://github.com/raspberrypi/pico-exa ... er_queue.c

You can see my simplified version of the code here

I have a struct as follows:

Code: Select all

typedef struct
{
    int32_t (*func)(std::string);
    std::string data;
} queue_entry_t;
I initialise the struct and send it to the other core via the queue method:

Code: Select all

        
        if(first==false){
            rcv = "A long string to test with..............";
            first=true;
            entry.func = &displayString;
            entry.data = rcv;
            queue_add_blocking(&call_queue, &entry);
        }
Then in a loop, we check to see if the function has been called and the result posted back to the result queue.

Code: Select all

        if(queue_try_remove(&results_queue, &res)){
            std::cout << "rcv is now:" << rcv << std::endl;
            queue_add_blocking(&call_queue, &entry);
            printf("Added to queue remove\n");
        }
The core runner code looks as follows:

Code: Select all

void core1_entry() {
    while (1) {
        printf("Inside core1....\n");
        queue_entry_t entry;
        queue_remove_blocking(&call_queue, &entry);
        std::cout << "Entry is:" << entry.data << std::endl;
        int32_t (*func)(std::string){entry.func};
        int32_t result = func(entry.data);
        queue_add_blocking(&results_queue, &result);
    }
}
The problem is, after running this a few times my string gets corrupted when read inside the core1_entry() function:

Code: Select all

Starting....
Setup queues...
Launching core1
Inside core1....
Entry is:A long string to test with..............           <---- String ok here
In function: A long string to test with..............
Inside core1....
rcv is now:A long string to test with..............
Added to queue remove
Entry is:Ä Ä tring to test with..............               <---- String is now corrupted
In function: Ä Ä tring to test with..............
Inside core1....
rcv is now:A long string to test with..............
Added to queue remove
One thing to note is that this is a cpp program making a call to a C function, not sure if that matters at all but when searching I found someone had encountered a similar issue where their structs were corrupted. Does anyone know what might be going wrong here?

PiJohn
Posts: 32
Joined: Sun Jan 31, 2021 11:19 am

Re: Corrupted struct variables when using multicore

Mon Jun 14, 2021 5:20 pm

Hmm I think I've sorted it, moving the definition of entry inside the core before the for loop no longer results in a corrupted string.

Code: Select all

void core1_entry() {
    queue_entry_t entry;
    while (1) {
        printf("Inside core1....\n");
        queue_remove_blocking(&call_queue, &entry);
        std::cout << "Entry is:" << entry.data << std::endl;
        int32_t (*func)(std::string){entry.func};
        int32_t result = func(entry.data);
        queue_add_blocking(&results_queue, &result);
    }
}
Not how it's done in the original code though. https://github.com/raspberrypi/pico-exa ... ueue.c#L30

Any one any idea why this might corrupted the variable?

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 752
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Corrupted struct variables when using multicore

Mon Jun 14, 2021 5:29 pm

1) A pretty fundamental problem in the full version; you are using the same global "entry" instance for core local stuff on each core... though you may have fixed that as you have a stack local one in the fragments of code
2) But yeah, you are passing a structure containing a c++ class std::string by value (the event structure is copied) through c code which has no idea that the string is there and has special copy semantics. The "value" you pass must be "Plain Old Data"

fivdi
Posts: 447
Joined: Sun Sep 23, 2012 8:09 pm
Contact: Website

Re: Corrupted struct variables when using multicore

Mon Jun 14, 2021 5:46 pm

I'd put a C style string (a char array) rather than a std::string in the struct to avoid the issues that will occur copying a std::string to and from the queue.

PiJohn
Posts: 32
Joined: Sun Jan 31, 2021 11:19 am

Re: Corrupted struct variables when using multicore

Mon Jun 14, 2021 5:56 pm

Thanks for the responses, yep, will try not using the string type.

Certainly seems much better now though once that variable is defined outside of the loop in the core function.

EDIT - after running the loop for a long time the struct was eventually corrupted as before :)

Going down the c char array route.

Return to “SDK”