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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 5.2 KB
RevLine 
[c05290e]1/*
[df4ed85]2 * Copyright (c) 2006 Jakub Jermar
[c05290e]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.
[b2951e2]27 */
28
[afbe96a]29/** @addtogroup libc
[b2951e2]30 * @{
31 */
32/** @file
[47b7006]33 */
[c05290e]34
35#include <thread.h>
36#include <libc.h>
[e5a1f82f]37#include <stdlib.h>
[afbe96a]38#include <libarch/faddr.h>
[c0699467]39#include <abi/proc/uarg.h>
[bc1f1c2]40#include <fibril.h>
[0aae87a6]41#include <stack.h>
[19f857a]42#include <str.h>
[80649a91]43#include <async.h>
[2902e1bb]44#include <errno.h>
45#include <as.h>
[47b7006]46#include "private/thread.h"
[29a9f62]47
[d54b303]48#ifdef FUTEX_UPGRADABLE
49#include <rcu.h>
50#endif
51
[9a3b469]52
[81e55099]53/** Main thread function.
54 *
55 * This function is called from __thread_entry() and is used
56 * to call the thread's implementing function and perform cleanup
[47b7006]57 * and exit when thread returns back.
[81e55099]58 *
59 * @param uarg Pointer to userspace argument structure.
[47b7006]60 *
[81e55099]61 */
[29a9f62]62void __thread_main(uspace_arg_t *uarg)
[e5a1f82f]63{
[47b7006]64 fibril_t *fibril = fibril_setup();
65 if (fibril == NULL)
66 thread_exit(0);
[a35b458]67
[47b7006]68 __tcb_set(fibril->tcb);
[a35b458]69
[d54b303]70#ifdef FUTEX_UPGRADABLE
71 rcu_register_fibril();
72 futex_upgrade_all_and_wait();
73#endif
[a35b458]74
[e5a1f82f]75 uarg->uspace_thread_function(uarg->uspace_thread_arg);
[2902e1bb]76 /*
77 * XXX: we cannot free the userspace stack while running on it
78 *
79 * free(uarg->uspace_stack);
80 * free(uarg);
81 */
[a35b458]82
[53ca318]83 /* If there is a manager, destroy it */
[80649a91]84 async_destroy_manager();
[d54b303]85
86#ifdef FUTEX_UPGRADABLE
87 rcu_deregister_fibril();
88#endif
[a35b458]89
[4d11204]90 fibril_teardown(fibril, false);
[a35b458]91
[e5a1f82f]92 thread_exit(0);
93}
[c05290e]94
[81e55099]95/** Create userspace thread.
96 *
97 * This function creates new userspace thread and allocates userspace
98 * stack and userspace argument structure for it.
99 *
100 * @param function Function implementing the thread.
101 * @param arg Argument to be passed to thread.
102 * @param name Symbolic name of the thread.
[201abde]103 * @param tid Thread ID of the newly created thread.
[81e55099]104 *
[201abde]105 * @return Zero on success or a code from @ref errno.h on failure.
[81e55099]106 */
[b7fd2a0]107errno_t thread_create(void (* function)(void *), void *arg, const char *name,
[f6d2c81]108 thread_id_t *tid)
[c05290e]109{
[2902e1bb]110 uspace_arg_t *uarg =
111 (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
112 if (!uarg)
113 return ENOMEM;
[a35b458]114
[0aae87a6]115 size_t stack_size = stack_size_get();
[2902e1bb]116 void *stack = as_area_create(AS_AREA_ANY, stack_size,
[3b8a990]117 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE | AS_AREA_GUARD |
[6aeca0d]118 AS_AREA_LATE_RESERVE, AS_AREA_UNPAGED);
[2902e1bb]119 if (stack == AS_MAP_FAILED) {
120 free(uarg);
121 return ENOMEM;
[e5a1f82f]122 }
[a35b458]123
[af5dfa5b]124 /* Make heap thread safe. */
125 malloc_enable_multithreaded();
[a35b458]126
[e5a1f82f]127 uarg->uspace_entry = (void *) FADDR(__thread_entry);
[2902e1bb]128 uarg->uspace_stack = stack;
129 uarg->uspace_stack_size = stack_size;
[81e55099]130 uarg->uspace_thread_function = function;
[e5a1f82f]131 uarg->uspace_thread_arg = arg;
132 uarg->uspace_uarg = uarg;
[a35b458]133
[b7fd2a0]134 errno_t rc = (errno_t) __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg,
[2902e1bb]135 (sysarg_t) name, (sysarg_t) str_size(name), (sysarg_t) tid);
[a35b458]136
[2902e1bb]137 if (rc != EOK) {
[f6d2c81]138 /*
139 * Failed to create a new thread.
[2902e1bb]140 * Free up the allocated data.
[f6d2c81]141 */
[2902e1bb]142 as_area_destroy(stack);
[f6d2c81]143 free(uarg);
144 }
[a35b458]145
[f6d2c81]146 return rc;
[c05290e]147}
148
[81e55099]149/** Terminate current thread.
150 *
[096ba7a]151 * @param status Exit status. Currently not used.
[47b7006]152 *
[81e55099]153 */
[c05290e]154void thread_exit(int status)
155{
156 __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
[a35b458]157
[47b7006]158 /* Unreachable */
159 while (1);
[c05290e]160}
[01ff41c]161
[dd655970]162/** Detach thread.
163 *
164 * Currently not implemented.
165 *
166 * @param thread TID.
167 */
[201abde]168void thread_detach(thread_id_t thread)
[dd655970]169{
170}
171
172/** Join thread.
173 *
174 * Currently not implemented.
175 *
176 * @param thread TID.
177 *
178 * @return Thread exit status.
179 */
[b7fd2a0]180errno_t thread_join(thread_id_t thread)
[dd655970]181{
[a2c58f6]182 return 0;
[dd655970]183}
184
185/** Get current thread ID.
186 *
187 * @return Current thread ID.
188 */
[201abde]189thread_id_t thread_get_id(void)
[dd655970]190{
[201abde]191 thread_id_t thread_id;
192
193 (void) __SYSCALL1(SYS_THREAD_GET_ID, (sysarg_t) &thread_id);
194
195 return thread_id;
[dd655970]196}
197
[582a0b8]198/** Wait unconditionally for specified number of microseconds
199 *
200 */
201int thread_usleep(useconds_t usec)
202{
203 (void) __SYSCALL1(SYS_THREAD_USLEEP, usec);
204 return 0;
205}
206
207/** Wait unconditionally for specified number of seconds
208 *
209 */
210unsigned int thread_sleep(unsigned int sec)
211{
212 /*
213 * Sleep in 1000 second steps to support
214 * full argument range
215 */
[a35b458]216
[582a0b8]217 while (sec > 0) {
218 unsigned int period = (sec > 1000) ? 1000 : sec;
[a35b458]219
[582a0b8]220 thread_usleep(period * 1000000);
221 sec -= period;
222 }
[a35b458]223
[582a0b8]224 return 0;
225}
226
[afbe96a]227/** @}
[b2951e2]228 */
Note: See TracBrowser for help on using the repository browser.