Ignore:
File:
1 edited

Legend:

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

    r31399f3 rd2bb25e7  
    3434 * Support for thread-local storage, as described in:
    3535 *      Drepper U.: ELF Handling For Thread-Local Storage, 2005
    36  *
    37  * Only static model is supported.
    38  */
     36 */
    3937
    4038#include <tls.h>
    4139#include <malloc.h>
    4240#include <str.h>
    43 #include <align.h>
    4441#include <unistd.h>
    4542
     43#ifdef CONFIG_RTLD
     44#include <rtld/rtld.h>
     45#endif
     46
     47size_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 */
     57void *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
    4666/** 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.
    5067 *
    5168 * @return Pointer to TCB.
     
    5673        tcb_t *tcb;
    5774        size_t tls_size = &_tbss_end - &_tdata_start;
    58        
     75
     76#ifdef CONFIG_RTLD
     77        if (runtime_env != NULL)
     78                return rtld_tls_make(runtime_env);
     79#endif
    5980        tcb = tls_alloc_arch(&data, tls_size);
    6081        if (!tcb)
    6182                return NULL;
    62        
     83
    6384        /*
    6485         * Copy thread local data from the initialization image.
     
    7697void tls_free(tcb_t *tcb)
    7798{
    78         size_t tls_size = &_tbss_end - &_tdata_start;
    79         tls_free_arch(tcb, tls_size);
     99        free(tcb->dtv);
     100        tls_free_arch(tcb, tls_get_size());
    80101}
    81102
     
    89110tcb_t *tls_alloc_variant_1(void **data, size_t size)
    90111{
    91         tcb_t *result;
     112        tcb_t *tcb;
    92113
    93         result = malloc(sizeof(tcb_t) + size);
    94         if (!result)
     114        tcb = malloc(sizeof(tcb_t) + size);
     115        if (!tcb)
    95116                return NULL;
    96         *data = ((void *)result) + sizeof(tcb_t);
     117        *data = ((void *)tcb) + sizeof(tcb_t);
     118        tcb->dtv = NULL;
    97119
    98         return result;
     120        return tcb;
    99121}
    100122
     
    121143{
    122144        tcb_t *tcb;
    123        
    124         size = ALIGN_UP(size, &_tls_alignment);
    125         *data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size);
    126         if (!*data)
     145
     146        *data = malloc(sizeof(tcb_t) + size);
     147        if (*data == NULL)
    127148                return NULL;
    128149        tcb = (tcb_t *) (*data + size);
    129150        tcb->self = tcb;
     151        tcb->dtv = NULL;
    130152
    131153        return tcb;
     
    139161void tls_free_variant_2(tcb_t *tcb, size_t size)
    140162{
    141         size = ALIGN_UP(size, &_tls_alignment);
    142163        void *start = ((void *) tcb) - size;
    143164        free(start);
Note: See TracChangeset for help on using the changeset viewer.