source: mainline/uspace/lib/c/generic/thread.c@ be2a38ad

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since be2a38ad was 2902e1bb, checked in by Martin Decky <martin@…>, 13 years ago

add support for variable uspace stack size
create individual address space areas for stacks of additional threads (instead of allocating the stack from heap)
avoid memory leaks in program_create()

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * Copyright (c) 2006 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
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.
16 *
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.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/** @file
33 */
34
35#include <thread.h>
36#include <libc.h>
37#include <stdlib.h>
38#include <libarch/faddr.h>
39#include <abi/proc/uarg.h>
40#include <fibril.h>
41#include <str.h>
42#include <async.h>
43#include <errno.h>
44#include <as.h>
45#include "private/thread.h"
46
47#ifndef THREAD_INITIAL_STACK_PAGES
48 #define THREAD_INITIAL_STACK_PAGES 2
49#endif
50
51/** Main thread function.
52 *
53 * This function is called from __thread_entry() and is used
54 * to call the thread's implementing function and perform cleanup
55 * and exit when thread returns back.
56 *
57 * @param uarg Pointer to userspace argument structure.
58 *
59 */
60void __thread_main(uspace_arg_t *uarg)
61{
62 fibril_t *fibril = fibril_setup();
63 if (fibril == NULL)
64 thread_exit(0);
65
66 __tcb_set(fibril->tcb);
67
68 uarg->uspace_thread_function(uarg->uspace_thread_arg);
69 /*
70 * XXX: we cannot free the userspace stack while running on it
71 *
72 * free(uarg->uspace_stack);
73 * free(uarg);
74 */
75
76 /* If there is a manager, destroy it */
77 async_destroy_manager();
78 fibril_teardown(fibril);
79
80 thread_exit(0);
81}
82
83/** Create userspace thread.
84 *
85 * This function creates new userspace thread and allocates userspace
86 * stack and userspace argument structure for it.
87 *
88 * @param function Function implementing the thread.
89 * @param arg Argument to be passed to thread.
90 * @param name Symbolic name of the thread.
91 * @param tid Thread ID of the newly created thread.
92 *
93 * @return Zero on success or a code from @ref errno.h on failure.
94 */
95int thread_create(void (* function)(void *), void *arg, const char *name,
96 thread_id_t *tid)
97{
98 uspace_arg_t *uarg =
99 (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
100 if (!uarg)
101 return ENOMEM;
102
103 size_t stack_size = getpagesize() * THREAD_INITIAL_STACK_PAGES;
104 void *stack = as_area_create(AS_AREA_ANY, stack_size,
105 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
106 if (stack == AS_MAP_FAILED) {
107 free(uarg);
108 return ENOMEM;
109 }
110
111 uarg->uspace_entry = (void *) FADDR(__thread_entry);
112 uarg->uspace_stack = stack;
113 uarg->uspace_stack_size = stack_size;
114 uarg->uspace_thread_function = function;
115 uarg->uspace_thread_arg = arg;
116 uarg->uspace_uarg = uarg;
117
118 int rc = __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg,
119 (sysarg_t) name, (sysarg_t) str_size(name), (sysarg_t) tid);
120
121 if (rc != EOK) {
122 /*
123 * Failed to create a new thread.
124 * Free up the allocated data.
125 */
126 as_area_destroy(stack);
127 free(uarg);
128 }
129
130 return rc;
131}
132
133/** Terminate current thread.
134 *
135 * @param status Exit status. Currently not used.
136 *
137 */
138void thread_exit(int status)
139{
140 __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
141
142 /* Unreachable */
143 while (1);
144}
145
146/** Detach thread.
147 *
148 * Currently not implemented.
149 *
150 * @param thread TID.
151 */
152void thread_detach(thread_id_t thread)
153{
154}
155
156/** Join thread.
157 *
158 * Currently not implemented.
159 *
160 * @param thread TID.
161 *
162 * @return Thread exit status.
163 */
164int thread_join(thread_id_t thread)
165{
166 return 0;
167}
168
169/** Get current thread ID.
170 *
171 * @return Current thread ID.
172 */
173thread_id_t thread_get_id(void)
174{
175 thread_id_t thread_id;
176
177 (void) __SYSCALL1(SYS_THREAD_GET_ID, (sysarg_t) &thread_id);
178
179 return thread_id;
180}
181
182/** @}
183 */
Note: See TracBrowser for help on using the repository browser.