Changeset c4c5de5 in mainline
- Timestamp:
- 2006-03-24T14:29:19Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 8fe1cdb
- Parents:
- 520492a
- Files:
-
- 4 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
init/init.c
r520492a rc4c5de5 40 40 atomic_t ftx; 41 41 42 int __thread tls_prom; 43 42 44 extern void utest(void *arg); 43 45 void utest(void *arg) … … 256 258 static int ptest(void *arg) 257 259 { 258 printf("Pseudo thread stage1.\n"); 260 tls_prom = -1; 261 printf("Pseudo thread stage%d.\n", -tls_prom); 262 tls_prom = -2; 259 263 psthread_schedule_next(); 260 printf("Pseudo thread stage2.\n"); 264 printf("Pseudo thread stage%d.\n", -tls_prom); 265 tls_prom = -3; 261 266 psthread_schedule_next(); 262 printf("Pseudo thread stage 3.\n");267 printf("Pseudo thread stage%d\n", -tls_prom); 263 268 psthread_schedule_next(); 264 269 printf("Pseudo thread stage4.\n"); … … 291 296 if (futex_down(&ftx) < 0) 292 297 printf("Futex failed.\n"); 293 298 /* 294 299 if ((tid = thread_create(utest, NULL, "utest")) != -1) { 295 300 printf("Created thread tid=%d\n", tid); … … 299 304 printf("Created thread tid=%d\n", tid); 300 305 } 301 306 */ 302 307 int i; 303 308 … … 308 313 printf("Futex failed.\n"); 309 314 315 316 printf("Creating pathread\n"); 317 tls_prom = 1; 310 318 ptid = psthread_create(ptest, NULL); 311 printf("Main thread stage1.\n"); 319 printf("Main thread stage%d\n",tls_prom); 320 tls_prom = 2; 312 321 psthread_schedule_next();; 313 printf("Main thread stage2.\n"); 322 printf("Main thread stage%d\n", tls_prom); 323 tls_prom = 3; 314 324 psthread_schedule_next();; 315 printf("Main thread stage 3.\n");325 printf("Main thread stage%d\n", tls_prom); 316 326 317 327 psthread_join(ptid); -
libc/arch/amd64/Makefile.inc
r520492a rc4c5de5 34 34 35 35 ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ 36 arch/$(ARCH)/src/psthread.S 36 arch/$(ARCH)/src/psthread.S \ 37 arch/$(ARCH)/src/thread.c 37 38 38 39 LFLAGS += -N -
libc/arch/amd64/_link.ld.in
r520492a rc4c5de5 21 21 *(.data); 22 22 } :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 23 34 .bss : { 24 35 *(COMMON); -
libc/arch/amd64/include/thread.h
r520492a rc4c5de5 32 32 #include <libc.h> 33 33 34 static inline void __tls_set(void *tls) 34 typedef struct { 35 void *self; 36 void *pst_data; 37 } tcb_t; 38 39 static inline void __tcb_set(tcb_t *tcb) 35 40 { 36 __SYSCALL1(SYS_TLS_SET, (sysarg_t) t ls);41 __SYSCALL1(SYS_TLS_SET, (sysarg_t) tcb); 37 42 } 38 43 39 static inline void * __tls_get(void)44 static inline tcb_t * __tcb_get(void) 40 45 { 41 46 void * retval; -
libc/arch/ia32/Makefile.inc
r520492a rc4c5de5 34 34 35 35 ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ 36 arch/$(ARCH)/src/psthread.S 36 arch/$(ARCH)/src/psthread.S \ 37 arch/$(ARCH)/src/thread.c 37 38 38 39 LFLAGS += -N -
libc/arch/ia32/_link.ld.in
r520492a rc4c5de5 21 21 *(.data); 22 22 } :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 23 33 .bss : { 24 34 *(COMMON); -
libc/arch/ia32/include/thread.h
r520492a rc4c5de5 32 32 #include <libc.h> 33 33 34 static inline void __tls_set(void *tls) 34 typedef struct { 35 void *self; 36 void *pst_data; 37 } tcb_t; 38 39 static inline void __tcb_set(tcb_t *tcb) 35 40 { 36 __SYSCALL1(SYS_TLS_SET, (sysarg_t) t ls);41 __SYSCALL1(SYS_TLS_SET, (sysarg_t) tcb); 37 42 } 38 43 39 static inline void * __tls_get(void)44 static inline tcb_t * __tcb_get(void) 40 45 { 41 46 void * retval; -
libc/arch/ia64/Makefile.inc
r520492a rc4c5de5 37 37 38 38 ARCH_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 27 27 *(.sdata); 28 28 } :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 29 39 .bss : { 30 40 *(.sbss); -
libc/arch/ia64/include/thread.h
r520492a rc4c5de5 30 30 #define __LIBC__ia64THREAD_H__ 31 31 32 static inline void __tls_set(void *tls) 32 /* This structure must be exactly 16 bytes long */ 33 typedef struct { 34 void *dtv; /* unused in static linking*/ 35 void *pst_data; 36 } tcb_t; 37 38 static inline void __tcb_set(tcb_t *tcb) 33 39 { 34 __asm__ volatile ("mov r13 = %0\n" : : "r" (t ls) : "r13");40 __asm__ volatile ("mov r13 = %0\n" : : "r" (tcb) : "r13"); 35 41 } 36 42 37 static inline void *__tls_get(void)43 static inline tcb_t *__tcb_get(void) 38 44 { 39 45 void *retval; -
libc/arch/mips32/Makefile.inc
r520492a rc4c5de5 35 35 36 36 ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ 37 arch/$(ARCH)/src/psthread.S 37 arch/$(ARCH)/src/psthread.S \ 38 arch/$(ARCH)/src/thread.c 38 39 39 40 -
libc/arch/mips32/_link.ld.in
r520492a rc4c5de5 22 22 *(.data.rel*); 23 23 } :data 24 24 25 .got : { 25 26 _gp = .; 26 27 *(.got); 27 28 } :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 28 41 .sbss : { 29 42 *(.scommon); -
libc/arch/mips32/include/psthread.h
r520492a rc4c5de5 32 32 #include <types.h> 33 33 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 34 45 /* +16 is just for sure that the called function 35 46 * have space to store it's arguments -
libc/arch/mips32/include/thread.h
r520492a rc4c5de5 32 32 #define __LIBC__mips32THREAD_H__ 33 33 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 48 typedef struct { 49 void *pst_data; 50 } tcb_t; 51 52 static inline void __tcb_set(tcb_t *tcb) 35 53 { 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 */ 37 58 } 38 59 39 static inline void * __tls_get(void)60 static inline tcb_t * __tcb_get(void) 40 61 { 41 62 void * retval; 42 63 43 64 __asm__ volatile("add %0, $27, $0" : "=r"(retval)); 44 return retval; 65 66 return (tcb_t *)(retval - MIPS_TP_OFFSET - sizeof(tcb_t)); 45 67 } 46 68 -
libc/generic/libc.c
r520492a rc4c5de5 37 37 } 38 38 39 #include <stdio.h> 39 40 void __main(void) { 40 __tls_set(__make_tls()); 41 tcb_t *tcb; 42 43 tcb = __make_tls(); 44 __tcb_set(tcb); 45 psthread_setup(tcb); 41 46 } 42 47 43 48 void __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); 46 54 _exit(0); 47 55 } -
libc/generic/psthread.c
r520492a rc4c5de5 40 40 static void psthread_main(void); 41 41 42 /** Setup PSthread information into TCB structure */ 43 psthread_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 58 void psthread_teardown(psthread_data_t *pt) 59 { 60 free(pt); 61 } 62 42 63 /** Function to preempt to other pseudo thread without adding 43 64 * currently running pseudo thread to ready_list. … … 60 81 void psthread_main(void) 61 82 { 62 psthread_data_t *pt = __tls_get(); 83 psthread_data_t *pt = __tcb_get()->pst_data; 84 63 85 pt->retval = pt->func(pt->arg); 64 86 … … 81 103 return 0; 82 104 83 pt = __t ls_get();105 pt = __tcb_get()->pst_data; 84 106 if (!context_save(&pt->ctx)) 85 107 return 1; … … 104 126 105 127 /* Handle psthrid = Kernel address -> it is wait for call */ 106 107 128 pt = (psthread_data_t *) psthrid; 108 129 109 130 if (!pt->finished) { 110 mypt = __t ls_get();131 mypt = __tcb_get()->pst_data; 111 132 if (context_save(&((psthread_data_t *) mypt)->ctx)) { 112 133 pt->waiter = (psthread_data_t *) mypt; … … 117 138 118 139 free(pt->stack); 119 __free_tls((psthread_data_t *) pt); 140 __free_tls(pt->tcb); 141 psthread_teardown((void *)pt); 120 142 121 143 return retval; … … 133 155 { 134 156 psthread_data_t *pt; 157 tcb_t *tcb; 135 158 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 } 137 168 pt->stack = (char *) malloc(getpagesize()); 138 169 139 170 if (!pt->stack) { 171 __free_tls(tcb); 172 psthread_teardown(pt); 140 173 return 0; 141 174 } … … 147 180 148 181 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); 150 184 151 185 list_append(&pt->link, &ready_list); -
libc/generic/thread.c
r520492a rc4c5de5 33 33 #include <kernel/proc/uarg.h> 34 34 #include <psthread.h> 35 #include <string.h> 35 36 36 37 #include <stdio.h> 37 void * __make_tls(void) 38 39 extern char _tdata_start; 40 extern char _tdata_end; 41 extern char _tbss_start; 42 extern 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 */ 49 tcb_t * __make_tls(void) 38 50 { 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); 40 59 41 pt = malloc(sizeof(psthread_data_t)); 42 pt->self = pt; 43 44 return pt; 60 return tcb; 45 61 } 46 62 47 void __free_tls( void *tls)63 void __free_tls(tcb_t *tcb) 48 64 { 49 free(tls); 65 size_t tls_size = &_tbss_end - &_tdata_start; 66 __free_tls_arch(tcb, tls_size); 50 67 } 51 68 … … 61 78 void __thread_main(uspace_arg_t *uarg) 62 79 { 80 tcb_t *tcb; 63 81 /* 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); 65 85 66 86 uarg->uspace_thread_function(uarg->uspace_thread_arg); … … 68 88 free(uarg); 69 89 70 __free_tls(__tls_get()); 90 psthread_teardown(tcb->pst_data); 91 __free_tls(tcb); 71 92 72 93 thread_exit(0); -
libc/include/psthread.h
r520492a rc4c5de5 32 32 #include <libarch/psthread.h> 33 33 #include <libadt/list.h> 34 #include <libarch/thread.h> 34 35 35 36 #ifndef context_set … … 43 44 44 45 struct psthread_data { 45 struct psthread_data *self; /* ia32, amd64 needs to get self address */46 47 46 link_t link; 48 47 context_t ctx; … … 50 49 void *arg; 51 50 int (*func)(void *); 51 tcb_t *tcb; 52 52 53 53 struct psthread_data *waiter; … … 64 64 int psthread_schedule_next(void); 65 65 int psthread_join(pstid_t psthrid); 66 psthread_data_t * psthread_setup(tcb_t *tcb); 67 void psthread_teardown(psthread_data_t *pt); 68 66 69 67 70 #endif -
libc/include/thread.h
r520492a rc4c5de5 32 32 #include <kernel/proc/uarg.h> 33 33 #include <libarch/thread.h> 34 #include <types.h> 34 35 35 36 extern void __thread_entry(void); … … 38 39 extern int thread_create(void (* function)(void *arg), void *arg, char *name); 39 40 extern void thread_exit(int status); 40 void * __make_tls(void); 41 void __free_tls(void *); 41 tcb_t * __make_tls(void); 42 tcb_t * __alloc_tls(void **data, size_t size); 43 void __free_tls(tcb_t *); 44 void __free_tls_arch(tcb_t *, size_t size); 42 45 43 46 #endif
Note:
See TracChangeset
for help on using the changeset viewer.