00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <thread.h>
00036 #include <libc.h>
00037 #include <stdlib.h>
00038 #include <arch/faddr.h>
00039 #include <kernel/proc/uarg.h>
00040 #include <psthread.h>
00041 #include <string.h>
00042 #include <async.h>
00043
00044 #include <stdio.h>
00045
00046
00047 #ifndef THREAD_INITIAL_STACK_PAGES_NO
00048 #define THREAD_INITIAL_STACK_PAGES_NO 1
00049 #endif
00050
00051 static LIST_INITIALIZE(thread_garbage);
00052
00053 extern char _tdata_start;
00054 extern char _tdata_end;
00055 extern char _tbss_start;
00056 extern char _tbss_end;
00057
00063 tcb_t * __make_tls(void)
00064 {
00065 void *data;
00066 tcb_t *tcb;
00067 size_t tls_size = &_tbss_end - &_tdata_start;
00068
00069 tcb = __alloc_tls(&data, tls_size);
00070
00071 memcpy(data, &_tdata_start, &_tdata_end - &_tdata_start);
00072 memset(data + (&_tbss_start-&_tdata_start), 0, &_tbss_end-&_tbss_start);
00073 return tcb;
00074 }
00075
00076 void __free_tls(tcb_t *tcb)
00077 {
00078 size_t tls_size = &_tbss_end - &_tdata_start;
00079 __free_tls_arch(tcb, tls_size);
00080 }
00081
00093 void __thread_main(uspace_arg_t *uarg)
00094 {
00095 psthread_data_t *pt;
00096
00097 pt = psthread_setup();
00098 __tcb_set(pt->tcb);
00099
00100 uarg->uspace_thread_function(uarg->uspace_thread_arg);
00101 free(uarg->uspace_stack);
00102 free(uarg);
00103
00104
00105 async_destroy_manager();
00106 psthread_teardown(pt);
00107
00108 thread_exit(0);
00109 }
00110
00122 int thread_create(void (* function)(void *), void *arg, char *name)
00123 {
00124 char *stack;
00125 uspace_arg_t *uarg;
00126
00127 stack = (char *) malloc(getpagesize()*THREAD_INITIAL_STACK_PAGES_NO);
00128 if (!stack)
00129 return -1;
00130
00131 uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
00132 if (!uarg) {
00133 free(stack);
00134 return -1;
00135 }
00136
00137 uarg->uspace_entry = (void *) FADDR(__thread_entry);
00138 uarg->uspace_stack = (void *) stack;
00139 uarg->uspace_thread_function = function;
00140 uarg->uspace_thread_arg = arg;
00141 uarg->uspace_uarg = uarg;
00142
00143 return __SYSCALL2(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name);
00144 }
00145
00150 void thread_exit(int status)
00151 {
00152 __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
00153 }
00154
00155
00156