source: mainline/uspace/lib/c/generic/private/fibril.h@ d3109ff

Last change on this file since d3109ff was 3fcea34, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 12 months ago

Simplify the SYS_THREAD_CREATE syscall interface

Removed the beefy uarg structure. Instead, the syscall gets two
parameters: %pc (program counter) and %sp (stack pointer). It starts
a thread with those values in corresponding registers, with no other
fuss whatsoever.

libc initializes threads by storing any other needed arguments on
the stack and retrieving them in thread_entry. Importantly, this
includes the address of the
thread_main function which is now
called indirectly to fix dynamic linking issues on some archs.

There's a bit of weirdness on SPARC and IA-64, because of their
stacked register handling. The current solution is that we require
some space *above* the stack pointer to be available for those
architectures. I think for SPARC, it can be made more normal.

For the remaining ones, we can (probably) just set the initial
%sp to the top edge of the stack. There's some lingering offsets
on some archs just because I didn't want to accidentally break
anything. The initial thread bringup should be functionally
unchanged from the previous state, and no binaries are currently
multithreaded except thread1 test, so there should be minimal
risk of breakage. Naturally, I tested all available emulator
builds, save for msim.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * Copyright (c) 2006 Ondrej Palkovsky
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#ifndef _LIBC_PRIVATE_FIBRIL_H_
30#define _LIBC_PRIVATE_FIBRIL_H_
31
32#include <adt/list.h>
33#include <context.h>
34#include <tls.h>
35#include <fibril.h>
36#include <ipc/common.h>
37
38#include "./futex.h"
39
40typedef struct {
41 fibril_t *fibril;
42} fibril_event_t;
43
44#define FIBRIL_EVENT_INIT ((fibril_event_t) {0})
45
46struct fibril {
47 // XXX: The first two fields must not move (for taskdump).
48 link_t all_link;
49 context_t ctx;
50
51 link_t link;
52 void *stack;
53 size_t stack_size;
54 void *arg;
55 errno_t (*func)(void *);
56 tcb_t *tcb;
57
58 fibril_t *clean_after_me;
59 errno_t retval;
60
61 fibril_t *thread_ctx;
62
63 bool is_running : 1;
64 bool is_writer : 1;
65 /* In some places, we use fibril structs that can't be freed. */
66 bool is_freeable : 1;
67
68 /* Debugging stuff. */
69 int rmutex_locks;
70 fibril_owner_info_t *waits_for;
71 fibril_event_t *sleep_event;
72};
73
74extern fibril_t *fibril_alloc(void);
75extern void fibril_setup(fibril_t *);
76extern void fibril_teardown(fibril_t *f);
77extern fibril_t *fibril_self(void);
78
79extern void __fibrils_init(void);
80extern void __fibrils_fini(void);
81
82extern void fibril_wait_for(fibril_event_t *);
83extern errno_t fibril_wait_timeout(fibril_event_t *, const struct timespec *);
84extern void fibril_notify(fibril_event_t *);
85
86extern errno_t fibril_ipc_wait(ipc_call_t *, const struct timespec *);
87extern void fibril_ipc_poke(void);
88
89/**
90 * "Restricted" fibril mutex.
91 *
92 * Similar to `fibril_mutex_t`, but has a set of restrictions placed on its
93 * use. Within a rmutex critical section, you
94 * - may not use any other synchronization primitive,
95 * save for another `fibril_rmutex_t`. This includes nonblocking
96 * operations like cvar signal and mutex unlock, unless otherwise
97 * specified.
98 * - may not read IPC messages
99 * - may not start a new thread/fibril
100 * (creating fibril without starting is fine)
101 *
102 * Additionally, locking with a timeout is not possible on this mutex,
103 * and there is no associated condition variable type.
104 * This is a design constraint, not a lack of implementation effort.
105 */
106typedef struct {
107 // TODO: At this point, this is just silly handwaving to hide current
108 // futex use behind a fibril based abstraction. Later, the imple-
109 // mentation will change, but the restrictions placed on this type
110 // will allow it to be simpler and faster than a regular mutex.
111 // There might also be optional debug checking of the assumptions.
112 //
113 // Note that a consequence of the restrictions is that if we are
114 // running on a single thread, no other fibril can ever get to run
115 // while a fibril has a rmutex locked. That means that for
116 // single-threaded programs, we can reduce all rmutex locks and
117 // unlocks to simple branches on a global bool variable.
118
119 futex_t futex;
120} fibril_rmutex_t;
121
122extern errno_t fibril_rmutex_initialize(fibril_rmutex_t *);
123extern void fibril_rmutex_destroy(fibril_rmutex_t *);
124extern void fibril_rmutex_lock(fibril_rmutex_t *);
125extern bool fibril_rmutex_trylock(fibril_rmutex_t *);
126extern void fibril_rmutex_unlock(fibril_rmutex_t *);
127
128#endif
Note: See TracBrowser for help on using the repository browser.