2 * Copyright (C) 2006 Jakub Jermar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <libarch/faddr.h>
39 #include <kernel/proc/uarg.h>
47 #ifndef THREAD_INITIAL_STACK_PAGES_NO
48 #define THREAD_INITIAL_STACK_PAGES_NO 1
51 static LIST_INITIALIZE(thread_garbage
);
53 extern char _tdata_start
;
54 extern char _tdata_end
;
55 extern char _tbss_start
;
56 extern char _tbss_end
;
58 /** Create TLS (Thread Local Storage) data structures.
60 * The code requires, that sections .tdata and .tbss are adjacent. It may be
61 * changed in the future.
63 * @return Pointer to TCB.
65 tcb_t
*__make_tls(void)
69 size_t tls_size
= &_tbss_end
- &_tdata_start
;
71 tcb
= __alloc_tls(&data
, tls_size
);
74 * Copy thread local data from the initialization image.
76 memcpy(data
, &_tdata_start
, &_tdata_end
- &_tdata_start
);
78 * Zero out the thread local uninitialized data.
80 memset(data
+ (&_tbss_start
- &_tdata_start
), 0, &_tbss_end
-
86 void __free_tls(tcb_t
*tcb
)
88 size_t tls_size
= &_tbss_end
- &_tdata_start
;
89 __free_tls_arch(tcb
, tls_size
);
92 /** Main thread function.
94 * This function is called from __thread_entry() and is used
95 * to call the thread's implementing function and perform cleanup
96 * and exit when thread returns back. Do not call this function
99 * @param uarg Pointer to userspace argument structure.
101 void __thread_main(uspace_arg_t
*uarg
)
105 pt
= psthread_setup();
108 uarg
->uspace_thread_function(uarg
->uspace_thread_arg
);
109 free(uarg
->uspace_stack
);
112 /* If there is a manager, destroy it */
113 async_destroy_manager();
114 psthread_teardown(pt
);
119 /** Create userspace thread.
121 * This function creates new userspace thread and allocates userspace
122 * stack and userspace argument structure for it.
124 * @param function Function implementing the thread.
125 * @param arg Argument to be passed to thread.
126 * @param name Symbolic name of the thread.
128 * @return TID of the new thread on success or -1 on failure.
130 int thread_create(void (* function
)(void *), void *arg
, char *name
)
135 stack
= (char *) malloc(getpagesize() * THREAD_INITIAL_STACK_PAGES_NO
);
139 uarg
= (uspace_arg_t
*) malloc(sizeof(uspace_arg_t
));
145 uarg
->uspace_entry
= (void *) FADDR(__thread_entry
);
146 uarg
->uspace_stack
= (void *) stack
;
147 uarg
->uspace_thread_function
= function
;
148 uarg
->uspace_thread_arg
= arg
;
149 uarg
->uspace_uarg
= uarg
;
151 return __SYSCALL2(SYS_THREAD_CREATE
, (sysarg_t
) uarg
, (sysarg_t
) name
);
154 /** Terminate current thread.
156 * @param status Exit status. Currently not used.
158 void thread_exit(int status
)
160 __SYSCALL1(SYS_THREAD_EXIT
, (sysarg_t
) status
);