Hash :
f16e94cd
Author :
Date :
2020-06-17T10:43:19
Prefer retrieval of TLS values through ASM code on Android On the Android platform prefer using the ASM code to retrieve TLS context object even for single threaded apps. This helps get rid of a branch in GetGlobalContext() and GetValidGlobalContext() further improving the CPU perf of TLS operations. Bug: angleproject:4717 Change-Id: I58d3d3b7061d613b24f945c07bed497c7c4be25c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2250318 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// tls.h: Simple cross-platform interface for thread local storage.
#ifndef COMMON_TLS_H_
#define COMMON_TLS_H_
#include "common/angleutils.h"
#include "common/platform.h"
namespace gl
{
class Context;
}
#ifdef ANGLE_PLATFORM_WINDOWS
// TLS does not exist for Windows Store and needs to be emulated
# ifdef ANGLE_ENABLE_WINDOWS_UWP
# ifndef TLS_OUT_OF_INDEXES
# define TLS_OUT_OF_INDEXES static_cast<DWORD>(0xFFFFFFFF)
# endif
# ifndef CREATE_SUSPENDED
# define CREATE_SUSPENDED 0x00000004
# endif
# endif
typedef DWORD TLSIndex;
# define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
#elif defined(ANGLE_PLATFORM_POSIX)
# include <errno.h>
# include <pthread.h>
# include <semaphore.h>
typedef pthread_key_t TLSIndex;
# define TLS_INVALID_INDEX (static_cast<TLSIndex>(-1))
#else
# error Unsupported platform.
#endif
#if defined(ANGLE_PLATFORM_ANDROID)
// The following ASM variant provides a much more performant store/retrieve interface
// compared to those provided by the pthread library. These have been derived from code
// in the bionic module of Android ->
// https://cs.android.com/android/platform/superproject/+/master:bionic/libc/platform/bionic/tls.h;l=30
# if defined(__aarch64__)
# define ANGLE_ANDROID_GET_GL_TLS() \
({ \
void **__val; \
__asm__("mrs %0, tpidr_el0" : "=r"(__val)); \
__val; \
})
# elif defined(__arm__)
# define ANGLE_ANDROID_GET_GL_TLS() \
({ \
void **__val; \
__asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__val)); \
__val; \
})
# elif defined(__mips__)
// On mips32r1, this goes via a kernel illegal instruction trap that's
// optimized for v1
# define ANGLE_ANDROID_GET_GL_TLS() \
({ \
register void **__val asm("v1"); \
__asm__( \
".set push\n" \
".set mips32r2\n" \
"rdhwr %0,$29\n" \
".set pop\n" \
: "=r"(__val)); \
__val; \
})
# elif defined(__i386__)
# define ANGLE_ANDROID_GET_GL_TLS() \
({ \
void **__val; \
__asm__("movl %%gs:0, %0" : "=r"(__val)); \
__val; \
})
# elif defined(__x86_64__)
# define ANGLE_ANDROID_GET_GL_TLS() \
({ \
void **__val; \
__asm__("mov %%fs:0, %0" : "=r"(__val)); \
__val; \
})
# else
# error unsupported architecture
# endif
#endif // ANGLE_PLATFORM_ANDROID
// - TLS_SLOT_OPENGL and TLS_SLOT_OPENGL_API: These two aren't used by bionic
// itself, but allow the graphics code to access TLS directly rather than
// using the pthread API.
//
// Choose the TLS_SLOT_OPENGL TLS slot with the value that matches value in the header file in
// bionic(tls_defines.h)
constexpr TLSIndex kAndroidOpenGLTlsSlot = 3;
extern bool gUseAndroidOpenGLTlsSlot;
ANGLE_INLINE bool SetContextToAndroidOpenGLTLSSlot(gl::Context *value)
{
#if defined(ANGLE_PLATFORM_ANDROID)
if (gUseAndroidOpenGLTlsSlot)
{
ANGLE_ANDROID_GET_GL_TLS()[kAndroidOpenGLTlsSlot] = static_cast<void *>(value);
return true;
}
#endif
return false;
}
void SetUseAndroidOpenGLTlsSlot(bool platformTypeVulkan);
// TODO(kbr): for POSIX platforms this will have to be changed to take
// in a destructor function pointer, to allow the thread-local storage
// to be properly deallocated upon thread exit.
TLSIndex CreateTLSIndex();
bool DestroyTLSIndex(TLSIndex index);
bool SetTLSValue(TLSIndex index, void *value);
void *GetTLSValue(TLSIndex index);
#endif // COMMON_TLS_H_