Skip to content

Commit

Permalink
Bug 756965 - Allow mozilla::ThreadLocal to store integer types smalle…
Browse files Browse the repository at this point in the history
…r than, or as large as, a pointer. r=Waldo
  • Loading branch information
glandium committed May 22, 2012
1 parent dc879d5 commit b2c6b65
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 12 deletions.
26 changes: 18 additions & 8 deletions mfbt/ThreadLocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,17 @@ class ThreadLocal
typedef pthread_key_t key_t;
#endif

union Helper {
void *ptr;
T value;
};

public:
MOZ_WARN_UNUSED_RESULT inline bool init();

inline T* get() const;
inline T get() const;

inline bool set(const T* value);
inline bool set(const T value);

bool initialized() const {
return inited;
Expand All @@ -91,6 +96,7 @@ class ThreadLocal
template <typename T>
inline bool
ThreadLocal<T>::init() {
MOZ_STATIC_ASSERT(sizeof(T) <= sizeof(void *), "mozilla::ThreadLocal can't be used for types larger than a pointer");
MOZ_ASSERT(!initialized());
#ifdef XP_WIN
key = TlsAlloc();
Expand All @@ -102,24 +108,28 @@ ThreadLocal<T>::init() {
}

template <typename T>
inline T*
inline T
ThreadLocal<T>::get() const {
MOZ_ASSERT(initialized());
Helper h;
#ifdef XP_WIN
return reinterpret_cast<T*>(TlsGetValue(key));
h.ptr = TlsGetValue(key);
#else
return reinterpret_cast<T*>(pthread_getspecific(key));
h.ptr = pthread_getspecific(key);
#endif
return h.value;
}

template <typename T>
inline bool
ThreadLocal<T>::set(const T* value) {
ThreadLocal<T>::set(const T value) {
MOZ_ASSERT(initialized());
Helper h;
h.value = value;
#ifdef XP_WIN
return TlsSetValue(key, const_cast<T*>(value));
return TlsSetValue(key, h.ptr);
#else
return !pthread_setspecific(key, value);
return !pthread_setspecific(key, h.ptr);
#endif
}

Expand Down
4 changes: 2 additions & 2 deletions tools/profiler/TableTicker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ using namespace mozilla;
#endif


mozilla::ThreadLocal<ProfileStack> tlsStack;
mozilla::ThreadLocal<TableTicker> tlsTicker;
mozilla::ThreadLocal<ProfileStack *> tlsStack;
mozilla::ThreadLocal<TableTicker *> tlsTicker;
// We need to track whether we've been initialized otherwise
// we end up using tlsStack without initializing it.
// Because tlsStack is totally opaque to us we can't reuse
Expand Down
4 changes: 2 additions & 2 deletions tools/profiler/sps_sampler.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ using mozilla::TimeDuration;
struct ProfileStack;
class TableTicker;

extern mozilla::ThreadLocal<ProfileStack> tlsStack;
extern mozilla::ThreadLocal<TableTicker> tlsTicker;
extern mozilla::ThreadLocal<ProfileStack *> tlsStack;
extern mozilla::ThreadLocal<TableTicker *> tlsTicker;
extern bool stack_key_initialized;

#ifndef SAMPLE_FUNCTION_NAME
Expand Down

0 comments on commit b2c6b65

Please sign in to comment.