@@ -148,20 +148,35 @@ struct override_hash {
148
148
149
149
using instance_map = std::unordered_multimap<const void *, instance *>;
150
150
151
+ #ifdef Py_GIL_DISABLED
152
+ // Wrapper around PyMutex to provide BasicLockable semantics
153
+ class pymutex {
154
+ PyMutex mutex;
155
+
156
+ public:
157
+ pymutex () : mutex({}) {}
158
+ void lock () { PyMutex_Lock (&mutex); }
159
+ void unlock () { PyMutex_Unlock (&mutex); }
160
+ };
161
+
151
162
// Instance map shards are used to reduce mutex contention in free-threaded Python.
152
163
struct instance_map_shard {
153
- std::mutex mutex;
154
164
instance_map registered_instances;
165
+ pymutex mutex;
155
166
// alignas(64) would be better, but causes compile errors in macOS before 10.14 (see #5200)
156
- char padding[64 - (sizeof (std::mutex ) + sizeof (instance_map )) % 64 ];
167
+ char padding[64 - (sizeof (instance_map ) + sizeof (pymutex )) % 64 ];
157
168
};
158
169
170
+ static_assert (sizeof (instance_map_shard) % 64 == 0,
171
+ "instance_map_shard size is not a multiple of 64 bytes");
172
+ #endif
173
+
159
174
// / Internal data structure used to track registered instances and types.
160
175
// / Whenever binary incompatible changes are made to this structure,
161
176
// / `PYBIND11_INTERNALS_VERSION` must be incremented.
162
177
struct internals {
163
178
#ifdef Py_GIL_DISABLED
164
- std::mutex mutex;
179
+ pymutex mutex;
165
180
#endif
166
181
// std::type_index -> pybind11's type information
167
182
type_map<type_info *> registered_types_cpp;
@@ -614,7 +629,7 @@ inline local_internals &get_local_internals() {
614
629
}
615
630
616
631
#ifdef Py_GIL_DISABLED
617
- # define PYBIND11_LOCK_INTERNALS (internals ) std::unique_lock<std::mutex > lock ((internals).mutex)
632
+ # define PYBIND11_LOCK_INTERNALS (internals ) std::unique_lock<pymutex > lock ((internals).mutex)
618
633
#else
619
634
# define PYBIND11_LOCK_INTERNALS (internals )
620
635
#endif
@@ -651,7 +666,7 @@ inline auto with_instance_map(const void *ptr,
651
666
auto idx = static_cast <size_t >(hash & internals.instance_shards_mask );
652
667
653
668
auto &shard = internals.instance_shards [idx];
654
- std::unique_lock<std::mutex > lock (shard.mutex );
669
+ std::unique_lock<pymutex > lock (shard.mutex );
655
670
return cb (shard.registered_instances );
656
671
#else
657
672
(void ) ptr;
@@ -667,7 +682,7 @@ inline size_t num_registered_instances() {
667
682
size_t count = 0 ;
668
683
for (size_t i = 0 ; i <= internals.instance_shards_mask ; ++i) {
669
684
auto &shard = internals.instance_shards [i];
670
- std::unique_lock<std::mutex > lock (shard.mutex );
685
+ std::unique_lock<pymutex > lock (shard.mutex );
671
686
count += shard.registered_instances .size ();
672
687
}
673
688
return count;
0 commit comments