Home > Enterprise >  free data asynchronously in c
free data asynchronously in c

Time:06-10

I get a data structure like this:

struct My_data
{
  MyArray<float> points;
  MyArray<float> normals;
  MyArray<float> uvCoords;
};

This function can be used to free them:

void ClearAlembicData(My_data* myData)
{
  myData->points.clear();
  myData->normals.clear();
  myData->uvCoords.clear();
}

I want to asynchronously clean the myData so that the program will not wait util all the xxx.clear() are done. Here is my actual code:

My_data myData;
myData.point.push_back(point);
myData.nomals.push_back(nomals);
myData.uvCorrds.push_back(uvCorrds);

ClearAlembicData(&myData);

myData.point.push_back(point);
myData.nomals.push_back(nomals);
myData.uvCorrds.push_back(uvCorrds);

Could you show me how to do it in C ? thanks

CodePudding user response:

Depending on the definition of MyArray, this will either cause undefined behavior or be completely pointless.

If the container is thread-safe, it will block your push_back while the clear is being executed in the other thread (making the 'clearing it asynchronously' completely pointless), if it is not, you are introducing a race condition, which might even end up crashing your program, because you would be concurrently manipulating a shared resource. (Not a good idea).

If you still want to do it, here is a way that might work:

  1. Make 'myData' into a pointer and operate on that.
  2. Upon wanting to clear, store that pointer in another pointer variable and replace the pointer with new My_Data.
  3. Pass the stored pointer to your asynchronous 'free' function.
  4. Continue to work with your new data structure in the original thread.

This way, you are not working on a shared resource and asynchronous freeing becomes feasible.

As for 'how to', if you've got C 11, something like this would work (Pseudo-Code).

My_data *myData = new My_data();
myData->point.push_back(point);
myData->nomals.push_back(nomals);
myData->uvCorrds.push_back(uvCorrds);

std::thread([=](){ ClearAlembicData(myData); delete myData; }).detach();

myData = new My_data()
myData->point.push_back(point);
myData->nomals.push_back(nomals);
myData->uvCorrds.push_back(uvCorrds);

delete myData;

CodePudding user response:

One of the solutions, implement MyArray::swap(MyArray&). Then

void ClearAlembicData(My_data* myData)
{
  MyArray<float> old_points;
  MyArray<float> old_normal;
  MyArray<float> old_coords;

  // Fast swap, myData arrays become empty
  myData->points.swap(old_points);
  myData->normals.clear(old_normals);
  myData->uvCoords.clear(old_coords);

  // Assumed to be passed to async function
  old_points.clear();
  old_normals.clear();
  old_coords.clear();
}

There is no enough information about MyArray abilities, such as support of move semantics, a real function clear, thus this is just an idea.

CodePudding user response:

If MyArray is a wrapper around std::vector, know that the clear() operation is O(1) as float is trivially destructible and the compiler can eliminate the loop that destroys elements individually.

If it is not, consider implementing MyArray.clear() such that it marks the container as having a non-zero capacity yet zero contents. As stated above, std::vector accomplishes this by simply setting slots_available = capacity.

  • Related