Subversion Repositories HelenOS

Rev

Rev 3022 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2006 Jakub Jermar
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup libc
  30.  * @{
  31.  */
  32. /** @file
  33.  *
  34.  * Support for thread-local storage, as described in:
  35.  *  Drepper U.: ELF Handling For Thread-Local Storage, 2005
  36.  *
  37.  * Only static model is supported.
  38.  */
  39.  
  40. #include <tls.h>
  41. #include <malloc.h>
  42. #include <string.h>
  43. #include <align.h>
  44.  
  45. /** Create TLS (Thread Local Storage) data structures.
  46.  *
  47.  * The code requires, that sections .tdata and .tbss are adjacent. It may be
  48.  * changed in the future.
  49.  *
  50.  * @return Pointer to TCB.
  51.  */
  52. tcb_t *__make_tls(void)
  53. {
  54.     void *data;
  55.     tcb_t *tcb;
  56.     size_t tls_size = &_tbss_end - &_tdata_start;
  57.    
  58.     tcb = __alloc_tls(&data, tls_size);
  59.    
  60.     /*
  61.      * Copy thread local data from the initialization image.
  62.      */
  63.     memcpy(data, &_tdata_start, &_tdata_end - &_tdata_start);
  64.     /*
  65.      * Zero out the thread local uninitialized data.
  66.      */
  67.     memset(data + (&_tbss_start - &_tdata_start), 0,
  68.         &_tbss_end - &_tbss_start);
  69.  
  70.     return tcb;
  71. }
  72.  
  73. void __free_tls(tcb_t *tcb)
  74. {
  75.     size_t tls_size = &_tbss_end - &_tdata_start;
  76.     __free_tls_arch(tcb, tls_size);
  77. }
  78.  
  79. #ifdef CONFIG_TLS_VARIANT_1
  80. /** Allocate TLS variant 1 data structures.
  81.  *
  82.  * @param data      Start of TLS section. This is an output argument.
  83.  * @param size      Size of tdata + tbss section.
  84.  * @return      Pointer to tcb_t structure.
  85.  */
  86. tcb_t *tls_alloc_variant_1(void **data, size_t size)
  87. {
  88.     tcb_t *result;
  89.  
  90.     result = malloc(sizeof(tcb_t) + size);
  91.     *data = ((void *)result) + sizeof(tcb_t);
  92.     return result;
  93. }
  94.  
  95. /** Free TLS variant I data structures.
  96.  *
  97.  * @param tcb       Pointer to TCB structure.
  98.  * @param size      This argument is ignored.
  99.  */
  100. void tls_free_variant_1(tcb_t *tcb, size_t size)
  101. {
  102.     free(tcb);
  103. }
  104. #endif
  105.  
  106. #ifdef CONFIG_TLS_VARIANT_2
  107. /** Allocate TLS variant II data structures.
  108.  *
  109.  * @param data      Pointer to pointer to thread local data. This is
  110.  *          actually an output argument.
  111.  * @param size      Size of thread local data.
  112.  * @return      Pointer to TCB structure.
  113.  */
  114. tcb_t * tls_alloc_variant_2(void **data, size_t size)
  115. {
  116.     tcb_t *tcb;
  117.    
  118.     size = ALIGN_UP(size, &_tls_alignment);
  119.     *data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size);
  120.  
  121.     tcb = (tcb_t *) (*data + size);
  122.     tcb->self = tcb;
  123.  
  124.     return tcb;
  125. }
  126.  
  127. /** Free TLS variant II data structures.
  128.  *
  129.  * @param tcb       Pointer to TCB structure.
  130.  * @param size      Size of thread local data.
  131.  */
  132. void tls_free_variant_2(tcb_t *tcb, size_t size)
  133. {
  134.     size = ALIGN_UP(size, &_tls_alignment);
  135.     void *start = ((void *) tcb) - size;
  136.     free(start);
  137. }
  138. #endif
  139.  
  140. /** @}
  141.  */
  142.