kernel: add common bits to support TLS
This adds the common struct fields and functions to support the implementation of thread local storage in individual architecture. This uses the thread stack to store TLS data. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
3180fc0ecc
commit
02b20351cd
|
@ -291,6 +291,11 @@ zephyr_cc_option(-fno-pie)
|
|||
zephyr_cc_option(-fno-pic)
|
||||
zephyr_cc_option(-fno-strict-overflow)
|
||||
|
||||
if(CONFIG_THREAD_LOCAL_STORAGE)
|
||||
# Only support local exec TLS model at this point.
|
||||
zephyr_cc_option(-ftls-model=local-exec)
|
||||
endif()
|
||||
|
||||
if(CONFIG_OVERRIDE_FRAME_POINTER_DEFAULT)
|
||||
if(CONFIG_OMIT_FRAME_POINTER)
|
||||
zephyr_cc_option(-fomit-frame-pointer)
|
||||
|
|
|
@ -365,6 +365,11 @@ struct k_thread {
|
|||
/** resource pool */
|
||||
struct k_mem_pool *resource_pool;
|
||||
|
||||
#if defined(CONFIG_THREAD_LOCAL_STORAGE)
|
||||
/* Pointer to arch-specific TLS area */
|
||||
uintptr_t tls;
|
||||
#endif /* CONFIG_THREAD_LOCAL_STORAGE */
|
||||
|
||||
/** arch-specifics: must always be at the end */
|
||||
struct _thread_arch arch;
|
||||
};
|
||||
|
|
|
@ -349,6 +349,26 @@ uint16_t arch_coredump_tgt_code_get(void);
|
|||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @defgroup arch-tls Architecture-specific Thread Local Storage APIs
|
||||
* @ingroup arch-interface
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup Architecture-specific TLS area in stack
|
||||
*
|
||||
* This sets up the stack area for thread local storage.
|
||||
* The structure inside in area is architecture specific.
|
||||
*
|
||||
* @param new_thread New thread object
|
||||
* @param stack_ptr Stack pointer
|
||||
* @return Number of bytes taken by the TLS area
|
||||
*/
|
||||
size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr);
|
||||
|
||||
/** @} */
|
||||
|
||||
/* Include arch-specific inline function implementation */
|
||||
#include <kernel_arch_func.h>
|
||||
|
||||
|
|
|
@ -77,6 +77,10 @@ GEN_OFFSET_SYM(_thread_t, next_thread);
|
|||
GEN_OFFSET_SYM(_thread_t, custom_data);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_THREAD_LOCAL_STORAGE
|
||||
GEN_OFFSET_SYM(_thread_t, tls);
|
||||
#endif
|
||||
|
||||
GEN_ABSOLUTE_SYM(K_THREAD_SIZEOF, sizeof(struct k_thread));
|
||||
|
||||
/* size of the device structure. Used by linker scripts */
|
||||
|
|
55
kernel/include/kernel_tls.h
Normal file
55
kernel/include/kernel_tls.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Kernel Thread Local Storage APIs.
|
||||
*
|
||||
* Kernel APIs related to thread local storage.
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_KERNEL_INCLUDE_KERNEL_TLS_H_
|
||||
#define ZEPHYR_KERNEL_INCLUDE_KERNEL_TLS_H_
|
||||
|
||||
#include <linker/linker-defs.h>
|
||||
|
||||
/**
|
||||
* @brief Return the total size of TLS data/bss areas
|
||||
*
|
||||
* This returns the total size of thread local storage (TLS)
|
||||
* data and bss areas as defined in the linker script.
|
||||
* Note that this does not include any architecture specific
|
||||
* bits required for proper functionality of TLS.
|
||||
*
|
||||
* @return Total size of TLS data/bss areas
|
||||
*/
|
||||
static inline size_t z_tls_data_size(void)
|
||||
{
|
||||
return (size_t)__tls_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copy the TLS data/bss areas into destination
|
||||
*
|
||||
* This copies the TLS data into destination and clear the area
|
||||
* of TLS bss size after the data section.
|
||||
*
|
||||
* @param dest Pointer to destination
|
||||
*/
|
||||
static inline void z_tls_copy(char *dest)
|
||||
{
|
||||
size_t tdata_size = (size_t)__tdata_size;
|
||||
size_t tbss_size = (size_t)__tbss_size;
|
||||
|
||||
/* Copy initialized data (tdata) */
|
||||
memcpy(dest, __tdata_start, tdata_size);
|
||||
|
||||
/* Clear BSS data (tbss) */
|
||||
dest += tdata_size;
|
||||
memset(dest, 0, tbss_size);
|
||||
}
|
||||
|
||||
#endif /* ZEPHYR_KERNEL_INCLUDE_KERNEL_TLS_H_ */
|
|
@ -44,6 +44,11 @@
|
|||
#define _thread_offset_to_callee_saved \
|
||||
(___thread_t_callee_saved_OFFSET)
|
||||
|
||||
#ifdef CONFIG_THREAD_LOCAL_STORAGE
|
||||
#define _thread_offset_to_tls \
|
||||
(___thread_t_tls_OFFSET)
|
||||
#endif /* CONFIG_THREAD_LOCAL_STORAGE */
|
||||
|
||||
/* base */
|
||||
|
||||
#define _thread_offset_to_thread_state \
|
||||
|
|
|
@ -492,6 +492,9 @@ static char *setup_thread_stack(struct k_thread *new_thread,
|
|||
*/
|
||||
*((uint32_t *)stack_buf_start) = STACK_SENTINEL;
|
||||
#endif /* CONFIG_STACK_SENTINEL */
|
||||
#ifdef CONFIG_THREAD_LOCAL_STORAGE
|
||||
delta += arch_tls_stack_setup(new_thread, (stack_ptr - delta));
|
||||
#endif /* CONFIG_THREAD_LOCAL_STORAGE */
|
||||
#ifdef CONFIG_THREAD_USERSPACE_LOCAL_DATA
|
||||
size_t tls_size = sizeof(struct _thread_userspace_local_data);
|
||||
|
||||
|
|
Loading…
Reference in a new issue