Implement type safety for TLS (#26942)
* Implement type safety for TLS This is mostly free when compiler support is available, but requires careful templating when implemented using pthread. Significantly slimmed the tls.h interface; it now only defines the "TLS keyword" for each supported compiler, delegating enforcement of correct usage (i.e. must be static) to the compiler itself. Implemented implicit conversion for the pthread wrapper so it can be used (mostly) the same as native support. Notable exception to this is that static_cast<void*> is needed when printing a pointer stored in TLS as %p. * Use GPR_THREAD_LOCAL macros consistentlypull/26974/head
parent
59d7f38184
commit
00c03c55ff
33 changed files with 226 additions and 456 deletions
@ -1,52 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_GPR_TLS_GCC_H |
||||
#define GRPC_CORE_LIB_GPR_TLS_GCC_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <stdbool.h> |
||||
|
||||
#include <grpc/support/log.h> |
||||
|
||||
/** Thread local storage based on gcc compiler primitives.
|
||||
#include tls.h to use this - and see that file for documentation */ |
||||
|
||||
struct gpr_gcc_thread_local { |
||||
intptr_t value; |
||||
}; |
||||
|
||||
#define GPR_TLS_DECL(name) \ |
||||
static __thread struct gpr_gcc_thread_local name = {0} |
||||
|
||||
#define GPR_TLS_CLASS_DECL(name) \ |
||||
static __thread struct gpr_gcc_thread_local name |
||||
|
||||
#define GPR_TLS_CLASS_DEF(name) __thread struct gpr_gcc_thread_local name = {0} |
||||
|
||||
#define gpr_tls_init(tls) \ |
||||
do { \
|
||||
} while (0) |
||||
#define gpr_tls_destroy(tls) \ |
||||
do { \
|
||||
} while (0) |
||||
#define gpr_tls_set(tls, new_value) (((tls)->value) = (new_value)) |
||||
#define gpr_tls_get(tls) ((tls)->value) |
||||
|
||||
#endif /* GRPC_CORE_LIB_GPR_TLS_GCC_H */ |
@ -1,54 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_GPR_TLS_MSVC_H |
||||
#define GRPC_CORE_LIB_GPR_TLS_MSVC_H |
||||
|
||||
/** Thread local storage based on ms visual c compiler primitives.
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include tls.h to use this - and see that file for documentation */ |
||||
|
||||
#include <cstdint> |
||||
|
||||
struct gpr_msvc_thread_local { |
||||
intptr_t value; |
||||
}; |
||||
|
||||
/** Use GPR_TLS_DECL to declare tls static variables outside a class */ |
||||
#define GPR_TLS_DECL(name) \ |
||||
static __declspec(thread) struct gpr_msvc_thread_local name = {0} |
||||
|
||||
/** Use GPR_TLS_CLASS_DECL to declare tls static variable members of a class.
|
||||
* GPR_TLS_CLASS_DEF needs to be called to define this member. */ |
||||
#define GPR_TLS_CLASS_DECL(name) \ |
||||
static __declspec(thread) struct gpr_msvc_thread_local name |
||||
|
||||
#define GPR_TLS_CLASS_DEF(name) \ |
||||
__declspec(thread) struct gpr_msvc_thread_local name = {0} |
||||
|
||||
#define gpr_tls_init(tls) \ |
||||
do { \
|
||||
} while (0) |
||||
#define gpr_tls_destroy(tls) \ |
||||
do { \
|
||||
} while (0) |
||||
#define gpr_tls_set(tls, new_value) (((tls)->value) = (new_value)) |
||||
#define gpr_tls_get(tls) ((tls)->value) |
||||
|
||||
#endif /* GRPC_CORE_LIB_GPR_TLS_MSVC_H */ |
@ -1,30 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#ifdef GPR_PTHREAD_TLS |
||||
|
||||
#include "src/core/lib/gpr/tls.h" |
||||
|
||||
intptr_t gpr_tls_set(struct gpr_pthread_thread_local* tls, intptr_t value) { |
||||
GPR_ASSERT(0 == pthread_setspecific(tls->key, (void*)value)); |
||||
return value; |
||||
} |
||||
|
||||
#endif /* GPR_PTHREAD_TLS */ |
@ -1,56 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2015 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_GPR_TLS_PTHREAD_H |
||||
#define GRPC_CORE_LIB_GPR_TLS_PTHREAD_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpc/support/log.h> /* for GPR_ASSERT */ |
||||
#include <pthread.h> |
||||
|
||||
/** Thread local storage based on pthread library calls.
|
||||
#include tls.h to use this - and see that file for documentation */ |
||||
|
||||
struct gpr_pthread_thread_local { |
||||
pthread_key_t key; |
||||
}; |
||||
|
||||
/** Use GPR_TLS_DECL to declare tls static variables outside a class */ |
||||
#define GPR_TLS_DECL(name) static struct gpr_pthread_thread_local name = {0} |
||||
|
||||
/** Use GPR_TLS_CLASS_DECL to declare tls static variable members of a class.
|
||||
* GPR_TLS_CLASS_DEF needs to be called to define this member. */ |
||||
#define GPR_TLS_CLASS_DECL(name) static struct gpr_pthread_thread_local name |
||||
|
||||
/** Use GPR_TLS_CLASS_DEF to declare tls static variable members of a class.
|
||||
* GPR_TLS_CLASS_DEF needs to be called to define this member. */ |
||||
#define GPR_TLS_CLASS_DEF(name) struct gpr_pthread_thread_local name = {0} |
||||
|
||||
#define gpr_tls_init(tls) GPR_ASSERT(0 == pthread_key_create(&(tls)->key, NULL)) |
||||
#define gpr_tls_destroy(tls) pthread_key_delete((tls)->key) |
||||
#define gpr_tls_get(tls) ((intptr_t)pthread_getspecific((tls)->key)) |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
intptr_t gpr_tls_set(struct gpr_pthread_thread_local* tls, intptr_t value); |
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
|
||||
#endif /* GRPC_CORE_LIB_GPR_TLS_PTHREAD_H */ |
@ -1,48 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2020 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_GPR_TLS_STDCPP_H |
||||
#define GRPC_CORE_LIB_GPR_TLS_STDCPP_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
/** Thread local storage based on C++ thread_local.
|
||||
#include tls.h to use this - and see that file for documentation */ |
||||
|
||||
/** Use GPR_TLS_DECL to declare tls static variables outside a class */ |
||||
#define GPR_TLS_DECL(name) thread_local static intptr_t name = 0 |
||||
|
||||
/** Use GPR_TLS_CLASS_DECL to declare tls static variable members of a class.
|
||||
* GPR_TLS_CLASS_DEF needs to be called to define this member. */ |
||||
#define GPR_TLS_CLASS_DECL(name) thread_local static intptr_t name |
||||
|
||||
#define GPR_TLS_CLASS_DEF(name) thread_local intptr_t name = 0 |
||||
|
||||
#define gpr_tls_init(tls) \ |
||||
do { \
|
||||
} while (0) |
||||
|
||||
#define gpr_tls_destroy(tls) \ |
||||
do { \
|
||||
} while (0) |
||||
|
||||
#define gpr_tls_set(tls, new_value) (*(tls) = (new_value)) |
||||
|
||||
#define gpr_tls_get(tls) (*(tls)) |
||||
|
||||
#endif /* GRPC_CORE_LIB_GPR_TLS_STDCPP_H */ |
Loading…
Reference in new issue