Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/tls.c

    rd2bb25e7 r31399f3  
    3434 * Support for thread-local storage, as described in:
    3535 *      Drepper U.: ELF Handling For Thread-Local Storage, 2005
    36  */
     36 *
     37 * Only static model is supported.
     38 */
    3739
    3840#include <tls.h>
    3941#include <malloc.h>
    4042#include <str.h>
     43#include <align.h>
    4144#include <unistd.h>
    4245
    43 #ifdef CONFIG_RTLD
    44 #include <rtld/rtld.h>
    45 #endif
    46 
    47 size_t tls_get_size(void)
    48 {
    49 #ifdef CONFIG_RTLD
    50         if (runtime_env != NULL)
    51                 return runtime_env->tls_size;
    52 #endif
    53         return &_tbss_end - &_tdata_start;
    54 }
    55 
    56 /** Get address of static TLS block */
    57 void *tls_get(void)
    58 {
    59 #ifdef CONFIG_TLS_VARIANT_1
    60         return (uint8_t *)__tcb_get() + sizeof(tcb_t);
    61 #else /* CONFIG_TLS_VARIANT_2 */
    62         return (uint8_t *)__tcb_get() - tls_get_size();
    63 #endif
    64 }
    65 
    6646/** Create TLS (Thread Local Storage) data structures.
     47 *
     48 * The code requires, that sections .tdata and .tbss are adjacent. It may be
     49 * changed in the future.
    6750 *
    6851 * @return Pointer to TCB.
     
    7356        tcb_t *tcb;
    7457        size_t tls_size = &_tbss_end - &_tdata_start;
    75 
    76 #ifdef CONFIG_RTLD
    77         if (runtime_env != NULL)
    78                 return rtld_tls_make(runtime_env);
    79 #endif
     58       
    8059        tcb = tls_alloc_arch(&data, tls_size);
    8160        if (!tcb)
    8261                return NULL;
    83 
     62       
    8463        /*
    8564         * Copy thread local data from the initialization image.
     
    9776void tls_free(tcb_t *tcb)
    9877{
    99         free(tcb->dtv);
    100         tls_free_arch(tcb, tls_get_size());
     78        size_t tls_size = &_tbss_end - &_tdata_start;
     79        tls_free_arch(tcb, tls_size);
    10180}
    10281
     
    11089tcb_t *tls_alloc_variant_1(void **data, size_t size)
    11190{
    112         tcb_t *tcb;
     91        tcb_t *result;
    11392
    114         tcb = malloc(sizeof(tcb_t) + size);
    115         if (!tcb)
     93        result = malloc(sizeof(tcb_t) + size);
     94        if (!result)
    11695                return NULL;
    117         *data = ((void *)tcb) + sizeof(tcb_t);
    118         tcb->dtv = NULL;
     96        *data = ((void *)result) + sizeof(tcb_t);
    11997
    120         return tcb;
     98        return result;
    12199}
    122100
     
    143121{
    144122        tcb_t *tcb;
    145 
    146         *data = malloc(sizeof(tcb_t) + size);
    147         if (*data == NULL)
     123       
     124        size = ALIGN_UP(size, &_tls_alignment);
     125        *data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size);
     126        if (!*data)
    148127                return NULL;
    149128        tcb = (tcb_t *) (*data + size);
    150129        tcb->self = tcb;
    151         tcb->dtv = NULL;
    152130
    153131        return tcb;
     
    161139void tls_free_variant_2(tcb_t *tcb, size_t size)
    162140{
     141        size = ALIGN_UP(size, &_tls_alignment);
    163142        void *start = ((void *) tcb) - size;
    164143        free(start);
Note: See TracChangeset for help on using the changeset viewer.