Changeset c4c5de5 in mainline


Ignore:
Timestamp:
2006-03-24T14:29:19Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
8fe1cdb
Parents:
520492a
Message:

Completed support for TLS in GCC (modifier thread) for ia32,amd64,ia64 and mips.

Files:
4 added
19 edited

Legend:

Unmodified
Added
Removed
  • init/init.c

    r520492a rc4c5de5  
    4040atomic_t ftx;
    4141
     42int __thread tls_prom;
     43
    4244extern void utest(void *arg);
    4345void utest(void *arg)
     
    256258static int ptest(void *arg)
    257259{
    258         printf("Pseudo thread stage1.\n");
     260        tls_prom = -1;
     261        printf("Pseudo thread stage%d.\n", -tls_prom);
     262        tls_prom = -2;
    259263        psthread_schedule_next();
    260         printf("Pseudo thread stage2.\n");
     264        printf("Pseudo thread stage%d.\n", -tls_prom);
     265        tls_prom = -3;
    261266        psthread_schedule_next();
    262         printf("Pseudo thread stage3.\n");
     267        printf("Pseudo thread stage%d\n", -tls_prom);
    263268        psthread_schedule_next();
    264269        printf("Pseudo thread stage4.\n");
     
    291296        if (futex_down(&ftx) < 0)
    292297                printf("Futex failed.\n");
    293 
     298/*
    294299        if ((tid = thread_create(utest, NULL, "utest")) != -1) {
    295300                printf("Created thread tid=%d\n", tid);
     
    299304                printf("Created thread tid=%d\n", tid);
    300305        }
    301 
     306*/
    302307        int i;
    303308       
     
    308313                printf("Futex failed.\n");
    309314
     315
     316        printf("Creating pathread\n");
     317        tls_prom = 1;
    310318        ptid = psthread_create(ptest, NULL);
    311         printf("Main thread stage1.\n");
     319        printf("Main thread stage%d\n",tls_prom);
     320        tls_prom = 2;
    312321        psthread_schedule_next();;
    313         printf("Main thread stage2.\n");
     322        printf("Main thread stage%d\n", tls_prom);
     323        tls_prom = 3;
    314324        psthread_schedule_next();;
    315         printf("Main thread stage3.\n");
     325        printf("Main thread stage%d\n", tls_prom);
    316326
    317327        psthread_join(ptid);
  • libc/arch/amd64/Makefile.inc

    r520492a rc4c5de5  
    3434
    3535ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \
    36                 arch/$(ARCH)/src/psthread.S
     36                arch/$(ARCH)/src/psthread.S \
     37                arch/$(ARCH)/src/thread.c
    3738
    3839LFLAGS += -N
  • libc/arch/amd64/_link.ld.in

    r520492a rc4c5de5  
    2121                *(.data);
    2222        } :data
     23        .tdata : {
     24                _tdata_start = .;
     25                *(.tdata);
     26                _tdata_end = .;
     27        } :data
     28        .tbss : {
     29                _tbss_start = .;
     30                *(.tbss);
     31                _tbss_end = .;
     32        } :data
     33       
    2334        .bss : {
    2435                *(COMMON);
  • libc/arch/amd64/include/thread.h

    r520492a rc4c5de5  
    3232#include <libc.h>
    3333
    34 static inline void __tls_set(void *tls)
     34typedef struct {
     35        void *self;
     36        void *pst_data;
     37} tcb_t;
     38
     39static inline void __tcb_set(tcb_t *tcb)
    3540{
    36         __SYSCALL1(SYS_TLS_SET, (sysarg_t) tls);
     41        __SYSCALL1(SYS_TLS_SET, (sysarg_t) tcb);
    3742}
    3843
    39 static inline void * __tls_get(void)
     44static inline tcb_t * __tcb_get(void)
    4045{
    4146        void * retval;
  • libc/arch/ia32/Makefile.inc

    r520492a rc4c5de5  
    3434
    3535ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
    36                 arch/$(ARCH)/src/psthread.S
     36                arch/$(ARCH)/src/psthread.S \
     37                arch/$(ARCH)/src/thread.c
    3738
    3839LFLAGS += -N
  • libc/arch/ia32/_link.ld.in

    r520492a rc4c5de5  
    2121                *(.data);
    2222        } :data
     23        .tdata : {
     24                _tdata_start = .;
     25                *(.tdata);
     26                _tdata_end = .;
     27        } :data
     28        .tbss : {
     29                _tbss_start = .;
     30                *(.tbss);
     31                _tbss_end = .;
     32        } :data
    2333        .bss : {
    2434                *(COMMON);
  • libc/arch/ia32/include/thread.h

    r520492a rc4c5de5  
    3232#include <libc.h>
    3333
    34 static inline void __tls_set(void *tls)
     34typedef struct {
     35        void *self;
     36        void *pst_data;
     37} tcb_t;
     38
     39static inline void __tcb_set(tcb_t *tcb)
    3540{
    36         __SYSCALL1(SYS_TLS_SET, (sysarg_t) tls);
     41        __SYSCALL1(SYS_TLS_SET, (sysarg_t) tcb);
    3742}
    3843
    39 static inline void * __tls_get(void)
     44static inline tcb_t * __tcb_get(void)
    4045{
    4146        void * retval;
  • libc/arch/ia64/Makefile.inc

    r520492a rc4c5de5  
    3737
    3838ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \
    39                 arch/$(ARCH)/src/psthread.S
     39                arch/$(ARCH)/src/psthread.S \
     40                arch/$(ARCH)/src/thread.c
  • libc/arch/ia64/_link.ld.in

    r520492a rc4c5de5  
    2727                *(.sdata);
    2828        } :data
     29        .tdata : {
     30                _tdata_start = .;
     31                *(.tdata);
     32                _tdata_end = .;
     33        } :data
     34        .tbss : {
     35                _tbss_start = .;
     36                *(.tbss);
     37                _tbss_end = .;
     38        } :data
    2939        .bss : {
    3040                *(.sbss);
  • libc/arch/ia64/include/thread.h

    r520492a rc4c5de5  
    3030#define __LIBC__ia64THREAD_H__
    3131
    32 static inline void __tls_set(void *tls)
     32/* This structure must be exactly 16 bytes long */
     33typedef struct {
     34        void *dtv; /* unused in static linking*/
     35        void *pst_data;
     36} tcb_t;
     37
     38static inline void __tcb_set(tcb_t *tcb)
    3339{
    34         __asm__ volatile ("mov r13 = %0\n" : : "r" (tls) : "r13");
     40        __asm__ volatile ("mov r13 = %0\n" : : "r" (tcb) : "r13");
    3541}
    3642
    37 static inline void *__tls_get(void)
     43static inline tcb_t *__tcb_get(void)
    3844{
    3945        void *retval;
  • libc/arch/mips32/Makefile.inc

    r520492a rc4c5de5  
    3535
    3636ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \
    37         arch/$(ARCH)/src/psthread.S
     37        arch/$(ARCH)/src/psthread.S \
     38        arch/$(ARCH)/src/thread.c
    3839
    3940
  • libc/arch/mips32/_link.ld.in

    r520492a rc4c5de5  
    2222                *(.data.rel*);
    2323        } :data
     24
    2425        .got : {
    2526                _gp = .;
    2627                *(.got);
    2728        } :data
     29
     30        .tdata : {
     31                _tdata_start = .;
     32                *(.tdata);
     33                _tdata_end = .;
     34        } :data
     35        .tbss : {
     36                _tbss_start = .;
     37                *(.tbss);
     38                _tbss_end = .;
     39        } :data
     40
    2841        .sbss : {
    2942                *(.scommon);
  • libc/arch/mips32/include/psthread.h

    r520492a rc4c5de5  
    3232#include <types.h>
    3333
     34/* We define our own context_set, because we need to set
     35 * the TLS pointer to the tcb+0x7000
     36 *
     37 * See tls_set in thread.h
     38 */
     39#define context_set(c, _pc, stack, size, ptls)                  \
     40        (c)->pc = (sysarg_t) (_pc);                             \
     41        (c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA;     \
     42        (c)->tls = ((sysarg_t)(ptls)) + 0x7000 + sizeof(tcb_t);
     43
     44
    3445/* +16 is just for sure that the called function
    3546 * have space to store it's arguments
  • libc/arch/mips32/include/thread.h

    r520492a rc4c5de5  
    3232#define __LIBC__mips32THREAD_H__
    3333
    34 static inline void __tls_set(void *tls)
     34/* I did not find any specification (neither MIPS nor PowerPC), but
     35 * as I found it
     36 * - it uses Variant II
     37 * - TCB is at Address(First TLS Block)+0x7000.
     38 * - DTV is at Address(First TLS Block)+0x8000
     39 * - What would happen if the TLS data was larger then 0x7000?
     40 * - The linker never accesses DTV directly, has the second definition any
     41 *   sense?
     42 * We will make it this way:
     43 * - TCB is at TP-0x7000-sizeof(tcb)
     44 * - No assumption about DTV etc., but it will not have a fixed address
     45 */
     46#define MIPS_TP_OFFSET 0x7000
     47
     48typedef struct {
     49        void *pst_data;
     50} tcb_t;
     51
     52static inline void __tcb_set(tcb_t *tcb)
    3553{
    36         __asm__ volatile ("add $27, %0, $0" : : "r"(tls)); /* Move tls to K1 */
     54        void *tp = tcb;
     55        tp += MIPS_TP_OFFSET + sizeof(tcb_t);
     56
     57        __asm__ volatile ("add $27, %0, $0" : : "r"(tp)); /* Move tls to K1 */
    3758}
    3859
    39 static inline void * __tls_get(void)
     60static inline tcb_t * __tcb_get(void)
    4061{
    4162        void * retval;
    4263
    4364        __asm__ volatile("add %0, $27, $0" : "=r"(retval));
    44         return retval;
     65
     66        return (tcb_t *)(retval - MIPS_TP_OFFSET - sizeof(tcb_t));
    4567}
    4668
  • libc/generic/libc.c

    r520492a rc4c5de5  
    3737}
    3838
     39#include <stdio.h>
    3940void __main(void) {
    40         __tls_set(__make_tls());
     41        tcb_t *tcb;
     42       
     43        tcb = __make_tls();
     44        __tcb_set(tcb);
     45        psthread_setup(tcb);
    4146}
    4247
    4348void __exit(void) {
    44         free(__tls_get());
    45        
     49        tcb_t *tcb;
     50
     51        tcb = __tcb_get();
     52        psthread_teardown(tcb->pst_data);
     53        __free_tls(tcb);
    4654        _exit(0);
    4755}
  • libc/generic/psthread.c

    r520492a rc4c5de5  
    4040static void psthread_main(void);
    4141
     42/** Setup PSthread information into TCB structure */
     43psthread_data_t * psthread_setup(tcb_t *tcb)
     44{
     45        psthread_data_t *pt;
     46
     47        pt = malloc(sizeof(*pt));
     48        if (!pt) {
     49                return NULL;
     50        }
     51
     52        tcb->pst_data = pt;
     53        pt->tcb = tcb;
     54
     55        return pt;
     56}
     57
     58void psthread_teardown(psthread_data_t *pt)
     59{
     60        free(pt);
     61}
     62
    4263/** Function to preempt to other pseudo thread without adding
    4364 * currently running pseudo thread to ready_list.
     
    6081void psthread_main(void)
    6182{
    62         psthread_data_t *pt = __tls_get();
     83        psthread_data_t *pt = __tcb_get()->pst_data;
     84
    6385        pt->retval = pt->func(pt->arg);
    6486
     
    81103                return 0;
    82104
    83         pt = __tls_get();
     105        pt = __tcb_get()->pst_data;
    84106        if (!context_save(&pt->ctx))
    85107                return 1;
     
    104126
    105127        /* Handle psthrid = Kernel address -> it is wait for call */
    106 
    107128        pt = (psthread_data_t *) psthrid;
    108129
    109130        if (!pt->finished) {
    110                 mypt = __tls_get();
     131                mypt = __tcb_get()->pst_data;
    111132                if (context_save(&((psthread_data_t *) mypt)->ctx)) {
    112133                        pt->waiter = (psthread_data_t *) mypt;
     
    117138
    118139        free(pt->stack);
    119         __free_tls((psthread_data_t *) pt);
     140        __free_tls(pt->tcb);
     141        psthread_teardown((void *)pt);
    120142
    121143        return retval;
     
    133155{
    134156        psthread_data_t *pt;
     157        tcb_t *tcb;
    135158
    136         pt = __make_tls();
     159        tcb = __make_tls();
     160        if (!tcb)
     161                return 0;
     162
     163        pt = psthread_setup(tcb);
     164        if (!pt) {
     165                __free_tls(tcb);
     166                return 0;
     167        }
    137168        pt->stack = (char *) malloc(getpagesize());
    138169
    139170        if (!pt->stack) {
     171                __free_tls(tcb);
     172                psthread_teardown(pt);
    140173                return 0;
    141174        }
     
    147180
    148181        context_save(&pt->ctx);
    149         context_set(&pt->ctx, FADDR(psthread_main), pt->stack, getpagesize(), pt);
     182        context_set(&pt->ctx, FADDR(psthread_main), pt->stack, getpagesize(),
     183                    tcb);
    150184
    151185        list_append(&pt->link, &ready_list);
  • libc/generic/thread.c

    r520492a rc4c5de5  
    3333#include <kernel/proc/uarg.h>
    3434#include <psthread.h>
     35#include <string.h>
    3536
    3637#include <stdio.h>
    37 void * __make_tls(void)
     38
     39extern char _tdata_start;
     40extern char _tdata_end;
     41extern char _tbss_start;
     42extern char _tbss_end;
     43
     44/** Create Thread Local storage area, return pointer to TCB(ThreadControlBlock)
     45 *
     46 * !! The code requires, that sections .tdata and .tbss are adjacent.
     47 *    It may be changed in the future.
     48 */
     49tcb_t * __make_tls(void)
    3850{
    39         psthread_data_t *pt;
     51        void *data;
     52        tcb_t *tcb;
     53        size_t tls_size = &_tbss_end - &_tdata_start;
     54       
     55        tcb = __alloc_tls(&data, tls_size);
     56       
     57        memcpy(data, &_tdata_start, &_tdata_end - &_tdata_start);
     58        memset(data + (&_tbss_start-&_tdata_start), &_tbss_end-&_tbss_start, 0);
    4059
    41         pt = malloc(sizeof(psthread_data_t));
    42         pt->self = pt;
    43 
    44         return pt;
     60        return tcb;
    4561}
    4662
    47 void __free_tls(void *tls)
     63void __free_tls(tcb_t *tcb)
    4864{
    49         free(tls);
     65        size_t tls_size = &_tbss_end - &_tdata_start;
     66        __free_tls_arch(tcb, tls_size);
    5067}
    5168
     
    6178void __thread_main(uspace_arg_t *uarg)
    6279{
     80        tcb_t *tcb;
    6381        /* This should initialize the area according to TLS specicification */
    64         __tls_set(__make_tls());
     82        tcb = __make_tls();
     83        __tcb_set(tcb);
     84        psthread_setup(tcb);
    6585
    6686        uarg->uspace_thread_function(uarg->uspace_thread_arg);
     
    6888        free(uarg);
    6989
    70         __free_tls(__tls_get());
     90        psthread_teardown(tcb->pst_data);
     91        __free_tls(tcb);
    7192
    7293        thread_exit(0);
  • libc/include/psthread.h

    r520492a rc4c5de5  
    3232#include <libarch/psthread.h>
    3333#include <libadt/list.h>
     34#include <libarch/thread.h>
    3435
    3536#ifndef context_set
     
    4344
    4445struct psthread_data {
    45         struct psthread_data *self; /* ia32, amd64 needs to get self address */
    46 
    4746        link_t link;
    4847        context_t ctx;
     
    5049        void *arg;
    5150        int (*func)(void *);
     51        tcb_t *tcb;
    5252
    5353        struct psthread_data *waiter;
     
    6464int psthread_schedule_next(void);
    6565int psthread_join(pstid_t psthrid);
     66psthread_data_t * psthread_setup(tcb_t *tcb);
     67void psthread_teardown(psthread_data_t *pt);
     68
    6669
    6770#endif
  • libc/include/thread.h

    r520492a rc4c5de5  
    3232#include <kernel/proc/uarg.h>
    3333#include <libarch/thread.h>
     34#include <types.h>
    3435
    3536extern void __thread_entry(void);
     
    3839extern int thread_create(void (* function)(void *arg), void *arg, char *name);
    3940extern void thread_exit(int status);
    40 void * __make_tls(void);
    41 void __free_tls(void *);
     41tcb_t * __make_tls(void);
     42tcb_t * __alloc_tls(void **data, size_t size);
     43void __free_tls(tcb_t *);
     44void __free_tls_arch(tcb_t *, size_t size);
    4245
    4346#endif
Note: See TracChangeset for help on using the changeset viewer.