123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- #pragma once
- #if IL2CPP_THREADS_PTHREAD
- #include "os/ErrorCodes.h"
- #include "utils/NonCopyable.h"
- #include <pthread.h>
- namespace il2cpp
- {
- namespace os
- {
- class ThreadLocalValueImpl : public il2cpp::utils::NonCopyable
- {
- public:
- inline ThreadLocalValueImpl()
- {
- pthread_key_t key;
- int result = pthread_key_create(&key, NULL);
- IL2CPP_ASSERT(result == 0);
- NO_UNUSED_WARNING(result);
- m_Key = key;
- }
- inline ~ThreadLocalValueImpl()
- {
- int result = pthread_key_delete(m_Key);
- IL2CPP_ASSERT(result == 0);
- NO_UNUSED_WARNING(result);
- }
- inline ErrorCode SetValue(void* value)
- {
- #if IL2CPP_TARGET_DARWIN
- apple_pthread_setspecific_direct(m_Key, value);
- #else
- if (pthread_setspecific(m_Key, value))
- return kErrorCodeGenFailure;
- #endif
- return kErrorCodeSuccess;
- }
- inline ErrorCode GetValue(void** value)
- {
- #if IL2CPP_TARGET_DARWIN
- *value = apple_pthread_getspecific_direct(m_Key);
- #else
- *value = pthread_getspecific(m_Key);
- #endif
- return kErrorCodeSuccess;
- }
- private:
- #if IL2CPP_TARGET_DARWIN
- static inline void * apple_pthread_getspecific_direct(unsigned long slot)
- {
- void *ret;
- #if defined(__i386__) || defined(__x86_64__)
- __asm__ ("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void**)(slot * sizeof(void *))));
- #elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5)))
- void **__pthread_tsd;
- #if defined(__arm__) && defined(_ARM_ARCH_6)
- uintptr_t __pthread_tpid;
- __asm__ ("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid));
- __pthread_tsd = (void**)(__pthread_tpid & ~0x3ul);
- #elif defined(__arm__) && defined(_ARM_ARCH_5)
- register uintptr_t __pthread_tpid asm ("r9");
- __pthread_tsd = (void**)__pthread_tpid;
- #endif
- ret = __pthread_tsd[slot];
- #elif defined(__arm64__)
- ret = pthread_getspecific(slot);
- #else
- #error no _pthread_getspecific_direct implementation for this arch
- #endif
- return ret;
- }
- inline static void apple_pthread_setspecific_direct(unsigned long slot, void * val)
- {
- #if defined(__i386__)
- #if defined(__PIC__)
- __asm__ ("movl %1,%%gs:%0" : "=m" (*(void**)(slot * sizeof(void *))) : "rn" (val));
- #else
- __asm__ ("movl %1,%%gs:%0" : "=m" (*(void**)(slot * sizeof(void *))) : "ri" (val));
- #endif
- #elif defined(__x86_64__)
- /* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */
- __asm__ ("movq %1,%%gs:%0" : "=m" (*(void**)(slot * sizeof(void *))) : "rn" (val));
- #elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5)))
- void **__pthread_tsd;
- #if defined(__arm__) && defined(_ARM_ARCH_6)
- uintptr_t __pthread_tpid;
- __asm__ ("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid));
- __pthread_tsd = (void**)(__pthread_tpid & ~0x3ul);
- #elif defined(__arm__) && defined(_ARM_ARCH_5)
- register uintptr_t __pthread_tpid asm ("r9");
- __pthread_tsd = (void**)__pthread_tpid;
- #endif
- __pthread_tsd[slot] = val;
- #elif defined(__arm64__)
- pthread_setspecific(slot, val);
- #else
- #error no _pthread_setspecific_direct implementation for this arch
- #endif
- }
- #endif
- pthread_key_t m_Key;
- };
- }
- }
- #endif
|