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 <libarch/faddr.h>
00039 #include <kernel/proc/uarg.h>
00040 #include <fibril.h>
00041 #include <str.h>
00042 #include <async.h>
00043 #include "private/thread.h"
00044 
00045 #ifndef THREAD_INITIAL_STACK_PAGES_NO
00046 #define THREAD_INITIAL_STACK_PAGES_NO   2 
00047 #endif
00048 
00058 void __thread_main(uspace_arg_t *uarg)
00059 {
00060         fibril_t *fibril = fibril_setup();
00061         if (fibril == NULL)
00062                 thread_exit(0);
00063         
00064         __tcb_set(fibril->tcb);
00065         
00066         uarg->uspace_thread_function(uarg->uspace_thread_arg);
00067         /* XXX: we cannot free the userspace stack while running on it
00068                 free(uarg->uspace_stack);
00069                 free(uarg);
00070         */
00071         
00072         /* If there is a manager, destroy it */
00073         async_destroy_manager();
00074         fibril_teardown(fibril);
00075         
00076         thread_exit(0);
00077 }
00078 
00091 int thread_create(void (* function)(void *), void *arg, const char *name,
00092     thread_id_t *tid)
00093 {
00094         char *stack;
00095         uspace_arg_t *uarg;
00096         int rc;
00097 
00098         stack = (char *) malloc(getpagesize() * THREAD_INITIAL_STACK_PAGES_NO);
00099         if (!stack)
00100                 return -1;
00101                 
00102         uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
00103         if (!uarg) {
00104                 free(stack);
00105                 return -1;
00106         }
00107         
00108         uarg->uspace_entry = (void *) FADDR(__thread_entry);
00109         uarg->uspace_stack = (void *) stack;
00110         uarg->uspace_thread_function = function;
00111         uarg->uspace_thread_arg = arg;
00112         uarg->uspace_uarg = uarg;
00113         
00114         rc = __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name,
00115             (sysarg_t) str_size(name), (sysarg_t) tid);
00116         
00117         if (rc) {
00118                 /*
00119                  * Failed to create a new thread.
00120                  * Free up the allocated structures.
00121                  */
00122                 free(uarg);
00123                 free(stack);
00124         }
00125 
00126         return rc;
00127 }
00128 
00134 void thread_exit(int status)
00135 {
00136         __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
00137         
00138         /* Unreachable */
00139         while (1);
00140 }
00141 
00148 void thread_detach(thread_id_t thread)
00149 {
00150 }
00151 
00160 int thread_join(thread_id_t thread)
00161 {
00162         return 0;
00163 }
00164 
00169 thread_id_t thread_get_id(void)
00170 {
00171         thread_id_t thread_id;
00172 
00173         (void) __SYSCALL1(SYS_THREAD_GET_ID, (sysarg_t) &thread_id);
00174 
00175         return thread_id;
00176 }
00177 

Generated on Thu Jun 2 07:45:46 2011 for HelenOS/USB by  doxygen 1.4.7