xref: /haiku/src/system/kernel/thread.cpp (revision 445d4fd926c569e7b9ae28017da86280aaecbae2)
1 /*
2  * Copyright 2018, Jérôme Duval, jerome.duval@gmail.com.
3  * Copyright 2005-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
4  * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
5  * Distributed under the terms of the MIT License.
6  *
7  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
8  * Distributed under the terms of the NewOS License.
9  */
10 
11 
12 /*! Threading routines */
13 
14 
15 #include <thread.h>
16 
17 #include <errno.h>
18 #include <malloc.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <sys/resource.h>
23 
24 #include <algorithm>
25 
26 #include <OS.h>
27 
28 #include <util/AutoLock.h>
29 #include <util/ThreadAutoLock.h>
30 
31 #include <arch/debug.h>
32 #include <boot/kernel_args.h>
33 #include <condition_variable.h>
34 #include <cpu.h>
35 #include <int.h>
36 #include <kimage.h>
37 #include <kscheduler.h>
38 #include <ksignal.h>
39 #include <Notifications.h>
40 #include <real_time_clock.h>
41 #include <slab/Slab.h>
42 #include <smp.h>
43 #include <syscalls.h>
44 #include <syscall_restart.h>
45 #include <team.h>
46 #include <tls.h>
47 #include <user_runtime.h>
48 #include <user_thread.h>
49 #include <vfs.h>
50 #include <vm/vm.h>
51 #include <vm/VMAddressSpace.h>
52 #include <wait_for_objects.h>
53 
54 #include "TeamThreadTables.h"
55 
56 
57 //#define TRACE_THREAD
58 #ifdef TRACE_THREAD
59 #	define TRACE(x) dprintf x
60 #else
61 #	define TRACE(x) ;
62 #endif
63 
64 
65 #define THREAD_MAX_MESSAGE_SIZE		65536
66 
67 
68 // #pragma mark - ThreadHashTable
69 
70 
71 typedef BKernel::TeamThreadTable<Thread> ThreadHashTable;
72 
73 
74 // thread list
75 static Thread sIdleThreads[SMP_MAX_CPUS];
76 static ThreadHashTable sThreadHash;
77 static rw_spinlock sThreadHashLock = B_RW_SPINLOCK_INITIALIZER;
78 static thread_id sNextThreadID = 2;
79 	// ID 1 is allocated for the kernel by Team::Team() behind our back
80 
81 // some arbitrarily chosen limits -- should probably depend on the available
82 // memory
83 static int32 sMaxThreads = 4096;
84 static int32 sUsedThreads = 0;
85 
86 spinlock gThreadCreationLock = B_SPINLOCK_INITIALIZER;
87 
88 
89 struct UndertakerEntry : DoublyLinkedListLinkImpl<UndertakerEntry> {
90 	Thread*	thread;
91 	team_id	teamID;
92 
93 	UndertakerEntry(Thread* thread, team_id teamID)
94 		:
95 		thread(thread),
96 		teamID(teamID)
97 	{
98 	}
99 };
100 
101 
102 struct ThreadEntryArguments {
103 	status_t	(*kernelFunction)(void* argument);
104 	void*		argument;
105 	bool		enterUserland;
106 };
107 
108 struct UserThreadEntryArguments : ThreadEntryArguments {
109 	addr_t			userlandEntry;
110 	void*			userlandArgument1;
111 	void*			userlandArgument2;
112 	pthread_t		pthread;
113 	arch_fork_arg*	forkArgs;
114 	uint32			flags;
115 };
116 
117 
118 class ThreadNotificationService : public DefaultNotificationService {
119 public:
120 	ThreadNotificationService()
121 		: DefaultNotificationService("threads")
122 	{
123 	}
124 
125 	void Notify(uint32 eventCode, team_id teamID, thread_id threadID,
126 		Thread* thread = NULL)
127 	{
128 		char eventBuffer[180];
129 		KMessage event;
130 		event.SetTo(eventBuffer, sizeof(eventBuffer), THREAD_MONITOR);
131 		event.AddInt32("event", eventCode);
132 		event.AddInt32("team", teamID);
133 		event.AddInt32("thread", threadID);
134 		if (thread != NULL)
135 			event.AddPointer("threadStruct", thread);
136 
137 		DefaultNotificationService::Notify(event, eventCode);
138 	}
139 
140 	void Notify(uint32 eventCode, Thread* thread)
141 	{
142 		return Notify(eventCode, thread->id, thread->team->id, thread);
143 	}
144 };
145 
146 
147 static DoublyLinkedList<UndertakerEntry> sUndertakerEntries;
148 static spinlock sUndertakerLock = B_SPINLOCK_INITIALIZER;
149 static ConditionVariable sUndertakerCondition;
150 static ThreadNotificationService sNotificationService;
151 
152 
153 // object cache to allocate thread structures from
154 static object_cache* sThreadCache;
155 
156 
157 // #pragma mark - Thread
158 
159 
160 /*!	Constructs a thread.
161 
162 	\param name The thread's name.
163 	\param threadID The ID to be assigned to the new thread. If
164 		  \code < 0 \endcode a fresh one is allocated.
165 	\param cpu The CPU the thread shall be assigned.
166 */
167 Thread::Thread(const char* name, thread_id threadID, struct cpu_ent* cpu)
168 	:
169 	flags(0),
170 	serial_number(-1),
171 	hash_next(NULL),
172 	team_next(NULL),
173 	priority(-1),
174 	io_priority(-1),
175 	cpu(cpu),
176 	previous_cpu(NULL),
177 	pinned_to_cpu(0),
178 	sig_block_mask(0),
179 	sigsuspend_original_unblocked_mask(0),
180 	user_signal_context(NULL),
181 	signal_stack_base(0),
182 	signal_stack_size(0),
183 	signal_stack_enabled(false),
184 	in_kernel(true),
185 	has_yielded(false),
186 	user_thread(NULL),
187 	fault_handler(0),
188 	page_faults_allowed(1),
189 	team(NULL),
190 	select_infos(NULL),
191 	kernel_stack_area(-1),
192 	kernel_stack_base(0),
193 	user_stack_area(-1),
194 	user_stack_base(0),
195 	user_local_storage(0),
196 	kernel_errno(0),
197 	user_time(0),
198 	kernel_time(0),
199 	last_time(0),
200 	cpu_clock_offset(0),
201 	post_interrupt_callback(NULL),
202 	post_interrupt_data(NULL)
203 {
204 	id = threadID >= 0 ? threadID : allocate_thread_id();
205 	visible = false;
206 
207 	// init locks
208 	char lockName[32];
209 	snprintf(lockName, sizeof(lockName), "Thread:%" B_PRId32, id);
210 	mutex_init_etc(&fLock, lockName, MUTEX_FLAG_CLONE_NAME);
211 
212 	B_INITIALIZE_SPINLOCK(&time_lock);
213 	B_INITIALIZE_SPINLOCK(&scheduler_lock);
214 	B_INITIALIZE_RW_SPINLOCK(&team_lock);
215 
216 	// init name
217 	if (name != NULL)
218 		strlcpy(this->name, name, B_OS_NAME_LENGTH);
219 	else
220 		strcpy(this->name, "unnamed thread");
221 
222 	exit.status = 0;
223 
224 	list_init(&exit.waiters);
225 
226 	exit.sem = -1;
227 	msg.write_sem = -1;
228 	msg.read_sem = -1;
229 
230 	// add to thread table -- yet invisible
231 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
232 	sThreadHash.Insert(this);
233 }
234 
235 
236 Thread::~Thread()
237 {
238 	// Delete resources that should actually be deleted by the thread itself,
239 	// when it exited, but that might still exist, if the thread was never run.
240 
241 	if (user_stack_area >= 0)
242 		delete_area(user_stack_area);
243 
244 	DeleteUserTimers(false);
245 
246 	// delete the resources, that may remain in either case
247 
248 	if (kernel_stack_area >= 0)
249 		delete_area(kernel_stack_area);
250 
251 	fPendingSignals.Clear();
252 
253 	if (exit.sem >= 0)
254 		delete_sem(exit.sem);
255 	if (msg.write_sem >= 0)
256 		delete_sem(msg.write_sem);
257 	if (msg.read_sem >= 0)
258 		delete_sem(msg.read_sem);
259 
260 	scheduler_on_thread_destroy(this);
261 
262 	mutex_destroy(&fLock);
263 
264 	// remove from thread table
265 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
266 	sThreadHash.Remove(this);
267 }
268 
269 
270 /*static*/ status_t
271 Thread::Create(const char* name, Thread*& _thread)
272 {
273 	Thread* thread = new Thread(name, -1, NULL);
274 	if (thread == NULL)
275 		return B_NO_MEMORY;
276 
277 	status_t error = thread->Init(false);
278 	if (error != B_OK) {
279 		delete thread;
280 		return error;
281 	}
282 
283 	_thread = thread;
284 	return B_OK;
285 }
286 
287 
288 /*static*/ Thread*
289 Thread::Get(thread_id id)
290 {
291 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
292 	Thread* thread = sThreadHash.Lookup(id);
293 	if (thread != NULL)
294 		thread->AcquireReference();
295 	return thread;
296 }
297 
298 
299 /*static*/ Thread*
300 Thread::GetAndLock(thread_id id)
301 {
302 	// look it up and acquire a reference
303 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
304 	Thread* thread = sThreadHash.Lookup(id);
305 	if (thread == NULL)
306 		return NULL;
307 
308 	thread->AcquireReference();
309 	threadHashLocker.Unlock();
310 
311 	// lock and check, if it is still in the hash table
312 	thread->Lock();
313 	threadHashLocker.Lock();
314 
315 	if (sThreadHash.Lookup(id) == thread)
316 		return thread;
317 
318 	threadHashLocker.Unlock();
319 
320 	// nope, the thread is no longer in the hash table
321 	thread->UnlockAndReleaseReference();
322 
323 	return NULL;
324 }
325 
326 
327 /*static*/ Thread*
328 Thread::GetDebug(thread_id id)
329 {
330 	return sThreadHash.Lookup(id, false);
331 }
332 
333 
334 /*static*/ bool
335 Thread::IsAlive(thread_id id)
336 {
337 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
338 	return sThreadHash.Lookup(id) != NULL;
339 }
340 
341 
342 void*
343 Thread::operator new(size_t size)
344 {
345 	return object_cache_alloc(sThreadCache, 0);
346 }
347 
348 
349 void*
350 Thread::operator new(size_t, void* pointer)
351 {
352 	return pointer;
353 }
354 
355 
356 void
357 Thread::operator delete(void* pointer, size_t size)
358 {
359 	object_cache_free(sThreadCache, pointer, 0);
360 }
361 
362 
363 status_t
364 Thread::Init(bool idleThread)
365 {
366 	status_t error = scheduler_on_thread_create(this, idleThread);
367 	if (error != B_OK)
368 		return error;
369 
370 	char temp[64];
371 	snprintf(temp, sizeof(temp), "thread_%" B_PRId32 "_retcode_sem", id);
372 	exit.sem = create_sem(0, temp);
373 	if (exit.sem < 0)
374 		return exit.sem;
375 
376 	snprintf(temp, sizeof(temp), "%s send", name);
377 	msg.write_sem = create_sem(1, temp);
378 	if (msg.write_sem < 0)
379 		return msg.write_sem;
380 
381 	snprintf(temp, sizeof(temp), "%s receive", name);
382 	msg.read_sem = create_sem(0, temp);
383 	if (msg.read_sem < 0)
384 		return msg.read_sem;
385 
386 	error = arch_thread_init_thread_struct(this);
387 	if (error != B_OK)
388 		return error;
389 
390 	return B_OK;
391 }
392 
393 
394 /*!	Checks whether the thread is still in the thread hash table.
395 */
396 bool
397 Thread::IsAlive() const
398 {
399 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
400 
401 	return sThreadHash.Lookup(id) != NULL;
402 }
403 
404 
405 void
406 Thread::ResetSignalsOnExec()
407 {
408 	// We are supposed keep the pending signals and the signal mask. Only the
409 	// signal stack, if set, shall be unset.
410 
411 	sigsuspend_original_unblocked_mask = 0;
412 	user_signal_context = NULL;
413 	signal_stack_base = 0;
414 	signal_stack_size = 0;
415 	signal_stack_enabled = false;
416 }
417 
418 
419 /*!	Adds the given user timer to the thread and, if user-defined, assigns it an
420 	ID.
421 
422 	The caller must hold the thread's lock.
423 
424 	\param timer The timer to be added. If it doesn't have an ID yet, it is
425 		considered user-defined and will be assigned an ID.
426 	\return \c B_OK, if the timer was added successfully, another error code
427 		otherwise.
428 */
429 status_t
430 Thread::AddUserTimer(UserTimer* timer)
431 {
432 	// If the timer is user-defined, check timer limit and increment
433 	// user-defined count.
434 	if (timer->ID() < 0 && !team->CheckAddUserDefinedTimer())
435 		return EAGAIN;
436 
437 	fUserTimers.AddTimer(timer);
438 
439 	return B_OK;
440 }
441 
442 
443 /*!	Removes the given user timer from the thread.
444 
445 	The caller must hold the thread's lock.
446 
447 	\param timer The timer to be removed.
448 
449 */
450 void
451 Thread::RemoveUserTimer(UserTimer* timer)
452 {
453 	fUserTimers.RemoveTimer(timer);
454 
455 	if (timer->ID() >= USER_TIMER_FIRST_USER_DEFINED_ID)
456 		team->UserDefinedTimersRemoved(1);
457 }
458 
459 
460 /*!	Deletes all (or all user-defined) user timers of the thread.
461 
462 	The caller must hold the thread's lock.
463 
464 	\param userDefinedOnly If \c true, only the user-defined timers are deleted,
465 		otherwise all timers are deleted.
466 */
467 void
468 Thread::DeleteUserTimers(bool userDefinedOnly)
469 {
470 	int32 count = fUserTimers.DeleteTimers(userDefinedOnly);
471 	if (count > 0)
472 		team->UserDefinedTimersRemoved(count);
473 }
474 
475 
476 void
477 Thread::DeactivateCPUTimeUserTimers()
478 {
479 	while (ThreadTimeUserTimer* timer = fCPUTimeUserTimers.Head())
480 		timer->Deactivate();
481 }
482 
483 
484 // #pragma mark - ThreadListIterator
485 
486 
487 ThreadListIterator::ThreadListIterator()
488 {
489 	// queue the entry
490 	InterruptsWriteSpinLocker locker(sThreadHashLock);
491 	sThreadHash.InsertIteratorEntry(&fEntry);
492 }
493 
494 
495 ThreadListIterator::~ThreadListIterator()
496 {
497 	// remove the entry
498 	InterruptsWriteSpinLocker locker(sThreadHashLock);
499 	sThreadHash.RemoveIteratorEntry(&fEntry);
500 }
501 
502 
503 Thread*
504 ThreadListIterator::Next()
505 {
506 	// get the next team -- if there is one, get reference for it
507 	InterruptsWriteSpinLocker locker(sThreadHashLock);
508 	Thread* thread = sThreadHash.NextElement(&fEntry);
509 	if (thread != NULL)
510 		thread->AcquireReference();
511 
512 	return thread;
513 }
514 
515 
516 // #pragma mark - ThreadCreationAttributes
517 
518 
519 ThreadCreationAttributes::ThreadCreationAttributes(thread_func function,
520 	const char* name, int32 priority, void* arg, team_id team,
521 	Thread* thread)
522 {
523 	this->entry = NULL;
524 	this->name = name;
525 	this->priority = priority;
526 	this->args1 = NULL;
527 	this->args2 = NULL;
528 	this->stack_address = NULL;
529 	this->stack_size = 0;
530 	this->guard_size = 0;
531 	this->pthread = NULL;
532 	this->flags = 0;
533 	this->team = team >= 0 ? team : team_get_kernel_team()->id;
534 	this->thread = thread;
535 	this->signal_mask = 0;
536 	this->additional_stack_size = 0;
537 	this->kernelEntry = function;
538 	this->kernelArgument = arg;
539 	this->forkArgs = NULL;
540 }
541 
542 
543 /*!	Initializes the structure from a userland structure.
544 	\param userAttributes The userland structure (must be a userland address).
545 	\param nameBuffer A character array of at least size B_OS_NAME_LENGTH,
546 		which will be used for the \c name field, if the userland structure has
547 		a name. The buffer must remain valid as long as this structure is in
548 		use afterwards (or until it is reinitialized).
549 	\return \c B_OK, if the initialization went fine, another error code
550 		otherwise.
551 */
552 status_t
553 ThreadCreationAttributes::InitFromUserAttributes(
554 	const thread_creation_attributes* userAttributes, char* nameBuffer)
555 {
556 	if (userAttributes == NULL || !IS_USER_ADDRESS(userAttributes)
557 		|| user_memcpy((thread_creation_attributes*)this, userAttributes,
558 				sizeof(thread_creation_attributes)) != B_OK) {
559 		return B_BAD_ADDRESS;
560 	}
561 
562 	if (stack_size != 0
563 		&& (stack_size < MIN_USER_STACK_SIZE
564 			|| stack_size > MAX_USER_STACK_SIZE)) {
565 		return B_BAD_VALUE;
566 	}
567 
568 	if (entry == NULL || !IS_USER_ADDRESS(entry)
569 		|| (stack_address != NULL && !IS_USER_ADDRESS(stack_address))
570 		|| (name != NULL && (!IS_USER_ADDRESS(name)
571 			|| user_strlcpy(nameBuffer, name, B_OS_NAME_LENGTH) < 0))) {
572 		return B_BAD_ADDRESS;
573 	}
574 
575 	name = name != NULL ? nameBuffer : "user thread";
576 
577 	// kernel only attributes (not in thread_creation_attributes):
578 	Thread* currentThread = thread_get_current_thread();
579 	team = currentThread->team->id;
580 	thread = NULL;
581 	signal_mask = currentThread->sig_block_mask;
582 		// inherit the current thread's signal mask
583 	additional_stack_size = 0;
584 	kernelEntry = NULL;
585 	kernelArgument = NULL;
586 	forkArgs = NULL;
587 
588 	return B_OK;
589 }
590 
591 
592 // #pragma mark - private functions
593 
594 
595 /*!	Inserts a thread into a team.
596 	The caller must hold the team's lock, the thread's lock, and the scheduler
597 	lock.
598 */
599 static void
600 insert_thread_into_team(Team *team, Thread *thread)
601 {
602 	thread->team_next = team->thread_list;
603 	team->thread_list = thread;
604 	team->num_threads++;
605 
606 	if (team->num_threads == 1) {
607 		// this was the first thread
608 		team->main_thread = thread;
609 	}
610 	thread->team = team;
611 }
612 
613 
614 /*!	Removes a thread from a team.
615 	The caller must hold the team's lock, the thread's lock, and the scheduler
616 	lock.
617 */
618 static void
619 remove_thread_from_team(Team *team, Thread *thread)
620 {
621 	Thread *temp, *last = NULL;
622 
623 	for (temp = team->thread_list; temp != NULL; temp = temp->team_next) {
624 		if (temp == thread) {
625 			if (last == NULL)
626 				team->thread_list = temp->team_next;
627 			else
628 				last->team_next = temp->team_next;
629 
630 			team->num_threads--;
631 			break;
632 		}
633 		last = temp;
634 	}
635 }
636 
637 
638 static status_t
639 enter_userspace(Thread* thread, UserThreadEntryArguments* args)
640 {
641 	status_t error = arch_thread_init_tls(thread);
642 	if (error != B_OK) {
643 		dprintf("Failed to init TLS for new userland thread \"%s\" (%" B_PRId32
644 			")\n", thread->name, thread->id);
645 		free(args->forkArgs);
646 		return error;
647 	}
648 
649 	user_debug_update_new_thread_flags(thread);
650 
651 	// init the thread's user_thread
652 	user_thread* userThread = thread->user_thread;
653 	set_ac();
654 	userThread->pthread = args->pthread;
655 	userThread->flags = 0;
656 	userThread->wait_status = B_OK;
657 	userThread->defer_signals
658 		= (args->flags & THREAD_CREATION_FLAG_DEFER_SIGNALS) != 0 ? 1 : 0;
659 	userThread->pending_signals = 0;
660 	clear_ac();
661 
662 	// initialize default TLS fields
663 	addr_t tls[TLS_FIRST_FREE_SLOT];
664 	memset(tls, 0, sizeof(tls));
665 	tls[TLS_BASE_ADDRESS_SLOT] = thread->user_local_storage;
666 	tls[TLS_THREAD_ID_SLOT] = thread->id;
667 	tls[TLS_USER_THREAD_SLOT] = (addr_t)thread->user_thread;
668 
669 	if (args->forkArgs == NULL) {
670 		if (user_memcpy((void*)thread->user_local_storage, tls, sizeof(tls)) != B_OK)
671 			return B_BAD_ADDRESS;
672 	} else {
673 		// This is a fork()ed thread.
674 
675 		// Update select TLS values, do not clear the whole array.
676 		set_ac();
677 		addr_t* userTls = (addr_t*)thread->user_local_storage;
678 		ASSERT(userTls[TLS_BASE_ADDRESS_SLOT] == thread->user_local_storage);
679 		userTls[TLS_THREAD_ID_SLOT] = tls[TLS_THREAD_ID_SLOT];
680 		userTls[TLS_USER_THREAD_SLOT] = tls[TLS_USER_THREAD_SLOT];
681 		clear_ac();
682 
683 		// Copy the fork args onto the stack and free them.
684 		arch_fork_arg archArgs = *args->forkArgs;
685 		free(args->forkArgs);
686 
687 		arch_restore_fork_frame(&archArgs);
688 			// this one won't return here
689 		return B_ERROR;
690 	}
691 
692 	// Jump to the entry point in user space. Only returns, if something fails.
693 	return arch_thread_enter_userspace(thread, args->userlandEntry,
694 		args->userlandArgument1, args->userlandArgument2);
695 }
696 
697 
698 status_t
699 thread_enter_userspace_new_team(Thread* thread, addr_t entryFunction,
700 	void* argument1, void* argument2)
701 {
702 	UserThreadEntryArguments entryArgs;
703 	entryArgs.kernelFunction = NULL;
704 	entryArgs.argument = NULL;
705 	entryArgs.enterUserland = true;
706 	entryArgs.userlandEntry = (addr_t)entryFunction;
707 	entryArgs.userlandArgument1 = argument1;
708 	entryArgs.userlandArgument2 = argument2;
709 	entryArgs.pthread = NULL;
710 	entryArgs.forkArgs = NULL;
711 	entryArgs.flags = 0;
712 
713 	return enter_userspace(thread, &entryArgs);
714 }
715 
716 
717 static void
718 common_thread_entry(void* _args)
719 {
720 	Thread* thread = thread_get_current_thread();
721 
722 	// The thread is new and has been scheduled the first time.
723 
724 	scheduler_new_thread_entry(thread);
725 
726 	// unlock the scheduler lock and enable interrupts
727 	release_spinlock(&thread->scheduler_lock);
728 	enable_interrupts();
729 
730 	// call the kernel function, if any
731 	ThreadEntryArguments* args = (ThreadEntryArguments*)_args;
732 	if (args->kernelFunction != NULL)
733 		args->kernelFunction(args->argument);
734 
735 	// If requested, enter userland, now.
736 	if (args->enterUserland) {
737 		enter_userspace(thread, (UserThreadEntryArguments*)args);
738 			// only returns or error
739 
740 		// If that's the team's main thread, init the team exit info.
741 		if (thread == thread->team->main_thread)
742 			team_init_exit_info_on_error(thread->team);
743 	}
744 
745 	// we're done
746 	thread_exit();
747 }
748 
749 
750 /*!	Prepares the given thread's kernel stack for executing its entry function.
751 
752 	The data pointed to by \a data of size \a dataSize are copied to the
753 	thread's kernel stack. A pointer to the copy's data is passed to the entry
754 	function. The entry function is common_thread_entry().
755 
756 	\param thread The thread.
757 	\param data Pointer to data to be copied to the thread's stack and passed
758 		to the entry function.
759 	\param dataSize The size of \a data.
760  */
761 static void
762 init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)
763 {
764 	uint8* stack = (uint8*)thread->kernel_stack_base;
765 	uint8* stackTop = (uint8*)thread->kernel_stack_top;
766 
767 	// clear (or rather invalidate) the kernel stack contents, if compiled with
768 	// debugging
769 #if KDEBUG > 0
770 #	if defined(DEBUG_KERNEL_STACKS) && defined(STACK_GROWS_DOWNWARDS)
771 	memset((void*)(stack + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE), 0xcc,
772 		KERNEL_STACK_SIZE);
773 #	else
774 	memset(stack, 0xcc, KERNEL_STACK_SIZE);
775 #	endif
776 #endif
777 
778 	// copy the data onto the stack, with 16-byte alignment to be on the safe
779 	// side
780 	void* clonedData;
781 #ifdef STACK_GROWS_DOWNWARDS
782 	clonedData = (void*)ROUNDDOWN((addr_t)stackTop - dataSize, 16);
783 	stackTop = (uint8*)clonedData;
784 #else
785 	clonedData = (void*)ROUNDUP((addr_t)stack, 16);
786 	stack = (uint8*)clonedData + ROUNDUP(dataSize, 16);
787 #endif
788 
789 	memcpy(clonedData, data, dataSize);
790 
791 	arch_thread_init_kthread_stack(thread, stack, stackTop,
792 		&common_thread_entry, clonedData);
793 }
794 
795 
796 static status_t
797 create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
798 	size_t stackSize, size_t additionalSize, size_t guardSize,
799 	char* nameBuffer)
800 {
801 	area_id stackArea = -1;
802 	uint8* stackBase = (uint8*)_stackBase;
803 
804 	if (stackBase != NULL) {
805 		// A stack has been specified. It must be large enough to hold the
806 		// TLS space at least. Guard pages are ignored for existing stacks.
807 		STATIC_ASSERT(TLS_SIZE < MIN_USER_STACK_SIZE);
808 		if (stackSize < MIN_USER_STACK_SIZE)
809 			return B_BAD_VALUE;
810 
811 		stackSize -= TLS_SIZE;
812 	} else {
813 		// No user-defined stack -- allocate one. For non-main threads the stack
814 		// will be between USER_STACK_REGION and the main thread stack area. For
815 		// a main thread the position is fixed.
816 
817 		guardSize = PAGE_ALIGN(guardSize);
818 
819 		if (stackSize == 0) {
820 			// Use the default size (a different one for a main thread).
821 			stackSize = thread->id == team->id
822 				? USER_MAIN_THREAD_STACK_SIZE : USER_STACK_SIZE;
823 		} else {
824 			// Verify that the given stack size is large enough.
825 			if (stackSize < MIN_USER_STACK_SIZE)
826 				return B_BAD_VALUE;
827 
828 			stackSize = PAGE_ALIGN(stackSize);
829 		}
830 
831 		size_t areaSize = PAGE_ALIGN(guardSize + stackSize + TLS_SIZE
832 			+ additionalSize);
833 
834 		snprintf(nameBuffer, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_stack",
835 			thread->name, thread->id);
836 
837 		stackBase = (uint8*)USER_STACK_REGION;
838 
839 		virtual_address_restrictions virtualRestrictions = {};
840 		virtualRestrictions.address_specification = B_RANDOMIZED_BASE_ADDRESS;
841 		virtualRestrictions.address = (void*)stackBase;
842 
843 		physical_address_restrictions physicalRestrictions = {};
844 
845 		stackArea = create_area_etc(team->id, nameBuffer,
846 			areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA | B_STACK_AREA,
847 			0, guardSize, &virtualRestrictions, &physicalRestrictions,
848 			(void**)&stackBase);
849 		if (stackArea < 0)
850 			return stackArea;
851 	}
852 
853 	// set the stack
854 	ThreadLocker threadLocker(thread);
855 #ifdef STACK_GROWS_DOWNWARDS
856 	thread->user_stack_base = (addr_t)stackBase + guardSize;
857 #else
858 	thread->user_stack_base = (addr_t)stackBase;
859 #endif
860 	thread->user_stack_size = stackSize;
861 	thread->user_stack_area = stackArea;
862 
863 	return B_OK;
864 }
865 
866 
867 status_t
868 thread_create_user_stack(Team* team, Thread* thread, void* stackBase,
869 	size_t stackSize, size_t additionalSize)
870 {
871 	char nameBuffer[B_OS_NAME_LENGTH];
872 	return create_thread_user_stack(team, thread, stackBase, stackSize,
873 		additionalSize, USER_STACK_GUARD_SIZE, nameBuffer);
874 }
875 
876 
877 /*!	Creates a new thread.
878 
879 	\param attributes The thread creation attributes, specifying the team in
880 		which to create the thread, as well as a whole bunch of other arguments.
881 	\param kernel \c true, if a kernel-only thread shall be created, \c false,
882 		if the thread shall also be able to run in userland.
883 	\return The ID of the newly created thread (>= 0) or an error code on
884 		failure.
885 */
886 thread_id
887 thread_create_thread(const ThreadCreationAttributes& attributes, bool kernel)
888 {
889 	status_t status = B_OK;
890 
891 	TRACE(("thread_create_thread(%s, thread = %p, %s)\n", attributes.name,
892 		attributes.thread, kernel ? "kernel" : "user"));
893 
894 	// get the team
895 	Team* team = Team::Get(attributes.team);
896 	if (team == NULL)
897 		return B_BAD_TEAM_ID;
898 	BReference<Team> teamReference(team, true);
899 
900 	// If a thread object is given, acquire a reference to it, otherwise create
901 	// a new thread object with the given attributes.
902 	Thread* thread = attributes.thread;
903 	if (thread != NULL) {
904 		thread->AcquireReference();
905 	} else {
906 		status = Thread::Create(attributes.name, thread);
907 		if (status != B_OK)
908 			return status;
909 	}
910 	BReference<Thread> threadReference(thread, true);
911 
912 	thread->team = team;
913 		// set already, so, if something goes wrong, the team pointer is
914 		// available for deinitialization
915 	thread->priority = attributes.priority == -1
916 		? B_NORMAL_PRIORITY : attributes.priority;
917 	thread->priority = std::max(thread->priority,
918 			(int32)THREAD_MIN_SET_PRIORITY);
919 	thread->priority = std::min(thread->priority,
920 			(int32)THREAD_MAX_SET_PRIORITY);
921 	thread->state = B_THREAD_SUSPENDED;
922 
923 	thread->sig_block_mask = attributes.signal_mask;
924 
925 	// init debug structure
926 	init_thread_debug_info(&thread->debug_info);
927 
928 	// create the kernel stack
929 	char stackName[B_OS_NAME_LENGTH];
930 	snprintf(stackName, B_OS_NAME_LENGTH, "%s_%" B_PRId32 "_kstack",
931 		thread->name, thread->id);
932 	virtual_address_restrictions virtualRestrictions = {};
933 	virtualRestrictions.address_specification = B_ANY_KERNEL_ADDRESS;
934 	physical_address_restrictions physicalRestrictions = {};
935 
936 	thread->kernel_stack_area = create_area_etc(B_SYSTEM_TEAM, stackName,
937 		KERNEL_STACK_SIZE + KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
938 		B_FULL_LOCK, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA
939 			| B_KERNEL_STACK_AREA, 0, KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE,
940 		&virtualRestrictions, &physicalRestrictions,
941 		(void**)&thread->kernel_stack_base);
942 
943 	if (thread->kernel_stack_area < 0) {
944 		// we're not yet part of a team, so we can just bail out
945 		status = thread->kernel_stack_area;
946 
947 		dprintf("create_thread: error creating kernel stack: %s!\n",
948 			strerror(status));
949 
950 		return status;
951 	}
952 
953 	thread->kernel_stack_top = thread->kernel_stack_base + KERNEL_STACK_SIZE
954 		+ KERNEL_STACK_GUARD_PAGES * B_PAGE_SIZE;
955 
956 	if (kernel) {
957 		// Init the thread's kernel stack. It will start executing
958 		// common_thread_entry() with the arguments we prepare here.
959 		ThreadEntryArguments entryArgs;
960 		entryArgs.kernelFunction = attributes.kernelEntry;
961 		entryArgs.argument = attributes.kernelArgument;
962 		entryArgs.enterUserland = false;
963 
964 		init_thread_kernel_stack(thread, &entryArgs, sizeof(entryArgs));
965 	} else {
966 		// create the userland stack, if the thread doesn't have one yet
967 		if (thread->user_stack_base == 0) {
968 			status = create_thread_user_stack(team, thread,
969 				attributes.stack_address, attributes.stack_size,
970 				attributes.additional_stack_size, attributes.guard_size,
971 				stackName);
972 			if (status != B_OK)
973 				return status;
974 		}
975 
976 		// Init the thread's kernel stack. It will start executing
977 		// common_thread_entry() with the arguments we prepare here.
978 		UserThreadEntryArguments entryArgs;
979 		entryArgs.kernelFunction = attributes.kernelEntry;
980 		entryArgs.argument = attributes.kernelArgument;
981 		entryArgs.enterUserland = true;
982 		entryArgs.userlandEntry = (addr_t)attributes.entry;
983 		entryArgs.userlandArgument1 = attributes.args1;
984 		entryArgs.userlandArgument2 = attributes.args2;
985 		entryArgs.pthread = attributes.pthread;
986 		entryArgs.forkArgs = attributes.forkArgs;
987 		entryArgs.flags = attributes.flags;
988 
989 		init_thread_kernel_stack(thread, &entryArgs, sizeof(entryArgs));
990 
991 		// create the pre-defined thread timers
992 		status = user_timer_create_thread_timers(team, thread);
993 		if (status != B_OK)
994 			return status;
995 	}
996 
997 	// lock the team and see, if it is still alive
998 	TeamLocker teamLocker(team);
999 	if (team->state >= TEAM_STATE_SHUTDOWN)
1000 		return B_BAD_TEAM_ID;
1001 
1002 	bool debugNewThread = false;
1003 	if (!kernel) {
1004 		// allocate the user_thread structure, if not already allocated
1005 		if (thread->user_thread == NULL) {
1006 			thread->user_thread = team_allocate_user_thread(team);
1007 			if (thread->user_thread == NULL)
1008 				return B_NO_MEMORY;
1009 		}
1010 
1011 		// If the new thread belongs to the same team as the current thread, it
1012 		// may inherit some of the thread debug flags.
1013 		Thread* currentThread = thread_get_current_thread();
1014 		if (currentThread != NULL && currentThread->team == team) {
1015 			// inherit all user flags...
1016 			int32 debugFlags = atomic_get(&currentThread->debug_info.flags)
1017 				& B_THREAD_DEBUG_USER_FLAG_MASK;
1018 
1019 			// ... save the syscall tracing flags, unless explicitely specified
1020 			if (!(debugFlags & B_THREAD_DEBUG_SYSCALL_TRACE_CHILD_THREADS)) {
1021 				debugFlags &= ~(B_THREAD_DEBUG_PRE_SYSCALL
1022 					| B_THREAD_DEBUG_POST_SYSCALL);
1023 			}
1024 
1025 			thread->debug_info.flags = debugFlags;
1026 
1027 			// stop the new thread, if desired
1028 			debugNewThread = debugFlags & B_THREAD_DEBUG_STOP_CHILD_THREADS;
1029 		}
1030 	}
1031 
1032 	// We're going to make the thread live, now. The thread itself will take
1033 	// over a reference to its Thread object. We'll acquire another reference
1034 	// for our own use (and threadReference remains armed).
1035 
1036 	ThreadLocker threadLocker(thread);
1037 
1038 	InterruptsSpinLocker threadCreationLocker(gThreadCreationLock);
1039 	WriteSpinLocker threadHashLocker(sThreadHashLock);
1040 
1041 	// check the thread limit
1042 	if (sUsedThreads >= sMaxThreads) {
1043 		// Clean up the user_thread structure. It's a bit unfortunate that the
1044 		// Thread destructor cannot do that, so we have to do that explicitly.
1045 		threadHashLocker.Unlock();
1046 		threadCreationLocker.Unlock();
1047 
1048 		user_thread* userThread = thread->user_thread;
1049 		thread->user_thread = NULL;
1050 
1051 		threadLocker.Unlock();
1052 		teamLocker.Unlock();
1053 
1054 		if (userThread != NULL)
1055 			team_free_user_thread(team, userThread);
1056 
1057 		return B_NO_MORE_THREADS;
1058 	}
1059 
1060 	// make thread visible in global hash/list
1061 	thread->visible = true;
1062 	sUsedThreads++;
1063 
1064 	scheduler_on_thread_init(thread);
1065 
1066 	thread->AcquireReference();
1067 
1068 	// Debug the new thread, if the parent thread required that (see above),
1069 	// or the respective global team debug flag is set. But only, if a
1070 	// debugger is installed for the team.
1071 	if (!kernel) {
1072 		int32 teamDebugFlags = atomic_get(&team->debug_info.flags);
1073 		debugNewThread |= (teamDebugFlags & B_TEAM_DEBUG_STOP_NEW_THREADS) != 0;
1074 		if (debugNewThread
1075 			&& (teamDebugFlags & B_TEAM_DEBUG_DEBUGGER_INSTALLED) != 0) {
1076 			thread->debug_info.flags |= B_THREAD_DEBUG_STOP;
1077 		}
1078 	}
1079 
1080 	{
1081 		SpinLocker signalLocker(team->signal_lock);
1082 		SpinLocker timeLocker(team->time_lock);
1083 
1084 		// insert thread into team
1085 		insert_thread_into_team(team, thread);
1086 	}
1087 
1088 	threadHashLocker.Unlock();
1089 	threadCreationLocker.Unlock();
1090 	threadLocker.Unlock();
1091 	teamLocker.Unlock();
1092 
1093 	// notify listeners
1094 	sNotificationService.Notify(THREAD_ADDED, thread);
1095 
1096 	return thread->id;
1097 }
1098 
1099 
1100 static status_t
1101 undertaker(void* /*args*/)
1102 {
1103 	while (true) {
1104 		// wait for a thread to bury
1105 		InterruptsSpinLocker locker(sUndertakerLock);
1106 
1107 		while (sUndertakerEntries.IsEmpty()) {
1108 			ConditionVariableEntry conditionEntry;
1109 			sUndertakerCondition.Add(&conditionEntry);
1110 			locker.Unlock();
1111 
1112 			conditionEntry.Wait();
1113 
1114 			locker.Lock();
1115 		}
1116 
1117 		UndertakerEntry* _entry = sUndertakerEntries.RemoveHead();
1118 		locker.Unlock();
1119 
1120 		UndertakerEntry entry = *_entry;
1121 			// we need a copy, since the original entry is on the thread's stack
1122 
1123 		// we've got an entry
1124 		Thread* thread = entry.thread;
1125 
1126 		// make sure the thread isn't running anymore
1127 		InterruptsSpinLocker schedulerLocker(thread->scheduler_lock);
1128 		ASSERT(thread->state == THREAD_STATE_FREE_ON_RESCHED);
1129 		schedulerLocker.Unlock();
1130 
1131 		// remove this thread from from the kernel team -- this makes it
1132 		// unaccessible
1133 		Team* kernelTeam = team_get_kernel_team();
1134 		TeamLocker kernelTeamLocker(kernelTeam);
1135 		thread->Lock();
1136 
1137 		InterruptsSpinLocker threadCreationLocker(gThreadCreationLock);
1138 		SpinLocker signalLocker(kernelTeam->signal_lock);
1139 		SpinLocker timeLocker(kernelTeam->time_lock);
1140 
1141 		remove_thread_from_team(kernelTeam, thread);
1142 
1143 		timeLocker.Unlock();
1144 		signalLocker.Unlock();
1145 		threadCreationLocker.Unlock();
1146 
1147 		kernelTeamLocker.Unlock();
1148 
1149 		// free the thread structure
1150 		thread->UnlockAndReleaseReference();
1151 	}
1152 
1153 	// can never get here
1154 	return B_OK;
1155 }
1156 
1157 
1158 /*!	Returns the semaphore the thread is currently waiting on.
1159 
1160 	The return value is purely informative.
1161 	The caller must hold the scheduler lock.
1162 
1163 	\param thread The thread.
1164 	\return The ID of the semaphore the thread is currently waiting on or \c -1,
1165 		if it isn't waiting on a semaphore.
1166 */
1167 static sem_id
1168 get_thread_wait_sem(Thread* thread)
1169 {
1170 	if (thread->state == B_THREAD_WAITING
1171 		&& thread->wait.type == THREAD_BLOCK_TYPE_SEMAPHORE) {
1172 		return (sem_id)(addr_t)thread->wait.object;
1173 	}
1174 	return -1;
1175 }
1176 
1177 
1178 /*!	Fills the thread_info structure with information from the specified thread.
1179 	The caller must hold the thread's lock and the scheduler lock.
1180 */
1181 static void
1182 fill_thread_info(Thread *thread, thread_info *info, size_t size)
1183 {
1184 	info->thread = thread->id;
1185 	info->team = thread->team->id;
1186 
1187 	strlcpy(info->name, thread->name, B_OS_NAME_LENGTH);
1188 
1189 	info->sem = -1;
1190 
1191 	if (thread->state == B_THREAD_WAITING) {
1192 		info->state = B_THREAD_WAITING;
1193 
1194 		switch (thread->wait.type) {
1195 			case THREAD_BLOCK_TYPE_SNOOZE:
1196 				info->state = B_THREAD_ASLEEP;
1197 				break;
1198 
1199 			case THREAD_BLOCK_TYPE_SEMAPHORE:
1200 			{
1201 				sem_id sem = (sem_id)(addr_t)thread->wait.object;
1202 				if (sem == thread->msg.read_sem)
1203 					info->state = B_THREAD_RECEIVING;
1204 				else
1205 					info->sem = sem;
1206 				break;
1207 			}
1208 
1209 			case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1210 			default:
1211 				break;
1212 		}
1213 	} else
1214 		info->state = (thread_state)thread->state;
1215 
1216 	info->priority = thread->priority;
1217 	info->stack_base = (void *)thread->user_stack_base;
1218 	info->stack_end = (void *)(thread->user_stack_base
1219 		+ thread->user_stack_size);
1220 
1221 	InterruptsSpinLocker threadTimeLocker(thread->time_lock);
1222 	info->user_time = thread->user_time;
1223 	info->kernel_time = thread->kernel_time;
1224 }
1225 
1226 
1227 static status_t
1228 send_data_etc(thread_id id, int32 code, const void *buffer, size_t bufferSize,
1229 	int32 flags)
1230 {
1231 	// get the thread
1232 	Thread *target = Thread::Get(id);
1233 	if (target == NULL)
1234 		return B_BAD_THREAD_ID;
1235 	BReference<Thread> targetReference(target, true);
1236 
1237 	// get the write semaphore
1238 	ThreadLocker targetLocker(target);
1239 	sem_id cachedSem = target->msg.write_sem;
1240 	targetLocker.Unlock();
1241 
1242 	if (bufferSize > THREAD_MAX_MESSAGE_SIZE)
1243 		return B_NO_MEMORY;
1244 
1245 	status_t status = acquire_sem_etc(cachedSem, 1, flags, 0);
1246 	if (status == B_INTERRUPTED) {
1247 		// we got interrupted by a signal
1248 		return status;
1249 	}
1250 	if (status != B_OK) {
1251 		// Any other acquisition problems may be due to thread deletion
1252 		return B_BAD_THREAD_ID;
1253 	}
1254 
1255 	void* data;
1256 	if (bufferSize > 0) {
1257 		data = malloc(bufferSize);
1258 		if (data == NULL)
1259 			return B_NO_MEMORY;
1260 		if (user_memcpy(data, buffer, bufferSize) != B_OK) {
1261 			free(data);
1262 			return B_BAD_DATA;
1263 		}
1264 	} else
1265 		data = NULL;
1266 
1267 	targetLocker.Lock();
1268 
1269 	// The target thread could have been deleted at this point.
1270 	if (!target->IsAlive()) {
1271 		targetLocker.Unlock();
1272 		free(data);
1273 		return B_BAD_THREAD_ID;
1274 	}
1275 
1276 	// Save message informations
1277 	target->msg.sender = thread_get_current_thread()->id;
1278 	target->msg.code = code;
1279 	target->msg.size = bufferSize;
1280 	target->msg.buffer = data;
1281 	cachedSem = target->msg.read_sem;
1282 
1283 	targetLocker.Unlock();
1284 
1285 	release_sem(cachedSem);
1286 	return B_OK;
1287 }
1288 
1289 
1290 static int32
1291 receive_data_etc(thread_id *_sender, void *buffer, size_t bufferSize,
1292 	int32 flags)
1293 {
1294 	Thread *thread = thread_get_current_thread();
1295 	size_t size;
1296 	int32 code;
1297 
1298 	status_t status = acquire_sem_etc(thread->msg.read_sem, 1, flags, 0);
1299 	if (status != B_OK) {
1300 		// Actually, we're not supposed to return error codes
1301 		// but since the only reason this can fail is that we
1302 		// were killed, it's probably okay to do so (but also
1303 		// meaningless).
1304 		return status;
1305 	}
1306 
1307 	if (buffer != NULL && bufferSize != 0 && thread->msg.buffer != NULL) {
1308 		size = min_c(bufferSize, thread->msg.size);
1309 		status = user_memcpy(buffer, thread->msg.buffer, size);
1310 		if (status != B_OK) {
1311 			free(thread->msg.buffer);
1312 			release_sem(thread->msg.write_sem);
1313 			return status;
1314 		}
1315 	}
1316 
1317 	*_sender = thread->msg.sender;
1318 	code = thread->msg.code;
1319 
1320 	free(thread->msg.buffer);
1321 	release_sem(thread->msg.write_sem);
1322 
1323 	return code;
1324 }
1325 
1326 
1327 static status_t
1328 common_getrlimit(int resource, struct rlimit * rlp)
1329 {
1330 	if (!rlp)
1331 		return B_BAD_ADDRESS;
1332 
1333 	switch (resource) {
1334 		case RLIMIT_AS:
1335 			rlp->rlim_cur = __HAIKU_ADDR_MAX;
1336 			rlp->rlim_max = __HAIKU_ADDR_MAX;
1337 			return B_OK;
1338 
1339 		case RLIMIT_CORE:
1340 			rlp->rlim_cur = 0;
1341 			rlp->rlim_max = 0;
1342 			return B_OK;
1343 
1344 		case RLIMIT_DATA:
1345 			rlp->rlim_cur = RLIM_INFINITY;
1346 			rlp->rlim_max = RLIM_INFINITY;
1347 			return B_OK;
1348 
1349 		case RLIMIT_NOFILE:
1350 		case RLIMIT_NOVMON:
1351 			return vfs_getrlimit(resource, rlp);
1352 
1353 		case RLIMIT_STACK:
1354 		{
1355 			rlp->rlim_cur = USER_MAIN_THREAD_STACK_SIZE;
1356 			rlp->rlim_max = USER_MAIN_THREAD_STACK_SIZE;
1357 			return B_OK;
1358 		}
1359 
1360 		default:
1361 			return EINVAL;
1362 	}
1363 
1364 	return B_OK;
1365 }
1366 
1367 
1368 static status_t
1369 common_setrlimit(int resource, const struct rlimit * rlp)
1370 {
1371 	if (!rlp)
1372 		return B_BAD_ADDRESS;
1373 
1374 	switch (resource) {
1375 		case RLIMIT_CORE:
1376 			// We don't support core file, so allow settings to 0/0 only.
1377 			if (rlp->rlim_cur != 0 || rlp->rlim_max != 0)
1378 				return EINVAL;
1379 			return B_OK;
1380 
1381 		case RLIMIT_NOFILE:
1382 		case RLIMIT_NOVMON:
1383 			return vfs_setrlimit(resource, rlp);
1384 
1385 		default:
1386 			return EINVAL;
1387 	}
1388 
1389 	return B_OK;
1390 }
1391 
1392 
1393 static status_t
1394 common_snooze_etc(bigtime_t timeout, clockid_t clockID, uint32 flags,
1395 	bigtime_t* _remainingTime)
1396 {
1397 #if KDEBUG
1398 	if (!are_interrupts_enabled()) {
1399 		panic("common_snooze_etc(): called with interrupts disabled, timeout "
1400 			"%" B_PRIdBIGTIME, timeout);
1401 	}
1402 #endif
1403 
1404 	switch (clockID) {
1405 		case CLOCK_REALTIME:
1406 			// make sure the B_TIMEOUT_REAL_TIME_BASE flag is set and fall
1407 			// through
1408 			flags |= B_TIMEOUT_REAL_TIME_BASE;
1409 		case CLOCK_MONOTONIC:
1410 		{
1411 			// Store the start time, for the case that we get interrupted and
1412 			// need to return the remaining time. For absolute timeouts we can
1413 			// still get he time later, if needed.
1414 			bigtime_t startTime
1415 				= _remainingTime != NULL && (flags & B_RELATIVE_TIMEOUT) != 0
1416 					? system_time() : 0;
1417 
1418 			Thread* thread = thread_get_current_thread();
1419 
1420 			thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_SNOOZE,
1421 				NULL);
1422 			status_t status = thread_block_with_timeout(flags, timeout);
1423 
1424 			if (status == B_TIMED_OUT || status == B_WOULD_BLOCK)
1425 				return B_OK;
1426 
1427 			// If interrupted, compute the remaining time, if requested.
1428 			if (status == B_INTERRUPTED && _remainingTime != NULL) {
1429 				if ((flags & B_RELATIVE_TIMEOUT) != 0) {
1430 					*_remainingTime = std::max(
1431 						startTime + timeout - system_time(), (bigtime_t)0);
1432 				} else {
1433 					bigtime_t now = (flags & B_TIMEOUT_REAL_TIME_BASE) != 0
1434 						? real_time_clock_usecs() : system_time();
1435 					*_remainingTime = std::max(timeout - now, (bigtime_t)0);
1436 				}
1437 			}
1438 
1439 			return status;
1440 		}
1441 
1442 		case CLOCK_THREAD_CPUTIME_ID:
1443 			// Waiting for ourselves to do something isn't particularly
1444 			// productive.
1445 			return B_BAD_VALUE;
1446 
1447 		case CLOCK_PROCESS_CPUTIME_ID:
1448 		default:
1449 			// We don't have to support those, but we are allowed to. Could be
1450 			// done be creating a UserTimer on the fly with a custom UserEvent
1451 			// that would just wake us up.
1452 			return ENOTSUP;
1453 	}
1454 }
1455 
1456 
1457 //	#pragma mark - debugger calls
1458 
1459 
1460 static int
1461 make_thread_unreal(int argc, char **argv)
1462 {
1463 	int32 id = -1;
1464 
1465 	if (argc > 2) {
1466 		print_debugger_command_usage(argv[0]);
1467 		return 0;
1468 	}
1469 
1470 	if (argc > 1)
1471 		id = strtoul(argv[1], NULL, 0);
1472 
1473 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1474 			Thread* thread = it.Next();) {
1475 		if (id != -1 && thread->id != id)
1476 			continue;
1477 
1478 		if (thread->priority > B_DISPLAY_PRIORITY) {
1479 			scheduler_set_thread_priority(thread, B_NORMAL_PRIORITY);
1480 			kprintf("thread %" B_PRId32 " made unreal\n", thread->id);
1481 		}
1482 	}
1483 
1484 	return 0;
1485 }
1486 
1487 
1488 static int
1489 set_thread_prio(int argc, char **argv)
1490 {
1491 	int32 id;
1492 	int32 prio;
1493 
1494 	if (argc > 3 || argc < 2) {
1495 		print_debugger_command_usage(argv[0]);
1496 		return 0;
1497 	}
1498 
1499 	prio = strtoul(argv[1], NULL, 0);
1500 	if (prio > THREAD_MAX_SET_PRIORITY)
1501 		prio = THREAD_MAX_SET_PRIORITY;
1502 	if (prio < THREAD_MIN_SET_PRIORITY)
1503 		prio = THREAD_MIN_SET_PRIORITY;
1504 
1505 	if (argc > 2)
1506 		id = strtoul(argv[2], NULL, 0);
1507 	else
1508 		id = thread_get_current_thread()->id;
1509 
1510 	bool found = false;
1511 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1512 			Thread* thread = it.Next();) {
1513 		if (thread->id != id)
1514 			continue;
1515 		scheduler_set_thread_priority(thread, prio);
1516 		kprintf("thread %" B_PRId32 " set to priority %" B_PRId32 "\n", id, prio);
1517 		found = true;
1518 		break;
1519 	}
1520 	if (!found)
1521 		kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1522 
1523 	return 0;
1524 }
1525 
1526 
1527 static int
1528 make_thread_suspended(int argc, char **argv)
1529 {
1530 	int32 id;
1531 
1532 	if (argc > 2) {
1533 		print_debugger_command_usage(argv[0]);
1534 		return 0;
1535 	}
1536 
1537 	if (argc == 1)
1538 		id = thread_get_current_thread()->id;
1539 	else
1540 		id = strtoul(argv[1], NULL, 0);
1541 
1542 	bool found = false;
1543 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1544 			Thread* thread = it.Next();) {
1545 		if (thread->id != id)
1546 			continue;
1547 
1548 		Signal signal(SIGSTOP, SI_USER, B_OK, team_get_kernel_team()->id);
1549 		send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE);
1550 
1551 		kprintf("thread %" B_PRId32 " suspended\n", id);
1552 		found = true;
1553 		break;
1554 	}
1555 	if (!found)
1556 		kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1557 
1558 	return 0;
1559 }
1560 
1561 
1562 static int
1563 make_thread_resumed(int argc, char **argv)
1564 {
1565 	int32 id;
1566 
1567 	if (argc != 2) {
1568 		print_debugger_command_usage(argv[0]);
1569 		return 0;
1570 	}
1571 
1572 	// force user to enter a thread id, as using
1573 	// the current thread is usually not intended
1574 	id = strtoul(argv[1], NULL, 0);
1575 
1576 	bool found = false;
1577 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1578 			Thread* thread = it.Next();) {
1579 		if (thread->id != id)
1580 			continue;
1581 
1582 		if (thread->state == B_THREAD_SUSPENDED || thread->state == B_THREAD_ASLEEP
1583 				|| thread->state == B_THREAD_WAITING) {
1584 			scheduler_enqueue_in_run_queue(thread);
1585 			kprintf("thread %" B_PRId32 " resumed\n", thread->id);
1586 		} else
1587 			kprintf("thread %" B_PRId32 " is already running\n", thread->id);
1588 		found = true;
1589 		break;
1590 	}
1591 	if (!found)
1592 		kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1593 
1594 	return 0;
1595 }
1596 
1597 
1598 static int
1599 drop_into_debugger(int argc, char **argv)
1600 {
1601 	status_t err;
1602 	int32 id;
1603 
1604 	if (argc > 2) {
1605 		print_debugger_command_usage(argv[0]);
1606 		return 0;
1607 	}
1608 
1609 	if (argc == 1)
1610 		id = thread_get_current_thread()->id;
1611 	else
1612 		id = strtoul(argv[1], NULL, 0);
1613 
1614 	err = _user_debug_thread(id);
1615 		// TODO: This is a non-trivial syscall doing some locking, so this is
1616 		// really nasty and may go seriously wrong.
1617 	if (err)
1618 		kprintf("drop failed\n");
1619 	else
1620 		kprintf("thread %" B_PRId32 " dropped into user debugger\n", id);
1621 
1622 	return 0;
1623 }
1624 
1625 
1626 /*!	Returns a user-readable string for a thread state.
1627 	Only for use in the kernel debugger.
1628 */
1629 static const char *
1630 state_to_text(Thread *thread, int32 state)
1631 {
1632 	switch (state) {
1633 		case B_THREAD_READY:
1634 			return "ready";
1635 
1636 		case B_THREAD_RUNNING:
1637 			return "running";
1638 
1639 		case B_THREAD_WAITING:
1640 		{
1641 			if (thread != NULL) {
1642 				switch (thread->wait.type) {
1643 					case THREAD_BLOCK_TYPE_SNOOZE:
1644 						return "zzz";
1645 
1646 					case THREAD_BLOCK_TYPE_SEMAPHORE:
1647 					{
1648 						sem_id sem = (sem_id)(addr_t)thread->wait.object;
1649 						if (sem == thread->msg.read_sem)
1650 							return "receive";
1651 						break;
1652 					}
1653 				}
1654 			}
1655 
1656 			return "waiting";
1657 		}
1658 
1659 		case B_THREAD_SUSPENDED:
1660 			return "suspended";
1661 
1662 		case THREAD_STATE_FREE_ON_RESCHED:
1663 			return "death";
1664 
1665 		default:
1666 			return "UNKNOWN";
1667 	}
1668 }
1669 
1670 
1671 static void
1672 print_thread_list_table_head()
1673 {
1674 	kprintf("%-*s       id  state     wait for  %-*s    cpu pri  %-*s   team  "
1675 		"name\n",
1676 		B_PRINTF_POINTER_WIDTH, "thread", B_PRINTF_POINTER_WIDTH, "object",
1677 		B_PRINTF_POINTER_WIDTH, "stack");
1678 }
1679 
1680 
1681 static void
1682 _dump_thread_info(Thread *thread, bool shortInfo)
1683 {
1684 	if (shortInfo) {
1685 		kprintf("%p %6" B_PRId32 "  %-10s", thread, thread->id,
1686 			state_to_text(thread, thread->state));
1687 
1688 		// does it block on a semaphore or a condition variable?
1689 		if (thread->state == B_THREAD_WAITING) {
1690 			switch (thread->wait.type) {
1691 				case THREAD_BLOCK_TYPE_SEMAPHORE:
1692 				{
1693 					sem_id sem = (sem_id)(addr_t)thread->wait.object;
1694 					if (sem == thread->msg.read_sem)
1695 						kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, "");
1696 					else {
1697 						kprintf("sem       %-*" B_PRId32,
1698 							B_PRINTF_POINTER_WIDTH + 5, sem);
1699 					}
1700 					break;
1701 				}
1702 
1703 				case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1704 				{
1705 					char name[5];
1706 					ssize_t length = debug_condition_variable_type_strlcpy(
1707 						(ConditionVariable*)thread->wait.object, name, sizeof(name));
1708 					if (length > 0)
1709 						kprintf("cvar:%*s %p   ", 4, name, thread->wait.object);
1710 					else
1711 						kprintf("cvar      %p   ", thread->wait.object);
1712 					break;
1713 				}
1714 
1715 				case THREAD_BLOCK_TYPE_SNOOZE:
1716 					kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, "");
1717 					break;
1718 
1719 				case THREAD_BLOCK_TYPE_SIGNAL:
1720 					kprintf("signal%*s", B_PRINTF_POINTER_WIDTH + 9, "");
1721 					break;
1722 
1723 				case THREAD_BLOCK_TYPE_MUTEX:
1724 					kprintf("mutex     %p   ", thread->wait.object);
1725 					break;
1726 
1727 				case THREAD_BLOCK_TYPE_RW_LOCK:
1728 					kprintf("rwlock    %p   ", thread->wait.object);
1729 					break;
1730 
1731 				case THREAD_BLOCK_TYPE_USER:
1732 					kprintf("user%*s", B_PRINTF_POINTER_WIDTH + 11, "");
1733 					break;
1734 
1735 				case THREAD_BLOCK_TYPE_OTHER:
1736 					kprintf("other%*s", B_PRINTF_POINTER_WIDTH + 10, "");
1737 					break;
1738 
1739 				case THREAD_BLOCK_TYPE_OTHER_OBJECT:
1740 					kprintf("other     %p   ", thread->wait.object);
1741 					break;
1742 
1743 				default:
1744 					kprintf("???       %p   ", thread->wait.object);
1745 					break;
1746 			}
1747 		} else
1748 			kprintf("-%*s", B_PRINTF_POINTER_WIDTH + 14, "");
1749 
1750 		// on which CPU does it run?
1751 		if (thread->cpu)
1752 			kprintf("%2d", thread->cpu->cpu_num);
1753 		else
1754 			kprintf(" -");
1755 
1756 		kprintf("%4" B_PRId32 "  %p%5" B_PRId32 "  %s\n", thread->priority,
1757 			(void *)thread->kernel_stack_base, thread->team->id, thread->name);
1758 
1759 		return;
1760 	}
1761 
1762 	// print the long info
1763 
1764 	struct thread_death_entry *death = NULL;
1765 
1766 	kprintf("THREAD: %p\n", thread);
1767 	kprintf("id:                 %" B_PRId32 " (%#" B_PRIx32 ")\n", thread->id,
1768 		thread->id);
1769 	kprintf("serial_number:      %" B_PRId64 "\n", thread->serial_number);
1770 	kprintf("name:               \"%s\"\n", thread->name);
1771 	kprintf("hash_next:          %p\nteam_next:          %p\n",
1772 		thread->hash_next, thread->team_next);
1773 	kprintf("priority:           %" B_PRId32 " (I/O: %" B_PRId32 ")\n",
1774 		thread->priority, thread->io_priority);
1775 	kprintf("state:              %s\n", state_to_text(thread, thread->state));
1776 	kprintf("cpu:                %p ", thread->cpu);
1777 	if (thread->cpu)
1778 		kprintf("(%d)\n", thread->cpu->cpu_num);
1779 	else
1780 		kprintf("\n");
1781 	kprintf("sig_pending:        %#" B_PRIx64 " (blocked: %#" B_PRIx64
1782 		", before sigsuspend(): %#" B_PRIx64 ")\n",
1783 		(int64)thread->ThreadPendingSignals(),
1784 		(int64)thread->sig_block_mask,
1785 		(int64)thread->sigsuspend_original_unblocked_mask);
1786 	kprintf("in_kernel:          %d\n", thread->in_kernel);
1787 
1788 	if (thread->state == B_THREAD_WAITING) {
1789 		kprintf("waiting for:        ");
1790 
1791 		switch (thread->wait.type) {
1792 			case THREAD_BLOCK_TYPE_SEMAPHORE:
1793 			{
1794 				sem_id sem = (sem_id)(addr_t)thread->wait.object;
1795 				if (sem == thread->msg.read_sem)
1796 					kprintf("data\n");
1797 				else
1798 					kprintf("semaphore %" B_PRId32 "\n", sem);
1799 				break;
1800 			}
1801 
1802 			case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1803 				kprintf("condition variable %p\n", thread->wait.object);
1804 				break;
1805 
1806 			case THREAD_BLOCK_TYPE_SNOOZE:
1807 				kprintf("snooze()\n");
1808 				break;
1809 
1810 			case THREAD_BLOCK_TYPE_SIGNAL:
1811 				kprintf("signal\n");
1812 				break;
1813 
1814 			case THREAD_BLOCK_TYPE_MUTEX:
1815 				kprintf("mutex %p\n", thread->wait.object);
1816 				break;
1817 
1818 			case THREAD_BLOCK_TYPE_RW_LOCK:
1819 				kprintf("rwlock %p\n", thread->wait.object);
1820 				break;
1821 
1822 			case THREAD_BLOCK_TYPE_USER:
1823 				kprintf("user\n");
1824 				break;
1825 
1826 			case THREAD_BLOCK_TYPE_OTHER:
1827 				kprintf("other (%s)\n", (char*)thread->wait.object);
1828 				break;
1829 
1830 			case THREAD_BLOCK_TYPE_OTHER_OBJECT:
1831 				kprintf("other (%p)\n", thread->wait.object);
1832 				break;
1833 
1834 			default:
1835 				kprintf("unknown (%p)\n", thread->wait.object);
1836 				break;
1837 		}
1838 	}
1839 
1840 	kprintf("fault_handler:      %p\n", (void *)thread->fault_handler);
1841 	kprintf("team:               %p, \"%s\"\n", thread->team,
1842 		thread->team->Name());
1843 	kprintf("  exit.sem:         %" B_PRId32 "\n", thread->exit.sem);
1844 	kprintf("  exit.status:      %#" B_PRIx32 " (%s)\n", thread->exit.status,
1845 		strerror(thread->exit.status));
1846 	kprintf("  exit.waiters:\n");
1847 	while ((death = (struct thread_death_entry*)list_get_next_item(
1848 			&thread->exit.waiters, death)) != NULL) {
1849 		kprintf("\t%p (thread %" B_PRId32 ")\n", death, death->thread);
1850 	}
1851 
1852 	kprintf("kernel_stack_area:  %" B_PRId32 "\n", thread->kernel_stack_area);
1853 	kprintf("kernel_stack_base:  %p\n", (void *)thread->kernel_stack_base);
1854 	kprintf("user_stack_area:    %" B_PRId32 "\n", thread->user_stack_area);
1855 	kprintf("user_stack_base:    %p\n", (void *)thread->user_stack_base);
1856 	kprintf("user_local_storage: %p\n", (void *)thread->user_local_storage);
1857 	kprintf("user_thread:        %p\n", (void *)thread->user_thread);
1858 	kprintf("kernel_errno:       %#x (%s)\n", thread->kernel_errno,
1859 		strerror(thread->kernel_errno));
1860 	kprintf("kernel_time:        %" B_PRId64 "\n", thread->kernel_time);
1861 	kprintf("user_time:          %" B_PRId64 "\n", thread->user_time);
1862 	kprintf("flags:              0x%" B_PRIx32 "\n", thread->flags);
1863 	kprintf("architecture dependant section:\n");
1864 	arch_thread_dump_info(&thread->arch_info);
1865 	kprintf("scheduler data:\n");
1866 	scheduler_dump_thread_data(thread);
1867 }
1868 
1869 
1870 static int
1871 dump_thread_info(int argc, char **argv)
1872 {
1873 	bool shortInfo = false;
1874 	int argi = 1;
1875 	if (argi < argc && strcmp(argv[argi], "-s") == 0) {
1876 		shortInfo = true;
1877 		print_thread_list_table_head();
1878 		argi++;
1879 	}
1880 
1881 	if (argi == argc) {
1882 		_dump_thread_info(thread_get_current_thread(), shortInfo);
1883 		return 0;
1884 	}
1885 
1886 	for (; argi < argc; argi++) {
1887 		const char *name = argv[argi];
1888 		ulong arg = strtoul(name, NULL, 0);
1889 
1890 		if (IS_KERNEL_ADDRESS(arg)) {
1891 			// semi-hack
1892 			_dump_thread_info((Thread *)arg, shortInfo);
1893 			continue;
1894 		}
1895 
1896 		// walk through the thread list, trying to match name or id
1897 		bool found = false;
1898 		for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1899 				Thread* thread = it.Next();) {
1900 			if (!strcmp(name, thread->name) || thread->id == (thread_id)arg) {
1901 				_dump_thread_info(thread, shortInfo);
1902 				found = true;
1903 				break;
1904 			}
1905 		}
1906 
1907 		if (!found)
1908 			kprintf("thread \"%s\" (%" B_PRId32 ") doesn't exist!\n", name, (thread_id)arg);
1909 	}
1910 
1911 	return 0;
1912 }
1913 
1914 
1915 static int
1916 dump_thread_list(int argc, char **argv)
1917 {
1918 	bool realTimeOnly = false;
1919 	bool calling = false;
1920 	const char *callSymbol = NULL;
1921 	addr_t callStart = 0;
1922 	addr_t callEnd = 0;
1923 	int32 requiredState = 0;
1924 	team_id team = -1;
1925 	sem_id sem = -1;
1926 
1927 	if (!strcmp(argv[0], "realtime"))
1928 		realTimeOnly = true;
1929 	else if (!strcmp(argv[0], "ready"))
1930 		requiredState = B_THREAD_READY;
1931 	else if (!strcmp(argv[0], "running"))
1932 		requiredState = B_THREAD_RUNNING;
1933 	else if (!strcmp(argv[0], "waiting")) {
1934 		requiredState = B_THREAD_WAITING;
1935 
1936 		if (argc > 1) {
1937 			sem = strtoul(argv[1], NULL, 0);
1938 			if (sem == 0)
1939 				kprintf("ignoring invalid semaphore argument.\n");
1940 		}
1941 	} else if (!strcmp(argv[0], "calling")) {
1942 		if (argc < 2) {
1943 			kprintf("Need to give a symbol name or start and end arguments.\n");
1944 			return 0;
1945 		} else if (argc == 3) {
1946 			callStart = parse_expression(argv[1]);
1947 			callEnd = parse_expression(argv[2]);
1948 		} else
1949 			callSymbol = argv[1];
1950 
1951 		calling = true;
1952 	} else if (argc > 1) {
1953 		team = strtoul(argv[1], NULL, 0);
1954 		if (team == 0)
1955 			kprintf("ignoring invalid team argument.\n");
1956 	}
1957 
1958 	print_thread_list_table_head();
1959 
1960 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1961 			Thread* thread = it.Next();) {
1962 		// filter out threads not matching the search criteria
1963 		if ((requiredState && thread->state != requiredState)
1964 			|| (calling && !arch_debug_contains_call(thread, callSymbol,
1965 					callStart, callEnd))
1966 			|| (sem > 0 && get_thread_wait_sem(thread) != sem)
1967 			|| (team > 0 && thread->team->id != team)
1968 			|| (realTimeOnly && thread->priority < B_REAL_TIME_DISPLAY_PRIORITY))
1969 			continue;
1970 
1971 		_dump_thread_info(thread, true);
1972 	}
1973 	return 0;
1974 }
1975 
1976 
1977 static void
1978 update_thread_sigmask_on_exit(Thread* thread)
1979 {
1980 	if ((thread->flags & THREAD_FLAGS_OLD_SIGMASK) != 0) {
1981 		thread->flags &= ~THREAD_FLAGS_OLD_SIGMASK;
1982 		sigprocmask(SIG_SETMASK, &thread->old_sig_block_mask, NULL);
1983 	}
1984 }
1985 
1986 
1987 //	#pragma mark - private kernel API
1988 
1989 
1990 void
1991 thread_exit(void)
1992 {
1993 	cpu_status state;
1994 	Thread* thread = thread_get_current_thread();
1995 	Team* team = thread->team;
1996 	Team* kernelTeam = team_get_kernel_team();
1997 	status_t status;
1998 	struct thread_debug_info debugInfo;
1999 	team_id teamID = team->id;
2000 
2001 	TRACE(("thread %" B_PRId32 " exiting w/return code %#" B_PRIx32 "\n",
2002 		thread->id, thread->exit.status));
2003 
2004 	if (!are_interrupts_enabled())
2005 		panic("thread_exit() called with interrupts disabled!\n");
2006 
2007 	// boost our priority to get this over with
2008 	scheduler_set_thread_priority(thread, B_URGENT_DISPLAY_PRIORITY);
2009 
2010 	if (team != kernelTeam) {
2011 		// Delete all user timers associated with the thread.
2012 		ThreadLocker threadLocker(thread);
2013 		thread->DeleteUserTimers(false);
2014 
2015 		// detach the thread's user thread
2016 		user_thread* userThread = thread->user_thread;
2017 		thread->user_thread = NULL;
2018 
2019 		threadLocker.Unlock();
2020 
2021 		// Delete the thread's user thread, if it's not the main thread. If it
2022 		// is, we can save the work, since it will be deleted with the team's
2023 		// address space.
2024 		if (thread != team->main_thread)
2025 			team_free_user_thread(team, userThread);
2026 	}
2027 
2028 	// remember the user stack area -- we will delete it below
2029 	area_id userStackArea = -1;
2030 	if (team->address_space != NULL && thread->user_stack_area >= 0) {
2031 		userStackArea = thread->user_stack_area;
2032 		thread->user_stack_area = -1;
2033 	}
2034 
2035 	struct job_control_entry *death = NULL;
2036 	struct thread_death_entry* threadDeathEntry = NULL;
2037 	bool deleteTeam = false;
2038 	port_id debuggerPort = -1;
2039 
2040 	if (team != kernelTeam) {
2041 		user_debug_thread_exiting(thread);
2042 
2043 		if (team->main_thread == thread) {
2044 			// The main thread is exiting. Shut down the whole team.
2045 			deleteTeam = true;
2046 
2047 			// kill off all other threads and the user debugger facilities
2048 			debuggerPort = team_shutdown_team(team);
2049 
2050 			// acquire necessary locks, which are: process group lock, kernel
2051 			// team lock, parent team lock, and the team lock
2052 			team->LockProcessGroup();
2053 			kernelTeam->Lock();
2054 			team->LockTeamAndParent(true);
2055 		} else {
2056 			threadDeathEntry
2057 				= (thread_death_entry*)malloc(sizeof(thread_death_entry));
2058 
2059 			// acquire necessary locks, which are: kernel team lock and the team
2060 			// lock
2061 			kernelTeam->Lock();
2062 			team->Lock();
2063 		}
2064 
2065 		ThreadLocker threadLocker(thread);
2066 
2067 		state = disable_interrupts();
2068 
2069 		// swap address spaces, to make sure we're running on the kernel's pgdir
2070 		vm_swap_address_space(team->address_space, VMAddressSpace::Kernel());
2071 
2072 		WriteSpinLocker teamLocker(thread->team_lock);
2073 		SpinLocker threadCreationLocker(gThreadCreationLock);
2074 			// removing the thread and putting its death entry to the parent
2075 			// team needs to be an atomic operation
2076 
2077 		// remember how long this thread lasted
2078 		bigtime_t now = system_time();
2079 
2080 		InterruptsSpinLocker signalLocker(kernelTeam->signal_lock);
2081 		SpinLocker teamTimeLocker(kernelTeam->time_lock);
2082 		SpinLocker threadTimeLocker(thread->time_lock);
2083 
2084 		thread->kernel_time += now - thread->last_time;
2085 		thread->last_time = now;
2086 
2087 		team->dead_threads_kernel_time += thread->kernel_time;
2088 		team->dead_threads_user_time += thread->user_time;
2089 
2090 		// stop/update thread/team CPU time user timers
2091 		if (thread->HasActiveCPUTimeUserTimers()
2092 			|| team->HasActiveCPUTimeUserTimers()) {
2093 			user_timer_stop_cpu_timers(thread, NULL);
2094 		}
2095 
2096 		// deactivate CPU time user timers for the thread
2097 		if (thread->HasActiveCPUTimeUserTimers())
2098 			thread->DeactivateCPUTimeUserTimers();
2099 
2100 		threadTimeLocker.Unlock();
2101 
2102 		// put the thread into the kernel team until it dies
2103 		remove_thread_from_team(team, thread);
2104 		insert_thread_into_team(kernelTeam, thread);
2105 
2106 		teamTimeLocker.Unlock();
2107 		signalLocker.Unlock();
2108 
2109 		teamLocker.Unlock();
2110 
2111 		if (team->death_entry != NULL) {
2112 			if (--team->death_entry->remaining_threads == 0)
2113 				team->death_entry->condition.NotifyOne();
2114 		}
2115 
2116 		if (deleteTeam) {
2117 			Team* parent = team->parent;
2118 
2119 			// Set the team job control state to "dead" and detach the job
2120 			// control entry from our team struct.
2121 			team_set_job_control_state(team, JOB_CONTROL_STATE_DEAD, NULL);
2122 			death = team->job_control_entry;
2123 			team->job_control_entry = NULL;
2124 
2125 			if (death != NULL) {
2126 				death->InitDeadState();
2127 
2128 				// team_set_job_control_state() already moved our entry
2129 				// into the parent's list. We just check the soft limit of
2130 				// death entries.
2131 				if (parent->dead_children.count > MAX_DEAD_CHILDREN) {
2132 					death = parent->dead_children.entries.RemoveHead();
2133 					parent->dead_children.count--;
2134 				} else
2135 					death = NULL;
2136 			}
2137 
2138 			threadCreationLocker.Unlock();
2139 			restore_interrupts(state);
2140 
2141 			threadLocker.Unlock();
2142 
2143 			// Get a temporary reference to the team's process group
2144 			// -- team_remove_team() removes the team from the group, which
2145 			// might destroy it otherwise and we wouldn't be able to unlock it.
2146 			ProcessGroup* group = team->group;
2147 			group->AcquireReference();
2148 
2149 			pid_t foregroundGroupToSignal;
2150 			team_remove_team(team, foregroundGroupToSignal);
2151 
2152 			// unlock everything but the parent team
2153 			team->Unlock();
2154 			if (parent != kernelTeam)
2155 				kernelTeam->Unlock();
2156 			group->Unlock();
2157 			group->ReleaseReference();
2158 
2159 			// Send SIGCHLD to the parent as long as we still have its lock.
2160 			// This makes job control state change + signalling atomic.
2161 			Signal childSignal(SIGCHLD, team->exit.reason, B_OK, team->id);
2162 			if (team->exit.reason == CLD_EXITED) {
2163 				childSignal.SetStatus(team->exit.status);
2164 			} else {
2165 				childSignal.SetStatus(team->exit.signal);
2166 				childSignal.SetSendingUser(team->exit.signaling_user);
2167 			}
2168 			send_signal_to_team(parent, childSignal, B_DO_NOT_RESCHEDULE);
2169 
2170 			// also unlock the parent
2171 			parent->Unlock();
2172 
2173 			// If the team was a session leader with controlling TTY, we have
2174 			// to send SIGHUP to the foreground process group.
2175 			if (foregroundGroupToSignal >= 0) {
2176 				Signal groupSignal(SIGHUP, SI_USER, B_OK, team->id);
2177 				send_signal_to_process_group(foregroundGroupToSignal,
2178 					groupSignal, B_DO_NOT_RESCHEDULE);
2179 			}
2180 		} else {
2181 			// The thread is not the main thread. We store a thread death entry
2182 			// for it, unless someone is already waiting for it.
2183 			if (threadDeathEntry != NULL
2184 				&& list_is_empty(&thread->exit.waiters)) {
2185 				threadDeathEntry->thread = thread->id;
2186 				threadDeathEntry->status = thread->exit.status;
2187 
2188 				// add entry to dead thread list
2189 				list_add_item(&team->dead_threads, threadDeathEntry);
2190 			}
2191 
2192 			threadCreationLocker.Unlock();
2193 			restore_interrupts(state);
2194 
2195 			threadLocker.Unlock();
2196 			team->Unlock();
2197 			kernelTeam->Unlock();
2198 		}
2199 
2200 		TRACE(("thread_exit: thread %" B_PRId32 " now a kernel thread!\n",
2201 			thread->id));
2202 	}
2203 
2204 	// delete the team if we're its main thread
2205 	if (deleteTeam) {
2206 		team_delete_team(team, debuggerPort);
2207 
2208 		// we need to delete any death entry that made it to here
2209 		delete death;
2210 	}
2211 
2212 	ThreadLocker threadLocker(thread);
2213 
2214 	state = disable_interrupts();
2215 	SpinLocker threadCreationLocker(gThreadCreationLock);
2216 
2217 	// mark invisible in global hash/list, so it's no longer accessible
2218 	WriteSpinLocker threadHashLocker(sThreadHashLock);
2219 	thread->visible = false;
2220 	sUsedThreads--;
2221 	threadHashLocker.Unlock();
2222 
2223 	// Stop debugging for this thread
2224 	SpinLocker threadDebugInfoLocker(thread->debug_info.lock);
2225 	debugInfo = thread->debug_info;
2226 	clear_thread_debug_info(&thread->debug_info, true);
2227 	threadDebugInfoLocker.Unlock();
2228 
2229 	// Remove the select infos. We notify them a little later.
2230 	select_info* selectInfos = thread->select_infos;
2231 	thread->select_infos = NULL;
2232 
2233 	threadCreationLocker.Unlock();
2234 	restore_interrupts(state);
2235 
2236 	threadLocker.Unlock();
2237 
2238 	destroy_thread_debug_info(&debugInfo);
2239 
2240 	// notify select infos
2241 	select_info* info = selectInfos;
2242 	while (info != NULL) {
2243 		select_sync* sync = info->sync;
2244 
2245 		notify_select_events(info, B_EVENT_INVALID);
2246 		info = info->next;
2247 		put_select_sync(sync);
2248 	}
2249 
2250 	// notify listeners
2251 	sNotificationService.Notify(THREAD_REMOVED, thread);
2252 
2253 	// shutdown the thread messaging
2254 
2255 	status = acquire_sem_etc(thread->msg.write_sem, 1, B_RELATIVE_TIMEOUT, 0);
2256 	if (status == B_WOULD_BLOCK) {
2257 		// there is data waiting for us, so let us eat it
2258 		thread_id sender;
2259 
2260 		delete_sem(thread->msg.write_sem);
2261 			// first, let's remove all possibly waiting writers
2262 		receive_data_etc(&sender, NULL, 0, B_RELATIVE_TIMEOUT);
2263 	} else {
2264 		// we probably own the semaphore here, and we're the last to do so
2265 		delete_sem(thread->msg.write_sem);
2266 	}
2267 	// now we can safely remove the msg.read_sem
2268 	delete_sem(thread->msg.read_sem);
2269 
2270 	// fill all death entries and delete the sem that others will use to wait
2271 	// for us
2272 	{
2273 		sem_id cachedExitSem = thread->exit.sem;
2274 
2275 		ThreadLocker threadLocker(thread);
2276 
2277 		// make sure no one will grab this semaphore again
2278 		thread->exit.sem = -1;
2279 
2280 		// fill all death entries
2281 		thread_death_entry* entry = NULL;
2282 		while ((entry = (thread_death_entry*)list_get_next_item(
2283 				&thread->exit.waiters, entry)) != NULL) {
2284 			entry->status = thread->exit.status;
2285 		}
2286 
2287 		threadLocker.Unlock();
2288 
2289 		delete_sem(cachedExitSem);
2290 	}
2291 
2292 	// delete the user stack, if this was a user thread
2293 	if (!deleteTeam && userStackArea >= 0) {
2294 		// We postponed deleting the user stack until now, since this way all
2295 		// notifications for the thread's death are out already and all other
2296 		// threads waiting for this thread's death and some object on its stack
2297 		// will wake up before we (try to) delete the stack area. Of most
2298 		// relevance is probably the case where this is the main thread and
2299 		// other threads use objects on its stack -- so we want them terminated
2300 		// first.
2301 		// When the team is deleted, all areas are deleted anyway, so we don't
2302 		// need to do that explicitly in that case.
2303 		vm_delete_area(teamID, userStackArea, true);
2304 	}
2305 
2306 	// notify the debugger
2307 	if (teamID != kernelTeam->id)
2308 		user_debug_thread_deleted(teamID, thread->id);
2309 
2310 	// enqueue in the undertaker list and reschedule for the last time
2311 	UndertakerEntry undertakerEntry(thread, teamID);
2312 
2313 	disable_interrupts();
2314 
2315 	SpinLocker schedulerLocker(thread->scheduler_lock);
2316 
2317 	SpinLocker undertakerLocker(sUndertakerLock);
2318 	sUndertakerEntries.Add(&undertakerEntry);
2319 	sUndertakerCondition.NotifyOne();
2320 	undertakerLocker.Unlock();
2321 
2322 	scheduler_reschedule(THREAD_STATE_FREE_ON_RESCHED);
2323 
2324 	panic("never can get here\n");
2325 }
2326 
2327 
2328 /*!	Called in the interrupt handler code when a thread enters
2329 	the kernel for any reason.
2330 	Only tracks time for now.
2331 	Interrupts are disabled.
2332 */
2333 void
2334 thread_at_kernel_entry(bigtime_t now)
2335 {
2336 	Thread *thread = thread_get_current_thread();
2337 
2338 	TRACE(("thread_at_kernel_entry: entry thread %" B_PRId32 "\n", thread->id));
2339 
2340 	// track user time
2341 	SpinLocker threadTimeLocker(thread->time_lock);
2342 	thread->user_time += now - thread->last_time;
2343 	thread->last_time = now;
2344 	thread->in_kernel = true;
2345 	threadTimeLocker.Unlock();
2346 }
2347 
2348 
2349 /*!	Called whenever a thread exits kernel space to user space.
2350 	Tracks time, handles signals, ...
2351 	Interrupts must be enabled. When the function returns, interrupts will be
2352 	disabled.
2353 	The function may not return. This e.g. happens when the thread has received
2354 	a deadly signal.
2355 */
2356 void
2357 thread_at_kernel_exit(void)
2358 {
2359 	Thread *thread = thread_get_current_thread();
2360 
2361 	TRACE(("thread_at_kernel_exit: exit thread %" B_PRId32 "\n", thread->id));
2362 
2363 	handle_signals(thread);
2364 
2365 	disable_interrupts();
2366 
2367 	update_thread_sigmask_on_exit(thread);
2368 
2369 	// track kernel time
2370 	bigtime_t now = system_time();
2371 	SpinLocker threadTimeLocker(thread->time_lock);
2372 	thread->in_kernel = false;
2373 	thread->kernel_time += now - thread->last_time;
2374 	thread->last_time = now;
2375 }
2376 
2377 
2378 /*!	The quick version of thread_kernel_exit(), in case no signals are pending
2379 	and no debugging shall be done.
2380 	Interrupts must be disabled.
2381 */
2382 void
2383 thread_at_kernel_exit_no_signals(void)
2384 {
2385 	Thread *thread = thread_get_current_thread();
2386 
2387 	TRACE(("thread_at_kernel_exit_no_signals: exit thread %" B_PRId32 "\n",
2388 		thread->id));
2389 
2390 	update_thread_sigmask_on_exit(thread);
2391 
2392 	// track kernel time
2393 	bigtime_t now = system_time();
2394 	SpinLocker threadTimeLocker(thread->time_lock);
2395 	thread->in_kernel = false;
2396 	thread->kernel_time += now - thread->last_time;
2397 	thread->last_time = now;
2398 }
2399 
2400 
2401 void
2402 thread_reset_for_exec(void)
2403 {
2404 	Thread* thread = thread_get_current_thread();
2405 
2406 	ThreadLocker threadLocker(thread);
2407 
2408 	// delete user-defined timers
2409 	thread->DeleteUserTimers(true);
2410 
2411 	// cancel pre-defined timer
2412 	if (UserTimer* timer = thread->UserTimerFor(USER_TIMER_REAL_TIME_ID))
2413 		timer->Cancel();
2414 
2415 	// reset user_thread and user stack
2416 	thread->user_thread = NULL;
2417 	thread->user_stack_area = -1;
2418 	thread->user_stack_base = 0;
2419 	thread->user_stack_size = 0;
2420 
2421 	// reset signals
2422 	thread->ResetSignalsOnExec();
2423 
2424 	// reset thread CPU time clock
2425 	InterruptsSpinLocker timeLocker(thread->time_lock);
2426 	thread->cpu_clock_offset = -thread->CPUTime(false);
2427 }
2428 
2429 
2430 thread_id
2431 allocate_thread_id()
2432 {
2433 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
2434 
2435 	// find the next unused ID
2436 	thread_id id;
2437 	do {
2438 		id = sNextThreadID++;
2439 
2440 		// deal with integer overflow
2441 		if (sNextThreadID < 0)
2442 			sNextThreadID = 2;
2443 
2444 		// check whether the ID is already in use
2445 	} while (sThreadHash.Lookup(id, false) != NULL);
2446 
2447 	return id;
2448 }
2449 
2450 
2451 thread_id
2452 peek_next_thread_id()
2453 {
2454 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
2455 	return sNextThreadID;
2456 }
2457 
2458 
2459 /*!	Yield the CPU to other threads.
2460 	Thread will continue to run, if there's no other thread in ready
2461 	state, and if it has a higher priority than the other ready threads, it
2462 	still has a good chance to continue.
2463 */
2464 void
2465 thread_yield(void)
2466 {
2467 	Thread *thread = thread_get_current_thread();
2468 	if (thread == NULL)
2469 		return;
2470 
2471 	InterruptsSpinLocker _(thread->scheduler_lock);
2472 
2473 	thread->has_yielded = true;
2474 	scheduler_reschedule(B_THREAD_READY);
2475 }
2476 
2477 
2478 void
2479 thread_map(void (*function)(Thread* thread, void* data), void* data)
2480 {
2481 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
2482 
2483 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
2484 		Thread* thread = it.Next();) {
2485 		function(thread, data);
2486 	}
2487 }
2488 
2489 
2490 /*!	Kernel private thread creation function.
2491 */
2492 thread_id
2493 spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority,
2494 	void *arg, team_id team)
2495 {
2496 	return thread_create_thread(
2497 		ThreadCreationAttributes(function, name, priority, arg, team),
2498 		true);
2499 }
2500 
2501 
2502 status_t
2503 wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
2504 	status_t *_returnCode)
2505 {
2506 	if (id < 0)
2507 		return B_BAD_THREAD_ID;
2508 	if (id == thread_get_current_thread_id())
2509 		return EDEADLK;
2510 
2511 	// get the thread, queue our death entry, and fetch the semaphore we have to
2512 	// wait on
2513 	sem_id exitSem = B_BAD_THREAD_ID;
2514 	struct thread_death_entry death;
2515 
2516 	Thread* thread = Thread::GetAndLock(id);
2517 	if (thread != NULL) {
2518 		// remember the semaphore we have to wait on and place our death entry
2519 		exitSem = thread->exit.sem;
2520 		if (exitSem >= 0)
2521 			list_add_link_to_head(&thread->exit.waiters, &death);
2522 
2523 		thread->UnlockAndReleaseReference();
2524 
2525 		if (exitSem < 0)
2526 			return B_BAD_THREAD_ID;
2527 	} else {
2528 		// we couldn't find this thread -- maybe it's already gone, and we'll
2529 		// find its death entry in our team
2530 		Team* team = thread_get_current_thread()->team;
2531 		TeamLocker teamLocker(team);
2532 
2533 		// check the child death entries first (i.e. main threads of child
2534 		// teams)
2535 		bool deleteEntry;
2536 		job_control_entry* freeDeath
2537 			= team_get_death_entry(team, id, &deleteEntry);
2538 		if (freeDeath != NULL) {
2539 			death.status = freeDeath->status;
2540 			if (deleteEntry)
2541 				delete freeDeath;
2542 		} else {
2543 			// check the thread death entries of the team (non-main threads)
2544 			thread_death_entry* threadDeathEntry = NULL;
2545 			while ((threadDeathEntry = (thread_death_entry*)list_get_next_item(
2546 					&team->dead_threads, threadDeathEntry)) != NULL) {
2547 				if (threadDeathEntry->thread == id) {
2548 					list_remove_item(&team->dead_threads, threadDeathEntry);
2549 					death.status = threadDeathEntry->status;
2550 					free(threadDeathEntry);
2551 					break;
2552 				}
2553 			}
2554 
2555 			if (threadDeathEntry == NULL)
2556 				return B_BAD_THREAD_ID;
2557 		}
2558 
2559 		// we found the thread's death entry in our team
2560 		if (_returnCode)
2561 			*_returnCode = death.status;
2562 
2563 		return B_OK;
2564 	}
2565 
2566 	// we need to wait for the death of the thread
2567 
2568 	resume_thread(id);
2569 		// make sure we don't wait forever on a suspended thread
2570 
2571 	status_t status = acquire_sem_etc(exitSem, 1, flags, timeout);
2572 
2573 	if (status == B_OK) {
2574 		// this should never happen as the thread deletes the semaphore on exit
2575 		panic("could acquire exit_sem for thread %" B_PRId32 "\n", id);
2576 	} else if (status == B_BAD_SEM_ID) {
2577 		// this is the way the thread normally exits
2578 		status = B_OK;
2579 	} else {
2580 		// We were probably interrupted or the timeout occurred; we need to
2581 		// remove our death entry now.
2582 		thread = Thread::GetAndLock(id);
2583 		if (thread != NULL) {
2584 			list_remove_link(&death);
2585 			thread->UnlockAndReleaseReference();
2586 		} else {
2587 			// The thread is already gone, so we need to wait uninterruptibly
2588 			// for its exit semaphore to make sure our death entry stays valid.
2589 			// It won't take long, since the thread is apparently already in the
2590 			// middle of the cleanup.
2591 			acquire_sem(exitSem);
2592 			status = B_OK;
2593 		}
2594 	}
2595 
2596 	if (status == B_OK && _returnCode != NULL)
2597 		*_returnCode = death.status;
2598 
2599 	return status;
2600 }
2601 
2602 
2603 status_t
2604 select_thread(int32 id, struct select_info* info, bool kernel)
2605 {
2606 	// get and lock the thread
2607 	Thread* thread = Thread::GetAndLock(id);
2608 	if (thread == NULL)
2609 		return B_BAD_THREAD_ID;
2610 	BReference<Thread> threadReference(thread, true);
2611 	ThreadLocker threadLocker(thread, true);
2612 
2613 	// We support only B_EVENT_INVALID at the moment.
2614 	info->selected_events &= B_EVENT_INVALID;
2615 
2616 	// add info to list
2617 	if (info->selected_events != 0) {
2618 		info->next = thread->select_infos;
2619 		thread->select_infos = info;
2620 
2621 		// we need a sync reference
2622 		atomic_add(&info->sync->ref_count, 1);
2623 	}
2624 
2625 	return B_OK;
2626 }
2627 
2628 
2629 status_t
2630 deselect_thread(int32 id, struct select_info* info, bool kernel)
2631 {
2632 	// get and lock the thread
2633 	Thread* thread = Thread::GetAndLock(id);
2634 	if (thread == NULL)
2635 		return B_BAD_THREAD_ID;
2636 	BReference<Thread> threadReference(thread, true);
2637 	ThreadLocker threadLocker(thread, true);
2638 
2639 	// remove info from list
2640 	select_info** infoLocation = &thread->select_infos;
2641 	while (*infoLocation != NULL && *infoLocation != info)
2642 		infoLocation = &(*infoLocation)->next;
2643 
2644 	if (*infoLocation != info)
2645 		return B_OK;
2646 
2647 	*infoLocation = info->next;
2648 
2649 	threadLocker.Unlock();
2650 
2651 	// surrender sync reference
2652 	put_select_sync(info->sync);
2653 
2654 	return B_OK;
2655 }
2656 
2657 
2658 int32
2659 thread_max_threads(void)
2660 {
2661 	return sMaxThreads;
2662 }
2663 
2664 
2665 int32
2666 thread_used_threads(void)
2667 {
2668 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
2669 	return sUsedThreads;
2670 }
2671 
2672 
2673 /*!	Returns a user-readable string for a thread state.
2674 	Only for use in the kernel debugger.
2675 */
2676 const char*
2677 thread_state_to_text(Thread* thread, int32 state)
2678 {
2679 	return state_to_text(thread, state);
2680 }
2681 
2682 
2683 int32
2684 thread_get_io_priority(thread_id id)
2685 {
2686 	Thread* thread = Thread::GetAndLock(id);
2687 	if (thread == NULL)
2688 		return B_BAD_THREAD_ID;
2689 	BReference<Thread> threadReference(thread, true);
2690 	ThreadLocker threadLocker(thread, true);
2691 
2692 	int32 priority = thread->io_priority;
2693 	if (priority < 0) {
2694 		// negative I/O priority means using the (CPU) priority
2695 		priority = thread->priority;
2696 	}
2697 
2698 	return priority;
2699 }
2700 
2701 
2702 void
2703 thread_set_io_priority(int32 priority)
2704 {
2705 	Thread* thread = thread_get_current_thread();
2706 	ThreadLocker threadLocker(thread);
2707 
2708 	thread->io_priority = priority;
2709 }
2710 
2711 
2712 status_t
2713 thread_init(kernel_args *args)
2714 {
2715 	TRACE(("thread_init: entry\n"));
2716 
2717 	// create the thread hash table
2718 	new(&sThreadHash) ThreadHashTable();
2719 	if (sThreadHash.Init(128) != B_OK)
2720 		panic("thread_init(): failed to init thread hash table!");
2721 
2722 	// create the thread structure object cache
2723 	sThreadCache = create_object_cache("threads", sizeof(Thread), 64, NULL,
2724 		NULL, NULL);
2725 		// Note: The x86 port requires 64 byte alignment of thread structures.
2726 	if (sThreadCache == NULL)
2727 		panic("thread_init(): failed to allocate thread object cache!");
2728 
2729 	if (arch_thread_init(args) < B_OK)
2730 		panic("arch_thread_init() failed!\n");
2731 
2732 	// skip all thread IDs including B_SYSTEM_TEAM, which is reserved
2733 	sNextThreadID = B_SYSTEM_TEAM + 1;
2734 
2735 	// create an idle thread for each cpu
2736 	for (uint32 i = 0; i < args->num_cpus; i++) {
2737 		Thread *thread;
2738 		area_info info;
2739 		char name[64];
2740 
2741 		sprintf(name, "idle thread %" B_PRIu32, i + 1);
2742 		thread = new(&sIdleThreads[i]) Thread(name,
2743 			i == 0 ? team_get_kernel_team_id() : -1, &gCPU[i]);
2744 		if (thread == NULL || thread->Init(true) != B_OK) {
2745 			panic("error creating idle thread struct\n");
2746 			return B_NO_MEMORY;
2747 		}
2748 
2749 		gCPU[i].running_thread = thread;
2750 
2751 		thread->team = team_get_kernel_team();
2752 		thread->priority = B_IDLE_PRIORITY;
2753 		thread->state = B_THREAD_RUNNING;
2754 		sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1);
2755 		thread->kernel_stack_area = find_area(name);
2756 
2757 		if (get_area_info(thread->kernel_stack_area, &info) != B_OK)
2758 			panic("error finding idle kstack area\n");
2759 
2760 		thread->kernel_stack_base = (addr_t)info.address;
2761 		thread->kernel_stack_top = thread->kernel_stack_base + info.size;
2762 
2763 		thread->visible = true;
2764 		insert_thread_into_team(thread->team, thread);
2765 
2766 		scheduler_on_thread_init(thread);
2767 	}
2768 	sUsedThreads = args->num_cpus;
2769 
2770 	// init the notification service
2771 	new(&sNotificationService) ThreadNotificationService();
2772 
2773 	sNotificationService.Register();
2774 
2775 	// start the undertaker thread
2776 	new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>();
2777 	sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries");
2778 
2779 	thread_id undertakerThread = spawn_kernel_thread(&undertaker, "undertaker",
2780 		B_DISPLAY_PRIORITY, NULL);
2781 	if (undertakerThread < 0)
2782 		panic("Failed to create undertaker thread!");
2783 	resume_thread(undertakerThread);
2784 
2785 	// set up some debugger commands
2786 	add_debugger_command_etc("threads", &dump_thread_list, "List all threads",
2787 		"[ <team> ]\n"
2788 		"Prints a list of all existing threads, or, if a team ID is given,\n"
2789 		"all threads of the specified team.\n"
2790 		"  <team>  - The ID of the team whose threads shall be listed.\n", 0);
2791 	add_debugger_command_etc("ready", &dump_thread_list,
2792 		"List all ready threads",
2793 		"\n"
2794 		"Prints a list of all threads in ready state.\n", 0);
2795 	add_debugger_command_etc("running", &dump_thread_list,
2796 		"List all running threads",
2797 		"\n"
2798 		"Prints a list of all threads in running state.\n", 0);
2799 	add_debugger_command_etc("waiting", &dump_thread_list,
2800 		"List all waiting threads (optionally for a specific semaphore)",
2801 		"[ <sem> ]\n"
2802 		"Prints a list of all threads in waiting state. If a semaphore is\n"
2803 		"specified, only the threads waiting on that semaphore are listed.\n"
2804 		"  <sem>  - ID of the semaphore.\n", 0);
2805 	add_debugger_command_etc("realtime", &dump_thread_list,
2806 		"List all realtime threads",
2807 		"\n"
2808 		"Prints a list of all threads with realtime priority.\n", 0);
2809 	add_debugger_command_etc("thread", &dump_thread_info,
2810 		"Dump info about a particular thread",
2811 		"[ -s ] ( <id> | <address> | <name> )*\n"
2812 		"Prints information about the specified thread. If no argument is\n"
2813 		"given the current thread is selected.\n"
2814 		"  -s         - Print info in compact table form (like \"threads\").\n"
2815 		"  <id>       - The ID of the thread.\n"
2816 		"  <address>  - The address of the thread structure.\n"
2817 		"  <name>     - The thread's name.\n", 0);
2818 	add_debugger_command_etc("calling", &dump_thread_list,
2819 		"Show all threads that have a specific address in their call chain",
2820 		"{ <symbol-pattern> | <start> <end> }\n", 0);
2821 	add_debugger_command_etc("unreal", &make_thread_unreal,
2822 		"Set realtime priority threads to normal priority",
2823 		"[ <id> ]\n"
2824 		"Sets the priority of all realtime threads or, if given, the one\n"
2825 		"with the specified ID to \"normal\" priority.\n"
2826 		"  <id>  - The ID of the thread.\n", 0);
2827 	add_debugger_command_etc("suspend", &make_thread_suspended,
2828 		"Suspend a thread",
2829 		"[ <id> ]\n"
2830 		"Suspends the thread with the given ID. If no ID argument is given\n"
2831 		"the current thread is selected.\n"
2832 		"  <id>  - The ID of the thread.\n", 0);
2833 	add_debugger_command_etc("resume", &make_thread_resumed, "Resume a thread",
2834 		"<id>\n"
2835 		"Resumes the specified thread, if it is currently suspended.\n"
2836 		"  <id>  - The ID of the thread.\n", 0);
2837 	add_debugger_command_etc("drop", &drop_into_debugger,
2838 		"Drop a thread into the userland debugger",
2839 		"<id>\n"
2840 		"Drops the specified (userland) thread into the userland debugger\n"
2841 		"after leaving the kernel debugger.\n"
2842 		"  <id>  - The ID of the thread.\n", 0);
2843 	add_debugger_command_etc("priority", &set_thread_prio,
2844 		"Set a thread's priority",
2845 		"<priority> [ <id> ]\n"
2846 		"Sets the priority of the thread with the specified ID to the given\n"
2847 		"priority. If no thread ID is given, the current thread is selected.\n"
2848 		"  <priority>  - The thread's new priority (0 - 120)\n"
2849 		"  <id>        - The ID of the thread.\n", 0);
2850 
2851 	return B_OK;
2852 }
2853 
2854 
2855 status_t
2856 thread_preboot_init_percpu(struct kernel_args *args, int32 cpuNum)
2857 {
2858 	// set up the cpu pointer in the not yet initialized per-cpu idle thread
2859 	// so that get_current_cpu and friends will work, which is crucial for
2860 	// a lot of low level routines
2861 	sIdleThreads[cpuNum].cpu = &gCPU[cpuNum];
2862 	arch_thread_set_current_thread(&sIdleThreads[cpuNum]);
2863 	return B_OK;
2864 }
2865 
2866 
2867 //	#pragma mark - thread blocking API
2868 
2869 
2870 static status_t
2871 thread_block_timeout(timer* timer)
2872 {
2873 	Thread* thread = (Thread*)timer->user_data;
2874 	thread_unblock(thread, B_TIMED_OUT);
2875 
2876 	return B_HANDLED_INTERRUPT;
2877 }
2878 
2879 
2880 /*!	Blocks the current thread.
2881 
2882 	The thread is blocked until someone else unblock it. Must be called after a
2883 	call to thread_prepare_to_block(). If the thread has already been unblocked
2884 	after the previous call to thread_prepare_to_block(), this function will
2885 	return immediately. Cf. the documentation of thread_prepare_to_block() for
2886 	more details.
2887 
2888 	The caller must hold the scheduler lock.
2889 
2890 	\param thread The current thread.
2891 	\return The error code passed to the unblocking function. thread_interrupt()
2892 		uses \c B_INTERRUPTED. By convention \c B_OK means that the wait was
2893 		successful while another error code indicates a failure (what that means
2894 		depends on the client code).
2895 */
2896 static inline status_t
2897 thread_block_locked(Thread* thread)
2898 {
2899 	if (thread->wait.status == 1) {
2900 		// check for signals, if interruptible
2901 		if (thread_is_interrupted(thread, thread->wait.flags)) {
2902 			thread->wait.status = B_INTERRUPTED;
2903 		} else
2904 			scheduler_reschedule(B_THREAD_WAITING);
2905 	}
2906 
2907 	return thread->wait.status;
2908 }
2909 
2910 
2911 /*!	Blocks the current thread.
2912 
2913 	The function acquires the scheduler lock and calls thread_block_locked().
2914 	See there for more information.
2915 */
2916 status_t
2917 thread_block()
2918 {
2919 	InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock);
2920 	return thread_block_locked(thread_get_current_thread());
2921 }
2922 
2923 
2924 /*!	Blocks the current thread with a timeout.
2925 
2926 	The current thread is blocked until someone else unblock it or the specified
2927 	timeout occurs. Must be called after a call to thread_prepare_to_block(). If
2928 	the thread has already been unblocked after the previous call to
2929 	thread_prepare_to_block(), this function will return immediately. See
2930 	thread_prepare_to_block() for more details.
2931 
2932 	The caller must not hold the scheduler lock.
2933 
2934 	\param timeoutFlags The standard timeout flags:
2935 		- \c B_RELATIVE_TIMEOUT: \a timeout specifies the time to wait.
2936 		- \c B_ABSOLUTE_TIMEOUT: \a timeout specifies the absolute end time when
2937 			the timeout shall occur.
2938 		- \c B_TIMEOUT_REAL_TIME_BASE: Only relevant when \c B_ABSOLUTE_TIMEOUT
2939 			is specified, too. Specifies that \a timeout is a real time, not a
2940 			system time.
2941 		If neither \c B_RELATIVE_TIMEOUT nor \c B_ABSOLUTE_TIMEOUT are
2942 		specified, an infinite timeout is implied and the function behaves like
2943 		thread_block_locked().
2944 	\return The error code passed to the unblocking function. thread_interrupt()
2945 		uses \c B_INTERRUPTED. When the timeout occurred, \c B_TIMED_OUT is
2946 		returned. By convention \c B_OK means that the wait was successful while
2947 		another error code indicates a failure (what that means depends on the
2948 		client code).
2949 */
2950 status_t
2951 thread_block_with_timeout(uint32 timeoutFlags, bigtime_t timeout)
2952 {
2953 	Thread* thread = thread_get_current_thread();
2954 
2955 	InterruptsSpinLocker locker(thread->scheduler_lock);
2956 
2957 	if (thread->wait.status != 1)
2958 		return thread->wait.status;
2959 
2960 	bool useTimer = (timeoutFlags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT))
2961 		&& timeout != B_INFINITE_TIMEOUT;
2962 
2963 	if (useTimer) {
2964 		// Timer flags: absolute/relative.
2965 		uint32 timerFlags;
2966 		if ((timeoutFlags & B_RELATIVE_TIMEOUT) != 0) {
2967 			timerFlags = B_ONE_SHOT_RELATIVE_TIMER;
2968 		} else {
2969 			timerFlags = B_ONE_SHOT_ABSOLUTE_TIMER;
2970 			if ((timeoutFlags & B_TIMEOUT_REAL_TIME_BASE) != 0)
2971 				timerFlags |= B_TIMER_REAL_TIME_BASE;
2972 		}
2973 
2974 		// install the timer
2975 		thread->wait.unblock_timer.user_data = thread;
2976 		add_timer(&thread->wait.unblock_timer, &thread_block_timeout, timeout,
2977 			timerFlags);
2978 	}
2979 
2980 	// block
2981 	status_t error = thread_block_locked(thread);
2982 
2983 	locker.Unlock();
2984 
2985 	// cancel timer, if it didn't fire
2986 	if (error != B_TIMED_OUT && useTimer)
2987 		cancel_timer(&thread->wait.unblock_timer);
2988 
2989 	return error;
2990 }
2991 
2992 
2993 /*!	Unblocks a thread.
2994 
2995 	Acquires the scheduler lock and calls thread_unblock_locked().
2996 	See there for more information.
2997 */
2998 void
2999 thread_unblock(Thread* thread, status_t status)
3000 {
3001 	InterruptsSpinLocker locker(thread->scheduler_lock);
3002 	thread_unblock_locked(thread, status);
3003 }
3004 
3005 
3006 /*!	Unblocks a userland-blocked thread.
3007 	The caller must not hold any locks.
3008 */
3009 static status_t
3010 user_unblock_thread(thread_id threadID, status_t status)
3011 {
3012 	// get the thread
3013 	Thread* thread = Thread::GetAndLock(threadID);
3014 	if (thread == NULL)
3015 		return B_BAD_THREAD_ID;
3016 	BReference<Thread> threadReference(thread, true);
3017 	ThreadLocker threadLocker(thread, true);
3018 
3019 	if (thread->user_thread == NULL)
3020 		return B_NOT_ALLOWED;
3021 
3022 	InterruptsSpinLocker locker(thread->scheduler_lock);
3023 
3024 	status_t waitStatus;
3025 	if (user_memcpy(&waitStatus, &thread->user_thread->wait_status,
3026 			sizeof(waitStatus)) < B_OK) {
3027 		return B_BAD_ADDRESS;
3028 	}
3029 	if (waitStatus > 0) {
3030 		if (user_memcpy(&thread->user_thread->wait_status, &status,
3031 				sizeof(status)) < B_OK) {
3032 			return B_BAD_ADDRESS;
3033 		}
3034 
3035 		// Even if the user_thread->wait_status was > 0, it may be the
3036 		// case that this thread is actually blocked on something else.
3037 		if (thread->wait.status > 0
3038 				&& thread->wait.type == THREAD_BLOCK_TYPE_USER) {
3039 			thread_unblock_locked(thread, status);
3040 		}
3041 	}
3042 	return B_OK;
3043 }
3044 
3045 
3046 static bool
3047 thread_check_permissions(const Thread* currentThread, const Thread* thread,
3048 	bool kernel)
3049 {
3050 	if (kernel)
3051 		return true;
3052 
3053 	if (thread->team->id == team_get_kernel_team_id())
3054 		return false;
3055 
3056 	if (thread->team == currentThread->team
3057 			|| currentThread->team->effective_uid == 0
3058 			|| thread->team->real_uid == currentThread->team->real_uid)
3059 		return true;
3060 
3061 	return false;
3062 }
3063 
3064 
3065 static status_t
3066 thread_send_signal(thread_id id, uint32 number, int32 signalCode,
3067 	int32 errorCode, bool kernel)
3068 {
3069 	if (id <= 0)
3070 		return B_BAD_VALUE;
3071 
3072 	Thread* currentThread = thread_get_current_thread();
3073 	Thread* thread = Thread::Get(id);
3074 	if (thread == NULL)
3075 		return B_BAD_THREAD_ID;
3076 	BReference<Thread> threadReference(thread, true);
3077 
3078 	// check whether sending the signal is allowed
3079 	if (!thread_check_permissions(currentThread, thread, kernel))
3080 		return B_NOT_ALLOWED;
3081 
3082 	Signal signal(number, signalCode, errorCode, currentThread->team->id);
3083 	return send_signal_to_thread(thread, signal, 0);
3084 }
3085 
3086 
3087 //	#pragma mark - public kernel API
3088 
3089 
3090 void
3091 exit_thread(status_t returnValue)
3092 {
3093 	Thread *thread = thread_get_current_thread();
3094 	Team* team = thread->team;
3095 
3096 	thread->exit.status = returnValue;
3097 
3098 	// if called from a kernel thread, we don't deliver the signal,
3099 	// we just exit directly to keep the user space behaviour of
3100 	// this function
3101 	if (team != team_get_kernel_team()) {
3102 		// If this is its main thread, set the team's exit status.
3103 		if (thread == team->main_thread) {
3104 			TeamLocker teamLocker(team);
3105 
3106 			if (!team->exit.initialized) {
3107 				team->exit.reason = CLD_EXITED;
3108 				team->exit.signal = 0;
3109 				team->exit.signaling_user = 0;
3110 				team->exit.status = returnValue;
3111 				team->exit.initialized = true;
3112 			}
3113 
3114 			teamLocker.Unlock();
3115 		}
3116 
3117 		Signal signal(SIGKILLTHR, SI_USER, B_OK, team->id);
3118 		send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE);
3119 	} else
3120 		thread_exit();
3121 }
3122 
3123 
3124 static status_t
3125 thread_kill_thread(thread_id id, bool kernel)
3126 {
3127 	return thread_send_signal(id, SIGKILLTHR, SI_USER, B_OK, kernel);
3128 }
3129 
3130 
3131 status_t
3132 kill_thread(thread_id id)
3133 {
3134 	return thread_kill_thread(id, true);
3135 }
3136 
3137 
3138 status_t
3139 send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize)
3140 {
3141 	return send_data_etc(thread, code, buffer, bufferSize, 0);
3142 }
3143 
3144 
3145 int32
3146 receive_data(thread_id *sender, void *buffer, size_t bufferSize)
3147 {
3148 	return receive_data_etc(sender, buffer, bufferSize, 0);
3149 }
3150 
3151 
3152 static bool
3153 thread_has_data(thread_id id, bool kernel)
3154 {
3155 	Thread* currentThread = thread_get_current_thread();
3156 	Thread* thread;
3157 	BReference<Thread> threadReference;
3158 	if (id == currentThread->id) {
3159 		thread = currentThread;
3160 	} else {
3161 		thread = Thread::Get(id);
3162 		if (thread == NULL)
3163 			return false;
3164 
3165 		threadReference.SetTo(thread, true);
3166 	}
3167 
3168 	if (!kernel && thread->team != currentThread->team)
3169 		return false;
3170 
3171 	int32 count;
3172 	if (get_sem_count(thread->msg.read_sem, &count) != B_OK)
3173 		return false;
3174 
3175 	return count == 0 ? false : true;
3176 }
3177 
3178 
3179 bool
3180 has_data(thread_id thread)
3181 {
3182 	return thread_has_data(thread, true);
3183 }
3184 
3185 
3186 status_t
3187 _get_thread_info(thread_id id, thread_info *info, size_t size)
3188 {
3189 	if (info == NULL || size != sizeof(thread_info) || id < B_OK)
3190 		return B_BAD_VALUE;
3191 
3192 	// get the thread
3193 	Thread* thread = Thread::GetAndLock(id);
3194 	if (thread == NULL)
3195 		return B_BAD_THREAD_ID;
3196 	BReference<Thread> threadReference(thread, true);
3197 	ThreadLocker threadLocker(thread, true);
3198 
3199 	// fill the info -- also requires the scheduler lock to be held
3200 	InterruptsSpinLocker locker(thread->scheduler_lock);
3201 
3202 	fill_thread_info(thread, info, size);
3203 
3204 	return B_OK;
3205 }
3206 
3207 
3208 status_t
3209 _get_next_thread_info(team_id teamID, int32 *_cookie, thread_info *info,
3210 	size_t size)
3211 {
3212 	if (info == NULL || size != sizeof(thread_info) || teamID < 0)
3213 		return B_BAD_VALUE;
3214 
3215 	int32 lastID = *_cookie;
3216 
3217 	// get the team
3218 	Team* team = Team::GetAndLock(teamID);
3219 	if (team == NULL)
3220 		return B_BAD_VALUE;
3221 	BReference<Team> teamReference(team, true);
3222 	TeamLocker teamLocker(team, true);
3223 
3224 	Thread* thread = NULL;
3225 
3226 	if (lastID == 0) {
3227 		// We start with the main thread
3228 		thread = team->main_thread;
3229 	} else {
3230 		// Find the one thread with an ID greater than ours (as long as the IDs
3231 		// don't wrap they are always sorted from highest to lowest).
3232 		// TODO: That is broken not only when the IDs wrap, but also for the
3233 		// kernel team, to which threads are added when they are dying.
3234 		for (Thread* next = team->thread_list; next != NULL;
3235 				next = next->team_next) {
3236 			if (next->id <= lastID)
3237 				break;
3238 
3239 			thread = next;
3240 		}
3241 	}
3242 
3243 	if (thread == NULL)
3244 		return B_BAD_VALUE;
3245 
3246 	lastID = thread->id;
3247 	*_cookie = lastID;
3248 
3249 	ThreadLocker threadLocker(thread);
3250 	InterruptsSpinLocker locker(thread->scheduler_lock);
3251 
3252 	fill_thread_info(thread, info, size);
3253 
3254 	return B_OK;
3255 }
3256 
3257 
3258 thread_id
3259 find_thread(const char* name)
3260 {
3261 	if (name == NULL)
3262 		return thread_get_current_thread_id();
3263 
3264 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
3265 
3266 	// Scanning the whole hash with the thread hash lock held isn't exactly
3267 	// cheap, but since this function is probably used very rarely, and we
3268 	// only need a read lock, it's probably acceptable.
3269 
3270 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
3271 			Thread* thread = it.Next();) {
3272 		if (!thread->visible)
3273 			continue;
3274 
3275 		if (strcmp(thread->name, name) == 0)
3276 			return thread->id;
3277 	}
3278 
3279 	return B_NAME_NOT_FOUND;
3280 }
3281 
3282 
3283 status_t
3284 rename_thread(thread_id id, const char* name)
3285 {
3286 	if (name == NULL)
3287 		return B_BAD_VALUE;
3288 
3289 	// get the thread
3290 	Thread* thread = Thread::GetAndLock(id);
3291 	if (thread == NULL)
3292 		return B_BAD_THREAD_ID;
3293 	BReference<Thread> threadReference(thread, true);
3294 	ThreadLocker threadLocker(thread, true);
3295 
3296 	// check whether the operation is allowed
3297 	if (thread->team != thread_get_current_thread()->team)
3298 		return B_NOT_ALLOWED;
3299 
3300 	strlcpy(thread->name, name, B_OS_NAME_LENGTH);
3301 
3302 	team_id teamID = thread->team->id;
3303 
3304 	threadLocker.Unlock();
3305 
3306 	// notify listeners
3307 	sNotificationService.Notify(THREAD_NAME_CHANGED, teamID, id);
3308 		// don't pass the thread structure, as it's unsafe, if it isn't ours
3309 
3310 	return B_OK;
3311 }
3312 
3313 
3314 static status_t
3315 thread_set_thread_priority(thread_id id, int32 priority, bool kernel)
3316 {
3317 	// make sure the passed in priority is within bounds
3318 	if (priority > THREAD_MAX_SET_PRIORITY)
3319 		priority = THREAD_MAX_SET_PRIORITY;
3320 	if (priority < THREAD_MIN_SET_PRIORITY)
3321 		priority = THREAD_MIN_SET_PRIORITY;
3322 
3323 	// get the thread
3324 	Thread* thread = Thread::GetAndLock(id);
3325 	if (thread == NULL)
3326 		return B_BAD_THREAD_ID;
3327 	BReference<Thread> threadReference(thread, true);
3328 	ThreadLocker threadLocker(thread, true);
3329 
3330 	// check whether the change is allowed
3331 	if (thread_is_idle_thread(thread) || !thread_check_permissions(
3332 			thread_get_current_thread(), thread, kernel))
3333 		return B_NOT_ALLOWED;
3334 
3335 	return scheduler_set_thread_priority(thread, priority);
3336 }
3337 
3338 
3339 status_t
3340 set_thread_priority(thread_id id, int32 priority)
3341 {
3342 	return thread_set_thread_priority(id, priority, true);
3343 }
3344 
3345 
3346 status_t
3347 snooze_etc(bigtime_t timeout, int timebase, uint32 flags)
3348 {
3349 	return common_snooze_etc(timeout, timebase, flags, NULL);
3350 }
3351 
3352 
3353 /*!	snooze() for internal kernel use only; doesn't interrupt on signals. */
3354 status_t
3355 snooze(bigtime_t timeout)
3356 {
3357 	return snooze_etc(timeout, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT);
3358 }
3359 
3360 
3361 /*!	snooze_until() for internal kernel use only; doesn't interrupt on
3362 	signals.
3363 */
3364 status_t
3365 snooze_until(bigtime_t timeout, int timebase)
3366 {
3367 	return snooze_etc(timeout, timebase, B_ABSOLUTE_TIMEOUT);
3368 }
3369 
3370 
3371 status_t
3372 wait_for_thread(thread_id thread, status_t *_returnCode)
3373 {
3374 	return wait_for_thread_etc(thread, 0, 0, _returnCode);
3375 }
3376 
3377 
3378 static status_t
3379 thread_suspend_thread(thread_id id, bool kernel)
3380 {
3381 	return thread_send_signal(id, SIGSTOP, SI_USER, B_OK, kernel);
3382 }
3383 
3384 
3385 status_t
3386 suspend_thread(thread_id id)
3387 {
3388 	return thread_suspend_thread(id, true);
3389 }
3390 
3391 
3392 static status_t
3393 thread_resume_thread(thread_id id, bool kernel)
3394 {
3395 	// Using the kernel internal SIGNAL_CONTINUE_THREAD signal retains
3396 	// compatibility to BeOS which documents the combination of suspend_thread()
3397 	// and resume_thread() to interrupt threads waiting on semaphores.
3398 	return thread_send_signal(id, SIGNAL_CONTINUE_THREAD, SI_USER, B_OK, kernel);
3399 }
3400 
3401 
3402 status_t
3403 resume_thread(thread_id id)
3404 {
3405 	return thread_resume_thread(id, true);
3406 }
3407 
3408 
3409 thread_id
3410 spawn_kernel_thread(thread_func function, const char *name, int32 priority,
3411 	void *arg)
3412 {
3413 	return thread_create_thread(
3414 		ThreadCreationAttributes(function, name, priority, arg),
3415 		true);
3416 }
3417 
3418 
3419 int
3420 getrlimit(int resource, struct rlimit * rlp)
3421 {
3422 	status_t error = common_getrlimit(resource, rlp);
3423 	if (error != B_OK) {
3424 		errno = error;
3425 		return -1;
3426 	}
3427 
3428 	return 0;
3429 }
3430 
3431 
3432 int
3433 setrlimit(int resource, const struct rlimit * rlp)
3434 {
3435 	status_t error = common_setrlimit(resource, rlp);
3436 	if (error != B_OK) {
3437 		errno = error;
3438 		return -1;
3439 	}
3440 
3441 	return 0;
3442 }
3443 
3444 
3445 //	#pragma mark - syscalls
3446 
3447 
3448 void
3449 _user_exit_thread(status_t returnValue)
3450 {
3451 	exit_thread(returnValue);
3452 }
3453 
3454 
3455 status_t
3456 _user_kill_thread(thread_id thread)
3457 {
3458 	return thread_kill_thread(thread, false);
3459 }
3460 
3461 
3462 status_t
3463 _user_cancel_thread(thread_id threadID, void (*cancelFunction)(int))
3464 {
3465 	// check the cancel function
3466 	if (cancelFunction == NULL || !IS_USER_ADDRESS(cancelFunction))
3467 		return B_BAD_VALUE;
3468 
3469 	// get and lock the thread
3470 	Thread* thread = Thread::GetAndLock(threadID);
3471 	if (thread == NULL)
3472 		return B_BAD_THREAD_ID;
3473 	BReference<Thread> threadReference(thread, true);
3474 	ThreadLocker threadLocker(thread, true);
3475 
3476 	// only threads of the same team can be canceled
3477 	if (thread->team != thread_get_current_thread()->team)
3478 		return B_NOT_ALLOWED;
3479 
3480 	// set the cancel function
3481 	thread->cancel_function = cancelFunction;
3482 
3483 	// send the cancellation signal to the thread
3484 	InterruptsReadSpinLocker teamLocker(thread->team_lock);
3485 	SpinLocker locker(thread->team->signal_lock);
3486 	return send_signal_to_thread_locked(thread, SIGNAL_CANCEL_THREAD, NULL, 0);
3487 }
3488 
3489 
3490 status_t
3491 _user_resume_thread(thread_id thread)
3492 {
3493 	return thread_resume_thread(thread, false);
3494 }
3495 
3496 
3497 status_t
3498 _user_suspend_thread(thread_id thread)
3499 {
3500 	return thread_suspend_thread(thread, false);
3501 }
3502 
3503 
3504 status_t
3505 _user_rename_thread(thread_id thread, const char *userName)
3506 {
3507 	char name[B_OS_NAME_LENGTH];
3508 
3509 	if (!IS_USER_ADDRESS(userName)
3510 		|| userName == NULL
3511 		|| user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK)
3512 		return B_BAD_ADDRESS;
3513 
3514 	// rename_thread() forbids thread renames across teams, so we don't
3515 	// need a "kernel" flag here.
3516 	return rename_thread(thread, name);
3517 }
3518 
3519 
3520 int32
3521 _user_set_thread_priority(thread_id thread, int32 newPriority)
3522 {
3523 	return thread_set_thread_priority(thread, newPriority, false);
3524 }
3525 
3526 
3527 thread_id
3528 _user_spawn_thread(thread_creation_attributes* userAttributes)
3529 {
3530 	// copy the userland structure to the kernel
3531 	char nameBuffer[B_OS_NAME_LENGTH];
3532 	ThreadCreationAttributes attributes;
3533 	status_t error = attributes.InitFromUserAttributes(userAttributes,
3534 		nameBuffer);
3535 	if (error != B_OK)
3536 		return error;
3537 
3538 	// create the thread
3539 	thread_id threadID = thread_create_thread(attributes, false);
3540 
3541 	if (threadID >= 0)
3542 		user_debug_thread_created(threadID);
3543 
3544 	return threadID;
3545 }
3546 
3547 
3548 status_t
3549 _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags,
3550 	bigtime_t* userRemainingTime)
3551 {
3552 	// We need to store more syscall restart parameters than usual and need a
3553 	// somewhat different handling. Hence we can't use
3554 	// syscall_restart_handle_timeout_pre() but do the job ourselves.
3555 	struct restart_parameters {
3556 		bigtime_t	timeout;
3557 		clockid_t	timebase;
3558 		uint32		flags;
3559 	};
3560 
3561 	Thread* thread = thread_get_current_thread();
3562 
3563 	if ((thread->flags & THREAD_FLAGS_SYSCALL_RESTARTED) != 0) {
3564 		// The syscall was restarted. Fetch the parameters from the stored
3565 		// restart parameters.
3566 		restart_parameters* restartParameters
3567 			= (restart_parameters*)thread->syscall_restart.parameters;
3568 		timeout = restartParameters->timeout;
3569 		timebase = restartParameters->timebase;
3570 		flags = restartParameters->flags;
3571 	} else {
3572 		// convert relative timeouts to absolute ones
3573 		if ((flags & B_RELATIVE_TIMEOUT) != 0) {
3574 			// not restarted yet and the flags indicate a relative timeout
3575 
3576 			// Make sure we use the system time base, so real-time clock changes
3577 			// won't affect our wait.
3578 			flags &= ~(uint32)B_TIMEOUT_REAL_TIME_BASE;
3579 			if (timebase == CLOCK_REALTIME)
3580 				timebase = CLOCK_MONOTONIC;
3581 
3582 			// get the current time and make the timeout absolute
3583 			bigtime_t now;
3584 			status_t error = user_timer_get_clock(timebase, now);
3585 			if (error != B_OK)
3586 				return error;
3587 
3588 			timeout += now;
3589 
3590 			// deal with overflow
3591 			if (timeout < 0)
3592 				timeout = B_INFINITE_TIMEOUT;
3593 
3594 			flags = (flags & ~B_RELATIVE_TIMEOUT) | B_ABSOLUTE_TIMEOUT;
3595 		} else
3596 			flags |= B_ABSOLUTE_TIMEOUT;
3597 	}
3598 
3599 	// snooze
3600 	bigtime_t remainingTime;
3601 	status_t error = common_snooze_etc(timeout, timebase,
3602 		flags | B_CAN_INTERRUPT | B_CHECK_PERMISSION,
3603 		userRemainingTime != NULL ? &remainingTime : NULL);
3604 
3605 	// If interrupted, copy the remaining time back to userland and prepare the
3606 	// syscall restart.
3607 	if (error == B_INTERRUPTED) {
3608 		if (userRemainingTime != NULL
3609 			&& (!IS_USER_ADDRESS(userRemainingTime)
3610 				|| user_memcpy(userRemainingTime, &remainingTime,
3611 					sizeof(remainingTime)) != B_OK)) {
3612 			return B_BAD_ADDRESS;
3613 		}
3614 
3615 		// store the normalized values in the restart parameters
3616 		restart_parameters* restartParameters
3617 			= (restart_parameters*)thread->syscall_restart.parameters;
3618 		restartParameters->timeout = timeout;
3619 		restartParameters->timebase = timebase;
3620 		restartParameters->flags = flags;
3621 
3622 		// restart the syscall, if possible
3623 		atomic_or(&thread->flags, THREAD_FLAGS_RESTART_SYSCALL);
3624 	}
3625 
3626 	return error;
3627 }
3628 
3629 
3630 void
3631 _user_thread_yield(void)
3632 {
3633 	thread_yield();
3634 }
3635 
3636 
3637 status_t
3638 _user_get_thread_info(thread_id id, thread_info *userInfo)
3639 {
3640 	thread_info info;
3641 	status_t status;
3642 
3643 	if (!IS_USER_ADDRESS(userInfo))
3644 		return B_BAD_ADDRESS;
3645 
3646 	status = _get_thread_info(id, &info, sizeof(thread_info));
3647 
3648 	if (status >= B_OK
3649 		&& user_memcpy(userInfo, &info, sizeof(thread_info)) < B_OK)
3650 		return B_BAD_ADDRESS;
3651 
3652 	return status;
3653 }
3654 
3655 
3656 status_t
3657 _user_get_next_thread_info(team_id team, int32 *userCookie,
3658 	thread_info *userInfo)
3659 {
3660 	status_t status;
3661 	thread_info info;
3662 	int32 cookie;
3663 
3664 	if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo)
3665 		|| user_memcpy(&cookie, userCookie, sizeof(int32)) < B_OK)
3666 		return B_BAD_ADDRESS;
3667 
3668 	status = _get_next_thread_info(team, &cookie, &info, sizeof(thread_info));
3669 	if (status < B_OK)
3670 		return status;
3671 
3672 	if (user_memcpy(userCookie, &cookie, sizeof(int32)) < B_OK
3673 		|| user_memcpy(userInfo, &info, sizeof(thread_info)) < B_OK)
3674 		return B_BAD_ADDRESS;
3675 
3676 	return status;
3677 }
3678 
3679 
3680 thread_id
3681 _user_find_thread(const char *userName)
3682 {
3683 	char name[B_OS_NAME_LENGTH];
3684 
3685 	if (userName == NULL)
3686 		return find_thread(NULL);
3687 
3688 	if (!IS_USER_ADDRESS(userName)
3689 		|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
3690 		return B_BAD_ADDRESS;
3691 
3692 	return find_thread(name);
3693 }
3694 
3695 
3696 status_t
3697 _user_wait_for_thread(thread_id id, status_t *userReturnCode)
3698 {
3699 	status_t returnCode;
3700 	status_t status;
3701 
3702 	if (userReturnCode != NULL && !IS_USER_ADDRESS(userReturnCode))
3703 		return B_BAD_ADDRESS;
3704 
3705 	status = wait_for_thread_etc(id, B_CAN_INTERRUPT, 0, &returnCode);
3706 
3707 	if (status == B_OK && userReturnCode != NULL
3708 		&& user_memcpy(userReturnCode, &returnCode, sizeof(status_t)) < B_OK) {
3709 		return B_BAD_ADDRESS;
3710 	}
3711 
3712 	return syscall_restart_handle_post(status);
3713 }
3714 
3715 
3716 status_t
3717 _user_wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, status_t *userReturnCode)
3718 {
3719 	status_t returnCode;
3720 	status_t status;
3721 
3722 	if (userReturnCode != NULL && !IS_USER_ADDRESS(userReturnCode))
3723 		return B_BAD_ADDRESS;
3724 
3725 	syscall_restart_handle_timeout_pre(flags, timeout);
3726 
3727 	status = wait_for_thread_etc(id, flags | B_CAN_INTERRUPT, timeout, &returnCode);
3728 
3729 	if (status == B_OK && userReturnCode != NULL
3730 		&& user_memcpy(userReturnCode, &returnCode, sizeof(status_t)) < B_OK) {
3731 		return B_BAD_ADDRESS;
3732 	}
3733 
3734 	return syscall_restart_handle_timeout_post(status, timeout);
3735 }
3736 
3737 
3738 bool
3739 _user_has_data(thread_id thread)
3740 {
3741 	return thread_has_data(thread, false);
3742 }
3743 
3744 
3745 status_t
3746 _user_send_data(thread_id thread, int32 code, const void *buffer,
3747 	size_t bufferSize)
3748 {
3749 	if (buffer != NULL && !IS_USER_ADDRESS(buffer))
3750 		return B_BAD_ADDRESS;
3751 
3752 	return send_data_etc(thread, code, buffer, bufferSize,
3753 		B_KILL_CAN_INTERRUPT);
3754 		// supports userland buffers
3755 }
3756 
3757 
3758 status_t
3759 _user_receive_data(thread_id *_userSender, void *buffer, size_t bufferSize)
3760 {
3761 	thread_id sender;
3762 	status_t code;
3763 
3764 	if ((!IS_USER_ADDRESS(_userSender) && _userSender != NULL)
3765 		|| (!IS_USER_ADDRESS(buffer) && buffer != NULL)) {
3766 		return B_BAD_ADDRESS;
3767 	}
3768 
3769 	code = receive_data_etc(&sender, buffer, bufferSize, B_KILL_CAN_INTERRUPT);
3770 		// supports userland buffers
3771 
3772 	if (_userSender != NULL)
3773 		if (user_memcpy(_userSender, &sender, sizeof(thread_id)) < B_OK)
3774 			return B_BAD_ADDRESS;
3775 
3776 	return code;
3777 }
3778 
3779 
3780 status_t
3781 _user_block_thread(uint32 flags, bigtime_t timeout)
3782 {
3783 	syscall_restart_handle_timeout_pre(flags, timeout);
3784 	flags |= B_CAN_INTERRUPT;
3785 
3786 	Thread* thread = thread_get_current_thread();
3787 	ThreadLocker threadLocker(thread);
3788 
3789 	// check, if already done
3790 	status_t waitStatus;
3791 	if (user_memcpy(&waitStatus, &thread->user_thread->wait_status,
3792 			sizeof(waitStatus)) < B_OK) {
3793 		return B_BAD_ADDRESS;
3794 	}
3795 	if (waitStatus <= 0)
3796 		return waitStatus;
3797 
3798 	// nope, so wait
3799 	thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_USER, NULL);
3800 
3801 	threadLocker.Unlock();
3802 
3803 	status_t status = thread_block_with_timeout(flags, timeout);
3804 
3805 	threadLocker.Lock();
3806 
3807 	// Interruptions or timeouts can race with other threads unblocking us.
3808 	// Favor a wake-up by another thread, i.e. if someone changed the wait
3809 	// status, use that.
3810 	status_t oldStatus;
3811 	if (user_memcpy(&oldStatus, &thread->user_thread->wait_status,
3812 		sizeof(oldStatus)) < B_OK) {
3813 		return B_BAD_ADDRESS;
3814 	}
3815 	if (oldStatus > 0) {
3816 		if (user_memcpy(&thread->user_thread->wait_status, &status,
3817 				sizeof(status)) < B_OK) {
3818 			return B_BAD_ADDRESS;
3819 		}
3820 	} else {
3821 		status = oldStatus;
3822 	}
3823 
3824 	threadLocker.Unlock();
3825 
3826 	return syscall_restart_handle_timeout_post(status, timeout);
3827 }
3828 
3829 
3830 status_t
3831 _user_unblock_thread(thread_id threadID, status_t status)
3832 {
3833 	status_t error = user_unblock_thread(threadID, status);
3834 
3835 	if (error == B_OK)
3836 		scheduler_reschedule_if_necessary();
3837 
3838 	return error;
3839 }
3840 
3841 
3842 status_t
3843 _user_unblock_threads(thread_id* userThreads, uint32 count, status_t status)
3844 {
3845 	enum {
3846 		MAX_USER_THREADS_TO_UNBLOCK	= 128
3847 	};
3848 
3849 	if (userThreads == NULL || !IS_USER_ADDRESS(userThreads))
3850 		return B_BAD_ADDRESS;
3851 	if (count > MAX_USER_THREADS_TO_UNBLOCK)
3852 		return B_BAD_VALUE;
3853 
3854 	thread_id threads[MAX_USER_THREADS_TO_UNBLOCK];
3855 	if (user_memcpy(threads, userThreads, count * sizeof(thread_id)) != B_OK)
3856 		return B_BAD_ADDRESS;
3857 
3858 	for (uint32 i = 0; i < count; i++)
3859 		user_unblock_thread(threads[i], status);
3860 
3861 	scheduler_reschedule_if_necessary();
3862 
3863 	return B_OK;
3864 }
3865 
3866 
3867 // TODO: the following two functions don't belong here
3868 
3869 
3870 int
3871 _user_getrlimit(int resource, struct rlimit *urlp)
3872 {
3873 	struct rlimit rl;
3874 	int ret;
3875 
3876 	if (urlp == NULL)
3877 		return EINVAL;
3878 
3879 	if (!IS_USER_ADDRESS(urlp))
3880 		return B_BAD_ADDRESS;
3881 
3882 	ret = common_getrlimit(resource, &rl);
3883 
3884 	if (ret == 0) {
3885 		ret = user_memcpy(urlp, &rl, sizeof(struct rlimit));
3886 		if (ret < 0)
3887 			return ret;
3888 
3889 		return 0;
3890 	}
3891 
3892 	return ret;
3893 }
3894 
3895 
3896 int
3897 _user_setrlimit(int resource, const struct rlimit *userResourceLimit)
3898 {
3899 	struct rlimit resourceLimit;
3900 
3901 	if (userResourceLimit == NULL)
3902 		return EINVAL;
3903 
3904 	if (!IS_USER_ADDRESS(userResourceLimit)
3905 		|| user_memcpy(&resourceLimit, userResourceLimit,
3906 			sizeof(struct rlimit)) < B_OK)
3907 		return B_BAD_ADDRESS;
3908 
3909 	return common_setrlimit(resource, &resourceLimit);
3910 }
3911