@@ -212,7 +212,7 @@ struct ServiceRegistry {
212212 // / hash used to identify the service, @a service is
213213 // / a type erased pointer to the service itself.
214214 // / This method is supposed to be thread safe
215- void registerService (ServiceTypeHash typeHash, void * service, ServiceKind kind, uint64_t threadId , char const * name = nullptr ) const ;
215+ void registerService (ServiceTypeHash typeHash, void * service, ServiceKind kind, Salt salt , char const * name = nullptr ) const ;
216216
217217 // Lookup a given @a typeHash for a given @a threadId at
218218 // a unique (per typeHash) location. There might
@@ -222,12 +222,13 @@ struct ServiceRegistry {
222222 // as guaranteed by the atomic, mServicesKey[i + id] will
223223 // either be 0 or the final value.
224224 // This method should NEVER register a new service, event when requested.
225- int getPos (ServiceTypeHash typeHash, uint64_t threadId ) const
225+ int getPos (ServiceTypeHash typeHash, Salt salt ) const
226226 {
227- auto threadHashId = (typeHash.hash ^ threadId) & MAX_SERVICES_MASK ;
227+ InstanceId instanceId = instanceFromTypeSalt (typeHash, salt);
228+ Index index = indexFromInstance (instanceId);
228229 for (uint8_t i = 0 ; i < MAX_DISTANCE ; ++i) {
229- if (mServicesKey [i + threadHashId ].load () == typeHash.hash ) {
230- return i + threadHashId ;
230+ if (mServicesKey [i + index. index ].load () == typeHash.hash ) {
231+ return i + index. index ;
231232 }
232233 }
233234 return -1 ;
@@ -241,15 +242,15 @@ struct ServiceRegistry {
241242 // if the service is not a stream service and the global
242243 // zero service is available.
243244 // Use this API only if you know what you are doing.
244- void * get (ServiceTypeHash typeHash, uint64_t threadId , ServiceKind kind, char const * name = nullptr ) const
245+ void * get (ServiceTypeHash typeHash, Salt salt , ServiceKind kind, char const * name = nullptr ) const
245246 {
246247 // Look for the service. If found, return it.
247248 // Notice how due to threading issues, we might
248249 // find it with getPos, but the value can still
249250 // be nullptr.
250- auto pos = getPos (typeHash, threadId );
251- if (pos != -1 && mServicesMeta [pos].kind == ServiceKind::Stream && mServicesMeta [pos].threadId != threadId ) {
252- throwError (runtime_error_f (" Inconsistent registry for thread %d. Expected %d" , threadId , mServicesMeta [pos].threadId ));
251+ auto pos = getPos (typeHash, salt );
252+ if (pos != -1 && mServicesMeta [pos].kind == ServiceKind::Stream && mServicesMeta [pos].salt . value != salt. value ) {
253+ throwError (runtime_error_f (" Inconsistent registry for thread %d. Expected %d" , salt. context . streamId , mServicesMeta [pos].salt . context . streamId ));
253254 O2_BUILTIN_UNREACHABLE ();
254255 }
255256
@@ -264,12 +265,12 @@ struct ServiceRegistry {
264265 // We are looking up a service which is not of
265266 // stream kind and was not looked up by this thread
266267 // before.
267- if (threadId != 0 ) {
268- int pos = getPos (typeHash, 0 );
268+ if (salt. value != GLOBAL_CONTEXT_SALT . value ) {
269+ int pos = getPos (typeHash, GLOBAL_CONTEXT_SALT );
269270 if (pos != -1 && kind != ServiceKind::Stream) {
270271 mServicesKey [pos].load ();
271272 std::atomic_thread_fence (std::memory_order_acquire);
272- registerService (typeHash, mServicesValue [pos], kind, threadId , name);
273+ registerService (typeHash, mServicesValue [pos], kind, salt , name);
273274 }
274275 if (pos != -1 ) {
275276 mServicesKey [pos].load ();
@@ -289,13 +290,14 @@ struct ServiceRegistry {
289290 {
290291 auto tid = std::this_thread::get_id ();
291292 std::hash<std::thread::id> hasher;
292- ServiceRegistry::registerService ({handle.hash }, handle.instance , handle.kind , hasher (tid), handle.name .c_str ());
293+ Salt salt{Context{.streamId = (short )hasher (tid)}};
294+ ServiceRegistry::registerService ({handle.hash }, handle.instance , handle.kind , salt, handle.name .c_str ());
293295 }
294296
295297 mutable std::vector<ServiceSpec> mSpecs ;
296298 mutable std::array<std::atomic<uint32_t >, MAX_SERVICES + MAX_DISTANCE > mServicesKey ;
297299 mutable std::array<void *, MAX_SERVICES + MAX_DISTANCE > mServicesValue ;
298- mutable std::array<ServiceMeta , MAX_SERVICES + MAX_DISTANCE > mServicesMeta ;
300+ mutable std::array<Meta , MAX_SERVICES + MAX_DISTANCE > mServicesMeta ;
299301 mutable std::array<std::atomic<bool >, MAX_SERVICES + MAX_DISTANCE > mServicesBooked ;
300302
301303 // / @deprecated old API to be substituted with the ServiceHandle one
@@ -310,7 +312,8 @@ struct ServiceRegistry {
310312 constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId<I>()};
311313 auto tid = std::this_thread::get_id ();
312314 std::hash<std::thread::id> hasher;
313- ServiceRegistry::registerService (typeHash, reinterpret_cast <void *>(service), K, hasher (tid), typeid (C).name ());
315+ Salt salt = Salt{Context{.streamId = (short )hasher (tid)}};
316+ ServiceRegistry::registerService (typeHash, reinterpret_cast <void *>(service), K, salt, typeid (C).name ());
314317 }
315318
316319 // / @deprecated old API to be substituted with the ServiceHandle one
@@ -325,7 +328,8 @@ struct ServiceRegistry {
325328 constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId<I const >()};
326329 auto tid = std::this_thread::get_id ();
327330 std::hash<std::thread::id> hasher;
328- this ->registerService (typeHash, reinterpret_cast <void *>(const_cast <C*>(service)), K, hasher (tid), typeid (C).name ());
331+ Salt salt = Salt{Context{.streamId = (short )hasher (tid)}};
332+ this ->registerService (typeHash, reinterpret_cast <void *>(const_cast <C*>(service)), K, salt, typeid (C).name ());
329333 }
330334
331335 // / Check if service of type T is currently active.
@@ -335,10 +339,11 @@ struct ServiceRegistry {
335339 constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId<T>()};
336340 auto tid = std::this_thread::get_id ();
337341 std::hash<std::thread::id> hasher;
338- if (this ->getPos (typeHash, 0 ) != -1 ) {
342+ if (this ->getPos (typeHash, GLOBAL_CONTEXT_SALT ) != -1 ) {
339343 return true ;
340344 }
341- auto result = this ->getPos (typeHash, hasher (tid)) != -1 ;
345+ Salt salt = Salt{Context{.streamId = (short )hasher (tid)}};
346+ auto result = this ->getPos (typeHash, salt) != -1 ;
342347 return result;
343348 }
344349
@@ -351,7 +356,8 @@ struct ServiceRegistry {
351356 constexpr ServiceTypeHash typeHash{TypeIdHelpers::uniqueId<T>()};
352357 auto tid = std::this_thread::get_id ();
353358 std::hash<std::thread::id> hasher;
354- auto ptr = this ->get (typeHash, hasher (tid), ServiceKind::Serial, typeid (T).name ());
359+ Salt salt = Salt{Context{.streamId = (short )hasher (tid)}};
360+ auto ptr = this ->get (typeHash, salt, ServiceKind::Serial, typeid (T).name ());
355361 if (O2_BUILTIN_LIKELY (ptr != nullptr )) {
356362 if constexpr (std::is_const_v<T>) {
357363 return *reinterpret_cast <T const *>(ptr);
0 commit comments