thread.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2006 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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         /* If there is a manager, destroy it */
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 

Generated on Sun Jun 18 17:54:21 2006 for HelenOS Userspace (ia32) by  doxygen 1.4.6