Environment is Ubuntu 24.04, QT Creator 6, g++ 13.3, pthreads.
Given the following code (error handling has been removed for readability):
#include <iostream>
#include <thread>
#include <cstring>
#define HEAPBUFFER (100000)
class Foo {
public:
Foo() {
foo_buffer = nullptr; //Construct to null
}
~Foo(){
std::cout<<"Deleting instance heap"<<std::endl;
delete [] foo_buffer; //Release the heap
}
void take_copy(u_int8_t *heap_to_copy, int len) {
foo_buffer = new u_int8_t[len]; //Allocate on the heap
buf_len = len; //Store the length internally
//At this point here, if this is running in one or more seperate threads, does this need to have mutex protection locked?
std::memcpy(foo_buffer, heap_to_copy, buf_len); //Copy from the "global" heap allocation to the "local" heap allocation
//At this point here, if this is running in one or more seperate threads, does this need to have mutex protection released?
}
private:
u_int8_t *foo_buffer;
int buf_len;
};
u_int8_t *heap_buffer;
int main()
{
Foo foo;
Foo bar;
heap_buffer = new u_int8_t[HEAPBUFFER]; //Allocate on heap, sets to 0x00
std::memset(heap_buffer, 0xFF, sizeof(u_int8_t)*HEAPBUFFER); //Set to 0xFF
std::thread take_copy_one(&Foo::take_copy, &foo, heap_buffer, HEAPBUFFER); //Take a copy for foo to use
std::thread take_copy_two(&Foo::take_copy, &bar, heap_buffer, HEAPBUFFER); //Take a copy for foo to use
//If I decide to do something here to heap_buffer, I'm guess there needs to be some shared mutex protection or bad things may happen?
take_copy_one.join();
take_copy_two.join();
delete [] heap_buffer; //Release the memory
return 0;
}
I have allocated heap memory, I then instantiate two objects of "Foo". These two objects require a copy of the heap allocated memory in order to perform some computation. In this simple example, the heap is untouched in the main thread as my question here relates purely to the std::memcpy function.
I am aware that in the real world, the main thread may well change the heap memory and would need some kind of synchronisation across the threads, but I'm ignoring that in this instance.
However, my questions to those cleverer than me are:
- In the case of the code above, would the
std::memcpycall in the two thread require a mutex around them? - If a mutex is required, this would need to be a shared mutex, i.e. I couldn't just use an instance level mutex, it would have to be declared "globally" and a reference to it passed to the instance, either via the constructor or the take_copy method?
I'm very unclear on this. My thoughts are that, because it is a copy, i.e. the shared heap memory is being read (not written), then the two std::memcpy calls will be "safe".
heap_bufferglobal?