2 * (c) 2004-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3 * Alexander Warg <warg@os.inf.tu-dresden.de>
4 * economic rights: Technische Universität Dresden (Germany)
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU Lesser General Public License 2.1.
7 * Please see the COPYING-LGPL-2.1 file for details.
10 #include <l4/cxx/thread>
11 #include <l4/cxx/iostream>
12 #include <l4/cxx/l4iostream>
14 #include <l4/sys/thread>
15 #include <l4/sys/factory>
16 #include <l4/sys/scheduler>
17 #include <l4/sys/ipc.h>
19 #include <l4/util/util.h>
22 #include <l4/cxx/ipc_stream>
28 l4_cap_idx_t _next_cap = 20 << L4_CAP_SHIFT;
29 static inline l4_cap_idx_t alloc_next_cap()
30 { l4_cap_idx_t r = _next_cap; _next_cap += (1UL << L4_CAP_SHIFT); return r; }
31 l4_addr_t _next_free_utcb;
35 L4::Cap<void> Thread::_pager;
36 L4::Cap<void> Thread::_master;
38 Thread::Thread( bool /*initiate*/ )
39 : _cap(L4Re::Env::env()->main_thread()), _state(Running)
41 _next_free_utcb = L4Re::Env::env()->first_free_utcb();
43 L4::Thread::Attr attr;
45 _pager = attr.pager();
46 _utcb_base = l4_addr_t(l4_utcb());
52 l4_msgtag_t err = L4Re::Env::env()->factory()->create_thread(_cap);
53 if (l4_msgtag_has_error(err) || l4_msgtag_label(err) < 0)
54 return l4_msgtag_label(err);
56 L4::Thread::Attr attr(l4_utcb());
58 attr.bind((l4_utcb_t*)_next_free_utcb, L4Re::This_task);
59 _next_free_utcb += L4_UTCB_OFFSET;
60 return _cap->control(attr).label();
63 Thread::Thread( void *stack )
64 : _cap(alloc_next_cap()), _state(Dead), _stack(stack)
69 Thread::Thread( void *stack, L4::Cap<L4::Thread> const &cap )
70 : _cap(cap), _state(Dead), _stack(stack)
82 L4Re::Env::env()->scheduler()->
83 run_thread(_cap, l4_sched_param(0xff, 0));
85 *(--((l4_umword_t*&)_stack)) = (l4_umword_t)this;
86 *(--((l4_umword_t*&)_stack)) = 0;
87 _cap->ex_regs((l4_umword_t)start_cxx_thread,
88 (l4_umword_t)_stack, 0);
90 if (l4_msgtag_has_error(l4_ipc_send(_cap.cap(), l4_utcb(),
93 L4::cerr << "ERROR: (master) error while thread handshake: "
94 << _master << "->" << self() << "\n";
98 void Thread::execute()
101 l4_msgtag_t tag = l4_ipc_wait(l4_utcb(), &src, L4_IPC_NEVER);
103 if (l4_msgtag_has_error(tag))
104 L4::cerr << "ERROR: (slave) error while thread handshake: "
111 void Thread::shutdown()
115 l4_ipc_sleep(L4_IPC_NEVER);
121 L4::cerr << "~Thread[" << self() << "]() called from "
122 << l4_myself() << " @" << L4::hex
123 << __builtin_return_address(0) << "\n";
127 *(((l4_umword_t*&)_stack)--) = (l4_umword_t)this;
128 _cap->ex_regs((l4_umword_t)kill_cxx_thread,
129 (l4_umword_t)_stack, 0);