Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Jian Li <jianli@chromium.org> | 3 * Copyright (C) 2009 Jian Li <jianli@chromium.org> |
| 4 * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com> | 4 * Copyright (C) 2012 Patrick Gansterer <paroga@paroga.com> |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * | 9 * |
| 10 * 1. Redistributions of source code must retain the above copyright | 10 * 1. Redistributions of source code must retain the above copyright |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 * only once. | 37 * only once. |
| 38 * This semantic discrepancy does not impose any problem because nowhere in | 38 * This semantic discrepancy does not impose any problem because nowhere in |
| 39 * WebKit the repeated call bahavior is utilized. | 39 * WebKit the repeated call bahavior is utilized. |
| 40 */ | 40 */ |
| 41 | 41 |
| 42 #ifndef WTF_ThreadSpecific_h | 42 #ifndef WTF_ThreadSpecific_h |
| 43 #define WTF_ThreadSpecific_h | 43 #define WTF_ThreadSpecific_h |
| 44 | 44 |
| 45 #include "wtf/Allocator.h" | 45 #include "wtf/Allocator.h" |
| 46 #include "wtf/Noncopyable.h" | 46 #include "wtf/Noncopyable.h" |
| 47 #include "wtf/StackUtil.h" | |
| 47 #include "wtf/StdLibExtras.h" | 48 #include "wtf/StdLibExtras.h" |
| 48 #include "wtf/WTF.h" | 49 #include "wtf/WTF.h" |
| 49 #include "wtf/WTFExport.h" | 50 #include "wtf/WTFExport.h" |
| 50 #include "wtf/allocator/PartitionAllocator.h" | 51 #include "wtf/allocator/PartitionAllocator.h" |
| 51 #include "wtf/allocator/Partitions.h" | 52 #include "wtf/allocator/Partitions.h" |
| 52 | 53 |
| 53 #if OS(POSIX) | 54 #if OS(POSIX) |
| 54 #include <pthread.h> | 55 #include <pthread.h> |
| 55 #elif OS(WIN) | 56 #elif OS(WIN) |
| 56 #include <windows.h> | 57 #include <windows.h> |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 106 #if OS(WIN) | 107 #if OS(WIN) |
| 107 void (*destructor)(void*); | 108 void (*destructor)(void*); |
| 108 #endif | 109 #endif |
| 109 }; | 110 }; |
| 110 | 111 |
| 111 #if OS(POSIX) | 112 #if OS(POSIX) |
| 112 pthread_key_t m_key; | 113 pthread_key_t m_key; |
| 113 #elif OS(WIN) | 114 #elif OS(WIN) |
| 114 int m_index; | 115 int m_index; |
| 115 #endif | 116 #endif |
| 117 // This member must only be accessed or modified on the main thread. | |
| 118 T* m_mainThreadStorage = nullptr; | |
| 116 }; | 119 }; |
| 117 | 120 |
| 118 #if OS(POSIX) | 121 #if OS(POSIX) |
| 119 | 122 |
| 120 typedef pthread_key_t ThreadSpecificKey; | 123 typedef pthread_key_t ThreadSpecificKey; |
| 121 | 124 |
| 122 inline void threadSpecificKeyCreate(ThreadSpecificKey* key, | 125 inline void threadSpecificKeyCreate(ThreadSpecificKey* key, |
| 123 void (*destructor)(void*)) { | 126 void (*destructor)(void*)) { |
| 124 int error = pthread_key_create(key, destructor); | 127 int error = pthread_key_create(key, destructor); |
| 125 if (error) | 128 if (error) |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 delete data; | 257 delete data; |
| 255 } | 258 } |
| 256 | 259 |
| 257 template <typename T> | 260 template <typename T> |
| 258 inline bool ThreadSpecific<T>::isSet() { | 261 inline bool ThreadSpecific<T>::isSet() { |
| 259 return !!get(); | 262 return !!get(); |
| 260 } | 263 } |
| 261 | 264 |
| 262 template <typename T> | 265 template <typename T> |
| 263 inline ThreadSpecific<T>::operator T*() { | 266 inline ThreadSpecific<T>::operator T*() { |
| 264 T* ptr = static_cast<T*>(get()); | 267 T* offThreadPtr; |
| 265 if (!ptr) { | 268 #if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD) |
| 266 // Set up thread-specific value's memory pointer before invoking | 269 // TLS is fast on these platforms. |
| 267 // constructor, in case any function it calls | 270 // TODO(csharrison): Qualify this statement for Android. |
| 268 // needs to access the value, to avoid recursion. | 271 T** ptr = &offThreadPtr; |
| 269 ptr = static_cast<T*>(Partitions::fastZeroedMalloc( | 272 offThreadPtr = static_cast<T*>(get()); |
| 273 #else | |
| 274 T** ptr = &m_mainThreadStorage; | |
| 275 if (UNLIKELY(internal::mayNotBeMainThread())) { | |
| 276 offThreadPtr = static_cast<T*>(get()); | |
| 277 ptr = &offThreadPtr; | |
| 278 } | |
| 279 #endif | |
| 280 // Set up thread-specific value's memory pointer before invoking constructor, | |
| 281 // in case any function it calls needs to access the value, to avoid | |
| 282 // recursion. | |
| 283 if (UNLIKELY(!*ptr)) { | |
|
haraken
2017/01/18 05:29:42
Can we just use if(!offThreadPtr) ? I don't fully
haraken
2017/01/18 05:29:42
Not related to this CL but we might want to remove
Charlie Harrison
2017/01/18 16:29:55
Acknowledged, though I wonder if that would lead t
Charlie Harrison
2017/01/18 16:29:55
We use pointer indirection here because ptr can po
haraken
2017/01/19 01:04:38
Thread initialization is already heavy, so I don't
| |
| 284 *ptr = static_cast<T*>(Partitions::fastZeroedMalloc( | |
| 270 sizeof(T), WTF_HEAP_PROFILER_TYPE_NAME(T))); | 285 sizeof(T), WTF_HEAP_PROFILER_TYPE_NAME(T))); |
| 271 set(ptr); | 286 set(*ptr); |
| 272 new (NotNull, ptr) T; | 287 new (NotNull, *ptr) T; |
| 273 } | 288 } |
| 274 return ptr; | 289 return *ptr; |
| 275 } | 290 } |
| 276 | 291 |
| 277 template <typename T> | 292 template <typename T> |
| 278 inline T* ThreadSpecific<T>::operator->() { | 293 inline T* ThreadSpecific<T>::operator->() { |
| 279 return operator T*(); | 294 return operator T*(); |
| 280 } | 295 } |
| 281 | 296 |
| 282 template <typename T> | 297 template <typename T> |
| 283 inline T& ThreadSpecific<T>::operator*() { | 298 inline T& ThreadSpecific<T>::operator*() { |
| 284 return *operator T*(); | 299 return *operator T*(); |
| 285 } | 300 } |
| 286 | 301 |
| 287 } // namespace WTF | 302 } // namespace WTF |
| 288 | 303 |
| 289 using WTF::ThreadSpecific; | 304 using WTF::ThreadSpecific; |
| 290 | 305 |
| 291 #endif // WTF_ThreadSpecific_h | 306 #endif // WTF_ThreadSpecific_h |
| OLD | NEW |