I have data structures (let's call each a "resource") that are stored in POSIX shared memory. Access to each resource is mediated by a per-resource mutex. A process may sometimes need to update several resources atomically. This process must acquire all of the prerequisite mutexes before updating/modifying the resources in question. The mutexes must be obtained in a well-defined order to avoid classic deadlock scenarios. I want to develop a compile-time method to ensure that locks are obtained in the correct order.
Each resource is mapped individually into each process in arbitrary order. For this reason, I cannot obtain the resources in resource-address order. Besides the fact that determining the proper order would not occur at compile-time, the relative order of resource addresses would likely differ from process to process, since each resource may (likely, even) be mapped to a different virtual address. Luckily, each resource type, represented by a struct, has a constexpr-defined unique integer ID. I want to obtain resources in ID-order.
Suppose each data structure looks something like this:
template<typename ResourceStruct, int UniqueId>
struct SharedResource
{
static constexpr int ID = UniqueId;
ResourceStruct resource;
};
I have a function similar to C++11's std::lock that receives the list of mutexes to lock as template parameters. I believe that it should be possible to sort these template parameters at compile-time according to each resource's ID. Unfortunately, I have been struggling with the necessary template meta-programming gymnastics to pull it off. I have studied several approaches (e.g., quicksort #1, quicksort #2) for sorting template parameters, but they all seem overly complicated. Am I over-thinking my problem? Is there an easier approach? If at all possible, I would prefer a pure C++11 solution (I would rather avoid dependencies on Boost).
Aucun commentaire:
Enregistrer un commentaire