@@ -149,20 +149,35 @@ struct override_hash {
149
149
150
150
using instance_map = std::unordered_multimap<const void *, instance *>;
151
151
152
+ #ifdef Py_GIL_DISABLED
153
+ // Wrapper around PyMutex to provide BasicLockable semantics
154
+ class pymutex {
155
+ PyMutex mutex;
156
+
157
+ public:
158
+ pymutex () : mutex({}) {}
159
+ void lock () { PyMutex_Lock (&mutex); }
160
+ void unlock () { PyMutex_Unlock (&mutex); }
161
+ };
162
+
152
163
// Instance map shards are used to reduce mutex contention in free-threaded Python.
153
164
struct instance_map_shard {
154
- std::mutex mutex;
155
165
instance_map registered_instances;
166
+ pymutex mutex;
156
167
// alignas(64) would be better, but causes compile errors in macOS before 10.14 (see #5200)
157
- char padding[64 - (sizeof (std::mutex ) + sizeof (instance_map )) % 64 ];
168
+ char padding[64 - (sizeof (instance_map ) + sizeof (pymutex )) % 64 ];
158
169
};
159
170
171
+ static_assert (sizeof (instance_map_shard) % 64 == 0,
172
+ "instance_map_shard size is not a multiple of 64 bytes");
173
+ #endif
174
+
160
175
// / Internal data structure used to track registered instances and types.
161
176
// / Whenever binary incompatible changes are made to this structure,
162
177
// / `PYBIND11_INTERNALS_VERSION` must be incremented.
163
178
struct internals {
164
179
#ifdef Py_GIL_DISABLED
165
- std::mutex mutex;
180
+ pymutex mutex;
166
181
#endif
167
182
// std::type_index -> pybind11's type information
168
183
type_map<type_info *> registered_types_cpp;
@@ -625,7 +640,7 @@ inline local_internals &get_local_internals() {
625
640
}
626
641
627
642
#ifdef Py_GIL_DISABLED
628
- # define PYBIND11_LOCK_INTERNALS (internals ) std::unique_lock<std::mutex > lock ((internals).mutex)
643
+ # define PYBIND11_LOCK_INTERNALS (internals ) std::unique_lock<pymutex > lock ((internals).mutex)
629
644
#else
630
645
# define PYBIND11_LOCK_INTERNALS (internals )
631
646
#endif
@@ -662,7 +677,7 @@ inline auto with_instance_map(const void *ptr,
662
677
auto idx = static_cast <size_t >(hash & internals.instance_shards_mask );
663
678
664
679
auto &shard = internals.instance_shards [idx];
665
- std::unique_lock<std::mutex > lock (shard.mutex );
680
+ std::unique_lock<pymutex > lock (shard.mutex );
666
681
return cb (shard.registered_instances );
667
682
#else
668
683
(void ) ptr;
@@ -678,7 +693,7 @@ inline size_t num_registered_instances() {
678
693
size_t count = 0 ;
679
694
for (size_t i = 0 ; i <= internals.instance_shards_mask ; ++i) {
680
695
auto &shard = internals.instance_shards [i];
681
- std::unique_lock<std::mutex > lock (shard.mutex );
696
+ std::unique_lock<pymutex > lock (shard.mutex );
682
697
count += shard.registered_instances .size ();
683
698
}
684
699
return count;
0 commit comments