xref: /haiku/src/system/kernel/thread.cpp (revision f18d2effbf60ff70fc6ba02f57da02e7c70993b7)
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 					kprintf("cvar      %p   ", thread->wait.object);
1705 					break;
1706 
1707 				case THREAD_BLOCK_TYPE_SNOOZE:
1708 					kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, "");
1709 					break;
1710 
1711 				case THREAD_BLOCK_TYPE_SIGNAL:
1712 					kprintf("signal%*s", B_PRINTF_POINTER_WIDTH + 9, "");
1713 					break;
1714 
1715 				case THREAD_BLOCK_TYPE_MUTEX:
1716 					kprintf("mutex     %p   ", thread->wait.object);
1717 					break;
1718 
1719 				case THREAD_BLOCK_TYPE_RW_LOCK:
1720 					kprintf("rwlock    %p   ", thread->wait.object);
1721 					break;
1722 
1723 				case THREAD_BLOCK_TYPE_USER:
1724 					kprintf("user%*s", B_PRINTF_POINTER_WIDTH + 11, "");
1725 					break;
1726 
1727 				case THREAD_BLOCK_TYPE_OTHER:
1728 					kprintf("other%*s", B_PRINTF_POINTER_WIDTH + 10, "");
1729 					break;
1730 
1731 				case THREAD_BLOCK_TYPE_OTHER_OBJECT:
1732 					kprintf("other     %p   ", thread->wait.object);
1733 					break;
1734 
1735 				default:
1736 					kprintf("???       %p   ", thread->wait.object);
1737 					break;
1738 			}
1739 		} else
1740 			kprintf("-%*s", B_PRINTF_POINTER_WIDTH + 14, "");
1741 
1742 		// on which CPU does it run?
1743 		if (thread->cpu)
1744 			kprintf("%2d", thread->cpu->cpu_num);
1745 		else
1746 			kprintf(" -");
1747 
1748 		kprintf("%4" B_PRId32 "  %p%5" B_PRId32 "  %s\n", thread->priority,
1749 			(void *)thread->kernel_stack_base, thread->team->id, thread->name);
1750 
1751 		return;
1752 	}
1753 
1754 	// print the long info
1755 
1756 	struct thread_death_entry *death = NULL;
1757 
1758 	kprintf("THREAD: %p\n", thread);
1759 	kprintf("id:                 %" B_PRId32 " (%#" B_PRIx32 ")\n", thread->id,
1760 		thread->id);
1761 	kprintf("serial_number:      %" B_PRId64 "\n", thread->serial_number);
1762 	kprintf("name:               \"%s\"\n", thread->name);
1763 	kprintf("hash_next:          %p\nteam_next:          %p\n",
1764 		thread->hash_next, thread->team_next);
1765 	kprintf("priority:           %" B_PRId32 " (I/O: %" B_PRId32 ")\n",
1766 		thread->priority, thread->io_priority);
1767 	kprintf("state:              %s\n", state_to_text(thread, thread->state));
1768 	kprintf("cpu:                %p ", thread->cpu);
1769 	if (thread->cpu)
1770 		kprintf("(%d)\n", thread->cpu->cpu_num);
1771 	else
1772 		kprintf("\n");
1773 	kprintf("sig_pending:        %#" B_PRIx64 " (blocked: %#" B_PRIx64
1774 		", before sigsuspend(): %#" B_PRIx64 ")\n",
1775 		(int64)thread->ThreadPendingSignals(),
1776 		(int64)thread->sig_block_mask,
1777 		(int64)thread->sigsuspend_original_unblocked_mask);
1778 	kprintf("in_kernel:          %d\n", thread->in_kernel);
1779 
1780 	if (thread->state == B_THREAD_WAITING) {
1781 		kprintf("waiting for:        ");
1782 
1783 		switch (thread->wait.type) {
1784 			case THREAD_BLOCK_TYPE_SEMAPHORE:
1785 			{
1786 				sem_id sem = (sem_id)(addr_t)thread->wait.object;
1787 				if (sem == thread->msg.read_sem)
1788 					kprintf("data\n");
1789 				else
1790 					kprintf("semaphore %" B_PRId32 "\n", sem);
1791 				break;
1792 			}
1793 
1794 			case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1795 				kprintf("condition variable %p\n", thread->wait.object);
1796 				break;
1797 
1798 			case THREAD_BLOCK_TYPE_SNOOZE:
1799 				kprintf("snooze()\n");
1800 				break;
1801 
1802 			case THREAD_BLOCK_TYPE_SIGNAL:
1803 				kprintf("signal\n");
1804 				break;
1805 
1806 			case THREAD_BLOCK_TYPE_MUTEX:
1807 				kprintf("mutex %p\n", thread->wait.object);
1808 				break;
1809 
1810 			case THREAD_BLOCK_TYPE_RW_LOCK:
1811 				kprintf("rwlock %p\n", thread->wait.object);
1812 				break;
1813 
1814 			case THREAD_BLOCK_TYPE_USER:
1815 				kprintf("user\n");
1816 				break;
1817 
1818 			case THREAD_BLOCK_TYPE_OTHER:
1819 				kprintf("other (%s)\n", (char*)thread->wait.object);
1820 				break;
1821 
1822 			case THREAD_BLOCK_TYPE_OTHER_OBJECT:
1823 				kprintf("other (%p)\n", thread->wait.object);
1824 				break;
1825 
1826 			default:
1827 				kprintf("unknown (%p)\n", thread->wait.object);
1828 				break;
1829 		}
1830 	}
1831 
1832 	kprintf("fault_handler:      %p\n", (void *)thread->fault_handler);
1833 	kprintf("team:               %p, \"%s\"\n", thread->team,
1834 		thread->team->Name());
1835 	kprintf("  exit.sem:         %" B_PRId32 "\n", thread->exit.sem);
1836 	kprintf("  exit.status:      %#" B_PRIx32 " (%s)\n", thread->exit.status,
1837 		strerror(thread->exit.status));
1838 	kprintf("  exit.waiters:\n");
1839 	while ((death = (struct thread_death_entry*)list_get_next_item(
1840 			&thread->exit.waiters, death)) != NULL) {
1841 		kprintf("\t%p (thread %" B_PRId32 ")\n", death, death->thread);
1842 	}
1843 
1844 	kprintf("kernel_stack_area:  %" B_PRId32 "\n", thread->kernel_stack_area);
1845 	kprintf("kernel_stack_base:  %p\n", (void *)thread->kernel_stack_base);
1846 	kprintf("user_stack_area:    %" B_PRId32 "\n", thread->user_stack_area);
1847 	kprintf("user_stack_base:    %p\n", (void *)thread->user_stack_base);
1848 	kprintf("user_local_storage: %p\n", (void *)thread->user_local_storage);
1849 	kprintf("user_thread:        %p\n", (void *)thread->user_thread);
1850 	kprintf("kernel_errno:       %#x (%s)\n", thread->kernel_errno,
1851 		strerror(thread->kernel_errno));
1852 	kprintf("kernel_time:        %" B_PRId64 "\n", thread->kernel_time);
1853 	kprintf("user_time:          %" B_PRId64 "\n", thread->user_time);
1854 	kprintf("flags:              0x%" B_PRIx32 "\n", thread->flags);
1855 	kprintf("architecture dependant section:\n");
1856 	arch_thread_dump_info(&thread->arch_info);
1857 	kprintf("scheduler data:\n");
1858 	scheduler_dump_thread_data(thread);
1859 }
1860 
1861 
1862 static int
1863 dump_thread_info(int argc, char **argv)
1864 {
1865 	bool shortInfo = false;
1866 	int argi = 1;
1867 	if (argi < argc && strcmp(argv[argi], "-s") == 0) {
1868 		shortInfo = true;
1869 		print_thread_list_table_head();
1870 		argi++;
1871 	}
1872 
1873 	if (argi == argc) {
1874 		_dump_thread_info(thread_get_current_thread(), shortInfo);
1875 		return 0;
1876 	}
1877 
1878 	for (; argi < argc; argi++) {
1879 		const char *name = argv[argi];
1880 		ulong arg = strtoul(name, NULL, 0);
1881 
1882 		if (IS_KERNEL_ADDRESS(arg)) {
1883 			// semi-hack
1884 			_dump_thread_info((Thread *)arg, shortInfo);
1885 			continue;
1886 		}
1887 
1888 		// walk through the thread list, trying to match name or id
1889 		bool found = false;
1890 		for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1891 				Thread* thread = it.Next();) {
1892 			if (!strcmp(name, thread->name) || thread->id == (thread_id)arg) {
1893 				_dump_thread_info(thread, shortInfo);
1894 				found = true;
1895 				break;
1896 			}
1897 		}
1898 
1899 		if (!found)
1900 			kprintf("thread \"%s\" (%" B_PRId32 ") doesn't exist!\n", name, (thread_id)arg);
1901 	}
1902 
1903 	return 0;
1904 }
1905 
1906 
1907 static int
1908 dump_thread_list(int argc, char **argv)
1909 {
1910 	bool realTimeOnly = false;
1911 	bool calling = false;
1912 	const char *callSymbol = NULL;
1913 	addr_t callStart = 0;
1914 	addr_t callEnd = 0;
1915 	int32 requiredState = 0;
1916 	team_id team = -1;
1917 	sem_id sem = -1;
1918 
1919 	if (!strcmp(argv[0], "realtime"))
1920 		realTimeOnly = true;
1921 	else if (!strcmp(argv[0], "ready"))
1922 		requiredState = B_THREAD_READY;
1923 	else if (!strcmp(argv[0], "running"))
1924 		requiredState = B_THREAD_RUNNING;
1925 	else if (!strcmp(argv[0], "waiting")) {
1926 		requiredState = B_THREAD_WAITING;
1927 
1928 		if (argc > 1) {
1929 			sem = strtoul(argv[1], NULL, 0);
1930 			if (sem == 0)
1931 				kprintf("ignoring invalid semaphore argument.\n");
1932 		}
1933 	} else if (!strcmp(argv[0], "calling")) {
1934 		if (argc < 2) {
1935 			kprintf("Need to give a symbol name or start and end arguments.\n");
1936 			return 0;
1937 		} else if (argc == 3) {
1938 			callStart = parse_expression(argv[1]);
1939 			callEnd = parse_expression(argv[2]);
1940 		} else
1941 			callSymbol = argv[1];
1942 
1943 		calling = true;
1944 	} else if (argc > 1) {
1945 		team = strtoul(argv[1], NULL, 0);
1946 		if (team == 0)
1947 			kprintf("ignoring invalid team argument.\n");
1948 	}
1949 
1950 	print_thread_list_table_head();
1951 
1952 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1953 			Thread* thread = it.Next();) {
1954 		// filter out threads not matching the search criteria
1955 		if ((requiredState && thread->state != requiredState)
1956 			|| (calling && !arch_debug_contains_call(thread, callSymbol,
1957 					callStart, callEnd))
1958 			|| (sem > 0 && get_thread_wait_sem(thread) != sem)
1959 			|| (team > 0 && thread->team->id != team)
1960 			|| (realTimeOnly && thread->priority < B_REAL_TIME_DISPLAY_PRIORITY))
1961 			continue;
1962 
1963 		_dump_thread_info(thread, true);
1964 	}
1965 	return 0;
1966 }
1967 
1968 
1969 static void
1970 update_thread_sigmask_on_exit(Thread* thread)
1971 {
1972 	if ((thread->flags & THREAD_FLAGS_OLD_SIGMASK) != 0) {
1973 		thread->flags &= ~THREAD_FLAGS_OLD_SIGMASK;
1974 		sigprocmask(SIG_SETMASK, &thread->old_sig_block_mask, NULL);
1975 	}
1976 }
1977 
1978 
1979 //	#pragma mark - private kernel API
1980 
1981 
1982 void
1983 thread_exit(void)
1984 {
1985 	cpu_status state;
1986 	Thread* thread = thread_get_current_thread();
1987 	Team* team = thread->team;
1988 	Team* kernelTeam = team_get_kernel_team();
1989 	status_t status;
1990 	struct thread_debug_info debugInfo;
1991 	team_id teamID = team->id;
1992 
1993 	TRACE(("thread %" B_PRId32 " exiting w/return code %#" B_PRIx32 "\n",
1994 		thread->id, thread->exit.status));
1995 
1996 	if (!are_interrupts_enabled())
1997 		panic("thread_exit() called with interrupts disabled!\n");
1998 
1999 	// boost our priority to get this over with
2000 	scheduler_set_thread_priority(thread, B_URGENT_DISPLAY_PRIORITY);
2001 
2002 	if (team != kernelTeam) {
2003 		// Delete all user timers associated with the thread.
2004 		ThreadLocker threadLocker(thread);
2005 		thread->DeleteUserTimers(false);
2006 
2007 		// detach the thread's user thread
2008 		user_thread* userThread = thread->user_thread;
2009 		thread->user_thread = NULL;
2010 
2011 		threadLocker.Unlock();
2012 
2013 		// Delete the thread's user thread, if it's not the main thread. If it
2014 		// is, we can save the work, since it will be deleted with the team's
2015 		// address space.
2016 		if (thread != team->main_thread)
2017 			team_free_user_thread(team, userThread);
2018 	}
2019 
2020 	// remember the user stack area -- we will delete it below
2021 	area_id userStackArea = -1;
2022 	if (team->address_space != NULL && thread->user_stack_area >= 0) {
2023 		userStackArea = thread->user_stack_area;
2024 		thread->user_stack_area = -1;
2025 	}
2026 
2027 	struct job_control_entry *death = NULL;
2028 	struct thread_death_entry* threadDeathEntry = NULL;
2029 	bool deleteTeam = false;
2030 	port_id debuggerPort = -1;
2031 
2032 	if (team != kernelTeam) {
2033 		user_debug_thread_exiting(thread);
2034 
2035 		if (team->main_thread == thread) {
2036 			// The main thread is exiting. Shut down the whole team.
2037 			deleteTeam = true;
2038 
2039 			// kill off all other threads and the user debugger facilities
2040 			debuggerPort = team_shutdown_team(team);
2041 
2042 			// acquire necessary locks, which are: process group lock, kernel
2043 			// team lock, parent team lock, and the team lock
2044 			team->LockProcessGroup();
2045 			kernelTeam->Lock();
2046 			team->LockTeamAndParent(true);
2047 		} else {
2048 			threadDeathEntry
2049 				= (thread_death_entry*)malloc(sizeof(thread_death_entry));
2050 
2051 			// acquire necessary locks, which are: kernel team lock and the team
2052 			// lock
2053 			kernelTeam->Lock();
2054 			team->Lock();
2055 		}
2056 
2057 		ThreadLocker threadLocker(thread);
2058 
2059 		state = disable_interrupts();
2060 
2061 		// swap address spaces, to make sure we're running on the kernel's pgdir
2062 		vm_swap_address_space(team->address_space, VMAddressSpace::Kernel());
2063 
2064 		WriteSpinLocker teamLocker(thread->team_lock);
2065 		SpinLocker threadCreationLocker(gThreadCreationLock);
2066 			// removing the thread and putting its death entry to the parent
2067 			// team needs to be an atomic operation
2068 
2069 		// remember how long this thread lasted
2070 		bigtime_t now = system_time();
2071 
2072 		InterruptsSpinLocker signalLocker(kernelTeam->signal_lock);
2073 		SpinLocker teamTimeLocker(kernelTeam->time_lock);
2074 		SpinLocker threadTimeLocker(thread->time_lock);
2075 
2076 		thread->kernel_time += now - thread->last_time;
2077 		thread->last_time = now;
2078 
2079 		team->dead_threads_kernel_time += thread->kernel_time;
2080 		team->dead_threads_user_time += thread->user_time;
2081 
2082 		// stop/update thread/team CPU time user timers
2083 		if (thread->HasActiveCPUTimeUserTimers()
2084 			|| team->HasActiveCPUTimeUserTimers()) {
2085 			user_timer_stop_cpu_timers(thread, NULL);
2086 		}
2087 
2088 		// deactivate CPU time user timers for the thread
2089 		if (thread->HasActiveCPUTimeUserTimers())
2090 			thread->DeactivateCPUTimeUserTimers();
2091 
2092 		threadTimeLocker.Unlock();
2093 
2094 		// put the thread into the kernel team until it dies
2095 		remove_thread_from_team(team, thread);
2096 		insert_thread_into_team(kernelTeam, thread);
2097 
2098 		teamTimeLocker.Unlock();
2099 		signalLocker.Unlock();
2100 
2101 		teamLocker.Unlock();
2102 
2103 		if (team->death_entry != NULL) {
2104 			if (--team->death_entry->remaining_threads == 0)
2105 				team->death_entry->condition.NotifyOne();
2106 		}
2107 
2108 		if (deleteTeam) {
2109 			Team* parent = team->parent;
2110 
2111 			// Set the team job control state to "dead" and detach the job
2112 			// control entry from our team struct.
2113 			team_set_job_control_state(team, JOB_CONTROL_STATE_DEAD, NULL);
2114 			death = team->job_control_entry;
2115 			team->job_control_entry = NULL;
2116 
2117 			if (death != NULL) {
2118 				death->InitDeadState();
2119 
2120 				// team_set_job_control_state() already moved our entry
2121 				// into the parent's list. We just check the soft limit of
2122 				// death entries.
2123 				if (parent->dead_children.count > MAX_DEAD_CHILDREN) {
2124 					death = parent->dead_children.entries.RemoveHead();
2125 					parent->dead_children.count--;
2126 				} else
2127 					death = NULL;
2128 			}
2129 
2130 			threadCreationLocker.Unlock();
2131 			restore_interrupts(state);
2132 
2133 			threadLocker.Unlock();
2134 
2135 			// Get a temporary reference to the team's process group
2136 			// -- team_remove_team() removes the team from the group, which
2137 			// might destroy it otherwise and we wouldn't be able to unlock it.
2138 			ProcessGroup* group = team->group;
2139 			group->AcquireReference();
2140 
2141 			pid_t foregroundGroupToSignal;
2142 			team_remove_team(team, foregroundGroupToSignal);
2143 
2144 			// unlock everything but the parent team
2145 			team->Unlock();
2146 			if (parent != kernelTeam)
2147 				kernelTeam->Unlock();
2148 			group->Unlock();
2149 			group->ReleaseReference();
2150 
2151 			// Send SIGCHLD to the parent as long as we still have its lock.
2152 			// This makes job control state change + signalling atomic.
2153 			Signal childSignal(SIGCHLD, team->exit.reason, B_OK, team->id);
2154 			if (team->exit.reason == CLD_EXITED) {
2155 				childSignal.SetStatus(team->exit.status);
2156 			} else {
2157 				childSignal.SetStatus(team->exit.signal);
2158 				childSignal.SetSendingUser(team->exit.signaling_user);
2159 			}
2160 			send_signal_to_team(parent, childSignal, B_DO_NOT_RESCHEDULE);
2161 
2162 			// also unlock the parent
2163 			parent->Unlock();
2164 
2165 			// If the team was a session leader with controlling TTY, we have
2166 			// to send SIGHUP to the foreground process group.
2167 			if (foregroundGroupToSignal >= 0) {
2168 				Signal groupSignal(SIGHUP, SI_USER, B_OK, team->id);
2169 				send_signal_to_process_group(foregroundGroupToSignal,
2170 					groupSignal, B_DO_NOT_RESCHEDULE);
2171 			}
2172 		} else {
2173 			// The thread is not the main thread. We store a thread death entry
2174 			// for it, unless someone is already waiting for it.
2175 			if (threadDeathEntry != NULL
2176 				&& list_is_empty(&thread->exit.waiters)) {
2177 				threadDeathEntry->thread = thread->id;
2178 				threadDeathEntry->status = thread->exit.status;
2179 
2180 				// add entry to dead thread list
2181 				list_add_item(&team->dead_threads, threadDeathEntry);
2182 			}
2183 
2184 			threadCreationLocker.Unlock();
2185 			restore_interrupts(state);
2186 
2187 			threadLocker.Unlock();
2188 			team->Unlock();
2189 			kernelTeam->Unlock();
2190 		}
2191 
2192 		TRACE(("thread_exit: thread %" B_PRId32 " now a kernel thread!\n",
2193 			thread->id));
2194 	}
2195 
2196 	// delete the team if we're its main thread
2197 	if (deleteTeam) {
2198 		team_delete_team(team, debuggerPort);
2199 
2200 		// we need to delete any death entry that made it to here
2201 		delete death;
2202 	}
2203 
2204 	ThreadLocker threadLocker(thread);
2205 
2206 	state = disable_interrupts();
2207 	SpinLocker threadCreationLocker(gThreadCreationLock);
2208 
2209 	// mark invisible in global hash/list, so it's no longer accessible
2210 	WriteSpinLocker threadHashLocker(sThreadHashLock);
2211 	thread->visible = false;
2212 	sUsedThreads--;
2213 	threadHashLocker.Unlock();
2214 
2215 	// Stop debugging for this thread
2216 	SpinLocker threadDebugInfoLocker(thread->debug_info.lock);
2217 	debugInfo = thread->debug_info;
2218 	clear_thread_debug_info(&thread->debug_info, true);
2219 	threadDebugInfoLocker.Unlock();
2220 
2221 	// Remove the select infos. We notify them a little later.
2222 	select_info* selectInfos = thread->select_infos;
2223 	thread->select_infos = NULL;
2224 
2225 	threadCreationLocker.Unlock();
2226 	restore_interrupts(state);
2227 
2228 	threadLocker.Unlock();
2229 
2230 	destroy_thread_debug_info(&debugInfo);
2231 
2232 	// notify select infos
2233 	select_info* info = selectInfos;
2234 	while (info != NULL) {
2235 		select_sync* sync = info->sync;
2236 
2237 		notify_select_events(info, B_EVENT_INVALID);
2238 		info = info->next;
2239 		put_select_sync(sync);
2240 	}
2241 
2242 	// notify listeners
2243 	sNotificationService.Notify(THREAD_REMOVED, thread);
2244 
2245 	// shutdown the thread messaging
2246 
2247 	status = acquire_sem_etc(thread->msg.write_sem, 1, B_RELATIVE_TIMEOUT, 0);
2248 	if (status == B_WOULD_BLOCK) {
2249 		// there is data waiting for us, so let us eat it
2250 		thread_id sender;
2251 
2252 		delete_sem(thread->msg.write_sem);
2253 			// first, let's remove all possibly waiting writers
2254 		receive_data_etc(&sender, NULL, 0, B_RELATIVE_TIMEOUT);
2255 	} else {
2256 		// we probably own the semaphore here, and we're the last to do so
2257 		delete_sem(thread->msg.write_sem);
2258 	}
2259 	// now we can safely remove the msg.read_sem
2260 	delete_sem(thread->msg.read_sem);
2261 
2262 	// fill all death entries and delete the sem that others will use to wait
2263 	// for us
2264 	{
2265 		sem_id cachedExitSem = thread->exit.sem;
2266 
2267 		ThreadLocker threadLocker(thread);
2268 
2269 		// make sure no one will grab this semaphore again
2270 		thread->exit.sem = -1;
2271 
2272 		// fill all death entries
2273 		thread_death_entry* entry = NULL;
2274 		while ((entry = (thread_death_entry*)list_get_next_item(
2275 				&thread->exit.waiters, entry)) != NULL) {
2276 			entry->status = thread->exit.status;
2277 		}
2278 
2279 		threadLocker.Unlock();
2280 
2281 		delete_sem(cachedExitSem);
2282 	}
2283 
2284 	// delete the user stack, if this was a user thread
2285 	if (!deleteTeam && userStackArea >= 0) {
2286 		// We postponed deleting the user stack until now, since this way all
2287 		// notifications for the thread's death are out already and all other
2288 		// threads waiting for this thread's death and some object on its stack
2289 		// will wake up before we (try to) delete the stack area. Of most
2290 		// relevance is probably the case where this is the main thread and
2291 		// other threads use objects on its stack -- so we want them terminated
2292 		// first.
2293 		// When the team is deleted, all areas are deleted anyway, so we don't
2294 		// need to do that explicitly in that case.
2295 		vm_delete_area(teamID, userStackArea, true);
2296 	}
2297 
2298 	// notify the debugger
2299 	if (teamID != kernelTeam->id)
2300 		user_debug_thread_deleted(teamID, thread->id);
2301 
2302 	// enqueue in the undertaker list and reschedule for the last time
2303 	UndertakerEntry undertakerEntry(thread, teamID);
2304 
2305 	disable_interrupts();
2306 
2307 	SpinLocker schedulerLocker(thread->scheduler_lock);
2308 
2309 	SpinLocker undertakerLocker(sUndertakerLock);
2310 	sUndertakerEntries.Add(&undertakerEntry);
2311 	sUndertakerCondition.NotifyOne();
2312 	undertakerLocker.Unlock();
2313 
2314 	scheduler_reschedule(THREAD_STATE_FREE_ON_RESCHED);
2315 
2316 	panic("never can get here\n");
2317 }
2318 
2319 
2320 /*!	Called in the interrupt handler code when a thread enters
2321 	the kernel for any reason.
2322 	Only tracks time for now.
2323 	Interrupts are disabled.
2324 */
2325 void
2326 thread_at_kernel_entry(bigtime_t now)
2327 {
2328 	Thread *thread = thread_get_current_thread();
2329 
2330 	TRACE(("thread_at_kernel_entry: entry thread %" B_PRId32 "\n", thread->id));
2331 
2332 	// track user time
2333 	SpinLocker threadTimeLocker(thread->time_lock);
2334 	thread->user_time += now - thread->last_time;
2335 	thread->last_time = now;
2336 	thread->in_kernel = true;
2337 	threadTimeLocker.Unlock();
2338 }
2339 
2340 
2341 /*!	Called whenever a thread exits kernel space to user space.
2342 	Tracks time, handles signals, ...
2343 	Interrupts must be enabled. When the function returns, interrupts will be
2344 	disabled.
2345 	The function may not return. This e.g. happens when the thread has received
2346 	a deadly signal.
2347 */
2348 void
2349 thread_at_kernel_exit(void)
2350 {
2351 	Thread *thread = thread_get_current_thread();
2352 
2353 	TRACE(("thread_at_kernel_exit: exit thread %" B_PRId32 "\n", thread->id));
2354 
2355 	handle_signals(thread);
2356 
2357 	disable_interrupts();
2358 
2359 	update_thread_sigmask_on_exit(thread);
2360 
2361 	// track kernel time
2362 	bigtime_t now = system_time();
2363 	SpinLocker threadTimeLocker(thread->time_lock);
2364 	thread->in_kernel = false;
2365 	thread->kernel_time += now - thread->last_time;
2366 	thread->last_time = now;
2367 }
2368 
2369 
2370 /*!	The quick version of thread_kernel_exit(), in case no signals are pending
2371 	and no debugging shall be done.
2372 	Interrupts must be disabled.
2373 */
2374 void
2375 thread_at_kernel_exit_no_signals(void)
2376 {
2377 	Thread *thread = thread_get_current_thread();
2378 
2379 	TRACE(("thread_at_kernel_exit_no_signals: exit thread %" B_PRId32 "\n",
2380 		thread->id));
2381 
2382 	update_thread_sigmask_on_exit(thread);
2383 
2384 	// track kernel time
2385 	bigtime_t now = system_time();
2386 	SpinLocker threadTimeLocker(thread->time_lock);
2387 	thread->in_kernel = false;
2388 	thread->kernel_time += now - thread->last_time;
2389 	thread->last_time = now;
2390 }
2391 
2392 
2393 void
2394 thread_reset_for_exec(void)
2395 {
2396 	Thread* thread = thread_get_current_thread();
2397 
2398 	ThreadLocker threadLocker(thread);
2399 
2400 	// delete user-defined timers
2401 	thread->DeleteUserTimers(true);
2402 
2403 	// cancel pre-defined timer
2404 	if (UserTimer* timer = thread->UserTimerFor(USER_TIMER_REAL_TIME_ID))
2405 		timer->Cancel();
2406 
2407 	// reset user_thread and user stack
2408 	thread->user_thread = NULL;
2409 	thread->user_stack_area = -1;
2410 	thread->user_stack_base = 0;
2411 	thread->user_stack_size = 0;
2412 
2413 	// reset signals
2414 	thread->ResetSignalsOnExec();
2415 
2416 	// reset thread CPU time clock
2417 	InterruptsSpinLocker timeLocker(thread->time_lock);
2418 	thread->cpu_clock_offset = -thread->CPUTime(false);
2419 }
2420 
2421 
2422 thread_id
2423 allocate_thread_id()
2424 {
2425 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
2426 
2427 	// find the next unused ID
2428 	thread_id id;
2429 	do {
2430 		id = sNextThreadID++;
2431 
2432 		// deal with integer overflow
2433 		if (sNextThreadID < 0)
2434 			sNextThreadID = 2;
2435 
2436 		// check whether the ID is already in use
2437 	} while (sThreadHash.Lookup(id, false) != NULL);
2438 
2439 	return id;
2440 }
2441 
2442 
2443 thread_id
2444 peek_next_thread_id()
2445 {
2446 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
2447 	return sNextThreadID;
2448 }
2449 
2450 
2451 /*!	Yield the CPU to other threads.
2452 	Thread will continue to run, if there's no other thread in ready
2453 	state, and if it has a higher priority than the other ready threads, it
2454 	still has a good chance to continue.
2455 */
2456 void
2457 thread_yield(void)
2458 {
2459 	Thread *thread = thread_get_current_thread();
2460 	if (thread == NULL)
2461 		return;
2462 
2463 	InterruptsSpinLocker _(thread->scheduler_lock);
2464 
2465 	thread->has_yielded = true;
2466 	scheduler_reschedule(B_THREAD_READY);
2467 }
2468 
2469 
2470 void
2471 thread_map(void (*function)(Thread* thread, void* data), void* data)
2472 {
2473 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
2474 
2475 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
2476 		Thread* thread = it.Next();) {
2477 		function(thread, data);
2478 	}
2479 }
2480 
2481 
2482 /*!	Kernel private thread creation function.
2483 */
2484 thread_id
2485 spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority,
2486 	void *arg, team_id team)
2487 {
2488 	return thread_create_thread(
2489 		ThreadCreationAttributes(function, name, priority, arg, team),
2490 		true);
2491 }
2492 
2493 
2494 status_t
2495 wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
2496 	status_t *_returnCode)
2497 {
2498 	if (id < 0)
2499 		return B_BAD_THREAD_ID;
2500 	if (id == thread_get_current_thread_id())
2501 		return EDEADLK;
2502 
2503 	// get the thread, queue our death entry, and fetch the semaphore we have to
2504 	// wait on
2505 	sem_id exitSem = B_BAD_THREAD_ID;
2506 	struct thread_death_entry death;
2507 
2508 	Thread* thread = Thread::GetAndLock(id);
2509 	if (thread != NULL) {
2510 		// remember the semaphore we have to wait on and place our death entry
2511 		exitSem = thread->exit.sem;
2512 		if (exitSem >= 0)
2513 			list_add_link_to_head(&thread->exit.waiters, &death);
2514 
2515 		thread->UnlockAndReleaseReference();
2516 
2517 		if (exitSem < 0)
2518 			return B_BAD_THREAD_ID;
2519 	} else {
2520 		// we couldn't find this thread -- maybe it's already gone, and we'll
2521 		// find its death entry in our team
2522 		Team* team = thread_get_current_thread()->team;
2523 		TeamLocker teamLocker(team);
2524 
2525 		// check the child death entries first (i.e. main threads of child
2526 		// teams)
2527 		bool deleteEntry;
2528 		job_control_entry* freeDeath
2529 			= team_get_death_entry(team, id, &deleteEntry);
2530 		if (freeDeath != NULL) {
2531 			death.status = freeDeath->status;
2532 			if (deleteEntry)
2533 				delete freeDeath;
2534 		} else {
2535 			// check the thread death entries of the team (non-main threads)
2536 			thread_death_entry* threadDeathEntry = NULL;
2537 			while ((threadDeathEntry = (thread_death_entry*)list_get_next_item(
2538 					&team->dead_threads, threadDeathEntry)) != NULL) {
2539 				if (threadDeathEntry->thread == id) {
2540 					list_remove_item(&team->dead_threads, threadDeathEntry);
2541 					death.status = threadDeathEntry->status;
2542 					free(threadDeathEntry);
2543 					break;
2544 				}
2545 			}
2546 
2547 			if (threadDeathEntry == NULL)
2548 				return B_BAD_THREAD_ID;
2549 		}
2550 
2551 		// we found the thread's death entry in our team
2552 		if (_returnCode)
2553 			*_returnCode = death.status;
2554 
2555 		return B_OK;
2556 	}
2557 
2558 	// we need to wait for the death of the thread
2559 
2560 	resume_thread(id);
2561 		// make sure we don't wait forever on a suspended thread
2562 
2563 	status_t status = acquire_sem_etc(exitSem, 1, flags, timeout);
2564 
2565 	if (status == B_OK) {
2566 		// this should never happen as the thread deletes the semaphore on exit
2567 		panic("could acquire exit_sem for thread %" B_PRId32 "\n", id);
2568 	} else if (status == B_BAD_SEM_ID) {
2569 		// this is the way the thread normally exits
2570 		status = B_OK;
2571 	} else {
2572 		// We were probably interrupted or the timeout occurred; we need to
2573 		// remove our death entry now.
2574 		thread = Thread::GetAndLock(id);
2575 		if (thread != NULL) {
2576 			list_remove_link(&death);
2577 			thread->UnlockAndReleaseReference();
2578 		} else {
2579 			// The thread is already gone, so we need to wait uninterruptibly
2580 			// for its exit semaphore to make sure our death entry stays valid.
2581 			// It won't take long, since the thread is apparently already in the
2582 			// middle of the cleanup.
2583 			acquire_sem(exitSem);
2584 			status = B_OK;
2585 		}
2586 	}
2587 
2588 	if (status == B_OK && _returnCode != NULL)
2589 		*_returnCode = death.status;
2590 
2591 	return status;
2592 }
2593 
2594 
2595 status_t
2596 select_thread(int32 id, struct select_info* info, bool kernel)
2597 {
2598 	// get and lock the thread
2599 	Thread* thread = Thread::GetAndLock(id);
2600 	if (thread == NULL)
2601 		return B_BAD_THREAD_ID;
2602 	BReference<Thread> threadReference(thread, true);
2603 	ThreadLocker threadLocker(thread, true);
2604 
2605 	// We support only B_EVENT_INVALID at the moment.
2606 	info->selected_events &= B_EVENT_INVALID;
2607 
2608 	// add info to list
2609 	if (info->selected_events != 0) {
2610 		info->next = thread->select_infos;
2611 		thread->select_infos = info;
2612 
2613 		// we need a sync reference
2614 		atomic_add(&info->sync->ref_count, 1);
2615 	}
2616 
2617 	return B_OK;
2618 }
2619 
2620 
2621 status_t
2622 deselect_thread(int32 id, struct select_info* info, bool kernel)
2623 {
2624 	// get and lock the thread
2625 	Thread* thread = Thread::GetAndLock(id);
2626 	if (thread == NULL)
2627 		return B_BAD_THREAD_ID;
2628 	BReference<Thread> threadReference(thread, true);
2629 	ThreadLocker threadLocker(thread, true);
2630 
2631 	// remove info from list
2632 	select_info** infoLocation = &thread->select_infos;
2633 	while (*infoLocation != NULL && *infoLocation != info)
2634 		infoLocation = &(*infoLocation)->next;
2635 
2636 	if (*infoLocation != info)
2637 		return B_OK;
2638 
2639 	*infoLocation = info->next;
2640 
2641 	threadLocker.Unlock();
2642 
2643 	// surrender sync reference
2644 	put_select_sync(info->sync);
2645 
2646 	return B_OK;
2647 }
2648 
2649 
2650 int32
2651 thread_max_threads(void)
2652 {
2653 	return sMaxThreads;
2654 }
2655 
2656 
2657 int32
2658 thread_used_threads(void)
2659 {
2660 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
2661 	return sUsedThreads;
2662 }
2663 
2664 
2665 /*!	Returns a user-readable string for a thread state.
2666 	Only for use in the kernel debugger.
2667 */
2668 const char*
2669 thread_state_to_text(Thread* thread, int32 state)
2670 {
2671 	return state_to_text(thread, state);
2672 }
2673 
2674 
2675 int32
2676 thread_get_io_priority(thread_id id)
2677 {
2678 	Thread* thread = Thread::GetAndLock(id);
2679 	if (thread == NULL)
2680 		return B_BAD_THREAD_ID;
2681 	BReference<Thread> threadReference(thread, true);
2682 	ThreadLocker threadLocker(thread, true);
2683 
2684 	int32 priority = thread->io_priority;
2685 	if (priority < 0) {
2686 		// negative I/O priority means using the (CPU) priority
2687 		priority = thread->priority;
2688 	}
2689 
2690 	return priority;
2691 }
2692 
2693 
2694 void
2695 thread_set_io_priority(int32 priority)
2696 {
2697 	Thread* thread = thread_get_current_thread();
2698 	ThreadLocker threadLocker(thread);
2699 
2700 	thread->io_priority = priority;
2701 }
2702 
2703 
2704 status_t
2705 thread_init(kernel_args *args)
2706 {
2707 	TRACE(("thread_init: entry\n"));
2708 
2709 	// create the thread hash table
2710 	new(&sThreadHash) ThreadHashTable();
2711 	if (sThreadHash.Init(128) != B_OK)
2712 		panic("thread_init(): failed to init thread hash table!");
2713 
2714 	// create the thread structure object cache
2715 	sThreadCache = create_object_cache("threads", sizeof(Thread), 64, NULL,
2716 		NULL, NULL);
2717 		// Note: The x86 port requires 64 byte alignment of thread structures.
2718 	if (sThreadCache == NULL)
2719 		panic("thread_init(): failed to allocate thread object cache!");
2720 
2721 	if (arch_thread_init(args) < B_OK)
2722 		panic("arch_thread_init() failed!\n");
2723 
2724 	// skip all thread IDs including B_SYSTEM_TEAM, which is reserved
2725 	sNextThreadID = B_SYSTEM_TEAM + 1;
2726 
2727 	// create an idle thread for each cpu
2728 	for (uint32 i = 0; i < args->num_cpus; i++) {
2729 		Thread *thread;
2730 		area_info info;
2731 		char name[64];
2732 
2733 		sprintf(name, "idle thread %" B_PRIu32, i + 1);
2734 		thread = new(&sIdleThreads[i]) Thread(name,
2735 			i == 0 ? team_get_kernel_team_id() : -1, &gCPU[i]);
2736 		if (thread == NULL || thread->Init(true) != B_OK) {
2737 			panic("error creating idle thread struct\n");
2738 			return B_NO_MEMORY;
2739 		}
2740 
2741 		gCPU[i].running_thread = thread;
2742 
2743 		thread->team = team_get_kernel_team();
2744 		thread->priority = B_IDLE_PRIORITY;
2745 		thread->state = B_THREAD_RUNNING;
2746 		sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1);
2747 		thread->kernel_stack_area = find_area(name);
2748 
2749 		if (get_area_info(thread->kernel_stack_area, &info) != B_OK)
2750 			panic("error finding idle kstack area\n");
2751 
2752 		thread->kernel_stack_base = (addr_t)info.address;
2753 		thread->kernel_stack_top = thread->kernel_stack_base + info.size;
2754 
2755 		thread->visible = true;
2756 		insert_thread_into_team(thread->team, thread);
2757 
2758 		scheduler_on_thread_init(thread);
2759 	}
2760 	sUsedThreads = args->num_cpus;
2761 
2762 	// init the notification service
2763 	new(&sNotificationService) ThreadNotificationService();
2764 
2765 	sNotificationService.Register();
2766 
2767 	// start the undertaker thread
2768 	new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>();
2769 	sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries");
2770 
2771 	thread_id undertakerThread = spawn_kernel_thread(&undertaker, "undertaker",
2772 		B_DISPLAY_PRIORITY, NULL);
2773 	if (undertakerThread < 0)
2774 		panic("Failed to create undertaker thread!");
2775 	resume_thread(undertakerThread);
2776 
2777 	// set up some debugger commands
2778 	add_debugger_command_etc("threads", &dump_thread_list, "List all threads",
2779 		"[ <team> ]\n"
2780 		"Prints a list of all existing threads, or, if a team ID is given,\n"
2781 		"all threads of the specified team.\n"
2782 		"  <team>  - The ID of the team whose threads shall be listed.\n", 0);
2783 	add_debugger_command_etc("ready", &dump_thread_list,
2784 		"List all ready threads",
2785 		"\n"
2786 		"Prints a list of all threads in ready state.\n", 0);
2787 	add_debugger_command_etc("running", &dump_thread_list,
2788 		"List all running threads",
2789 		"\n"
2790 		"Prints a list of all threads in running state.\n", 0);
2791 	add_debugger_command_etc("waiting", &dump_thread_list,
2792 		"List all waiting threads (optionally for a specific semaphore)",
2793 		"[ <sem> ]\n"
2794 		"Prints a list of all threads in waiting state. If a semaphore is\n"
2795 		"specified, only the threads waiting on that semaphore are listed.\n"
2796 		"  <sem>  - ID of the semaphore.\n", 0);
2797 	add_debugger_command_etc("realtime", &dump_thread_list,
2798 		"List all realtime threads",
2799 		"\n"
2800 		"Prints a list of all threads with realtime priority.\n", 0);
2801 	add_debugger_command_etc("thread", &dump_thread_info,
2802 		"Dump info about a particular thread",
2803 		"[ -s ] ( <id> | <address> | <name> )*\n"
2804 		"Prints information about the specified thread. If no argument is\n"
2805 		"given the current thread is selected.\n"
2806 		"  -s         - Print info in compact table form (like \"threads\").\n"
2807 		"  <id>       - The ID of the thread.\n"
2808 		"  <address>  - The address of the thread structure.\n"
2809 		"  <name>     - The thread's name.\n", 0);
2810 	add_debugger_command_etc("calling", &dump_thread_list,
2811 		"Show all threads that have a specific address in their call chain",
2812 		"{ <symbol-pattern> | <start> <end> }\n", 0);
2813 	add_debugger_command_etc("unreal", &make_thread_unreal,
2814 		"Set realtime priority threads to normal priority",
2815 		"[ <id> ]\n"
2816 		"Sets the priority of all realtime threads or, if given, the one\n"
2817 		"with the specified ID to \"normal\" priority.\n"
2818 		"  <id>  - The ID of the thread.\n", 0);
2819 	add_debugger_command_etc("suspend", &make_thread_suspended,
2820 		"Suspend a thread",
2821 		"[ <id> ]\n"
2822 		"Suspends the thread with the given ID. If no ID argument is given\n"
2823 		"the current thread is selected.\n"
2824 		"  <id>  - The ID of the thread.\n", 0);
2825 	add_debugger_command_etc("resume", &make_thread_resumed, "Resume a thread",
2826 		"<id>\n"
2827 		"Resumes the specified thread, if it is currently suspended.\n"
2828 		"  <id>  - The ID of the thread.\n", 0);
2829 	add_debugger_command_etc("drop", &drop_into_debugger,
2830 		"Drop a thread into the userland debugger",
2831 		"<id>\n"
2832 		"Drops the specified (userland) thread into the userland debugger\n"
2833 		"after leaving the kernel debugger.\n"
2834 		"  <id>  - The ID of the thread.\n", 0);
2835 	add_debugger_command_etc("priority", &set_thread_prio,
2836 		"Set a thread's priority",
2837 		"<priority> [ <id> ]\n"
2838 		"Sets the priority of the thread with the specified ID to the given\n"
2839 		"priority. If no thread ID is given, the current thread is selected.\n"
2840 		"  <priority>  - The thread's new priority (0 - 120)\n"
2841 		"  <id>        - The ID of the thread.\n", 0);
2842 
2843 	return B_OK;
2844 }
2845 
2846 
2847 status_t
2848 thread_preboot_init_percpu(struct kernel_args *args, int32 cpuNum)
2849 {
2850 	// set up the cpu pointer in the not yet initialized per-cpu idle thread
2851 	// so that get_current_cpu and friends will work, which is crucial for
2852 	// a lot of low level routines
2853 	sIdleThreads[cpuNum].cpu = &gCPU[cpuNum];
2854 	arch_thread_set_current_thread(&sIdleThreads[cpuNum]);
2855 	return B_OK;
2856 }
2857 
2858 
2859 //	#pragma mark - thread blocking API
2860 
2861 
2862 static status_t
2863 thread_block_timeout(timer* timer)
2864 {
2865 	Thread* thread = (Thread*)timer->user_data;
2866 	thread_unblock(thread, B_TIMED_OUT);
2867 
2868 	return B_HANDLED_INTERRUPT;
2869 }
2870 
2871 
2872 /*!	Blocks the current thread.
2873 
2874 	The thread is blocked until someone else unblock it. Must be called after a
2875 	call to thread_prepare_to_block(). If the thread has already been unblocked
2876 	after the previous call to thread_prepare_to_block(), this function will
2877 	return immediately. Cf. the documentation of thread_prepare_to_block() for
2878 	more details.
2879 
2880 	The caller must hold the scheduler lock.
2881 
2882 	\param thread The current thread.
2883 	\return The error code passed to the unblocking function. thread_interrupt()
2884 		uses \c B_INTERRUPTED. By convention \c B_OK means that the wait was
2885 		successful while another error code indicates a failure (what that means
2886 		depends on the client code).
2887 */
2888 static inline status_t
2889 thread_block_locked(Thread* thread)
2890 {
2891 	if (thread->wait.status == 1) {
2892 		// check for signals, if interruptible
2893 		if (thread_is_interrupted(thread, thread->wait.flags)) {
2894 			thread->wait.status = B_INTERRUPTED;
2895 		} else
2896 			scheduler_reschedule(B_THREAD_WAITING);
2897 	}
2898 
2899 	return thread->wait.status;
2900 }
2901 
2902 
2903 /*!	Blocks the current thread.
2904 
2905 	The function acquires the scheduler lock and calls thread_block_locked().
2906 	See there for more information.
2907 */
2908 status_t
2909 thread_block()
2910 {
2911 	InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock);
2912 	return thread_block_locked(thread_get_current_thread());
2913 }
2914 
2915 
2916 /*!	Blocks the current thread with a timeout.
2917 
2918 	The current thread is blocked until someone else unblock it or the specified
2919 	timeout occurs. Must be called after a call to thread_prepare_to_block(). If
2920 	the thread has already been unblocked after the previous call to
2921 	thread_prepare_to_block(), this function will return immediately. See
2922 	thread_prepare_to_block() for more details.
2923 
2924 	The caller must not hold the scheduler lock.
2925 
2926 	\param timeoutFlags The standard timeout flags:
2927 		- \c B_RELATIVE_TIMEOUT: \a timeout specifies the time to wait.
2928 		- \c B_ABSOLUTE_TIMEOUT: \a timeout specifies the absolute end time when
2929 			the timeout shall occur.
2930 		- \c B_TIMEOUT_REAL_TIME_BASE: Only relevant when \c B_ABSOLUTE_TIMEOUT
2931 			is specified, too. Specifies that \a timeout is a real time, not a
2932 			system time.
2933 		If neither \c B_RELATIVE_TIMEOUT nor \c B_ABSOLUTE_TIMEOUT are
2934 		specified, an infinite timeout is implied and the function behaves like
2935 		thread_block_locked().
2936 	\return The error code passed to the unblocking function. thread_interrupt()
2937 		uses \c B_INTERRUPTED. When the timeout occurred, \c B_TIMED_OUT is
2938 		returned. By convention \c B_OK means that the wait was successful while
2939 		another error code indicates a failure (what that means depends on the
2940 		client code).
2941 */
2942 status_t
2943 thread_block_with_timeout(uint32 timeoutFlags, bigtime_t timeout)
2944 {
2945 	Thread* thread = thread_get_current_thread();
2946 
2947 	InterruptsSpinLocker locker(thread->scheduler_lock);
2948 
2949 	if (thread->wait.status != 1)
2950 		return thread->wait.status;
2951 
2952 	bool useTimer = (timeoutFlags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT))
2953 		&& timeout != B_INFINITE_TIMEOUT;
2954 
2955 	if (useTimer) {
2956 		// Timer flags: absolute/relative.
2957 		uint32 timerFlags;
2958 		if ((timeoutFlags & B_RELATIVE_TIMEOUT) != 0) {
2959 			timerFlags = B_ONE_SHOT_RELATIVE_TIMER;
2960 		} else {
2961 			timerFlags = B_ONE_SHOT_ABSOLUTE_TIMER;
2962 			if ((timeoutFlags & B_TIMEOUT_REAL_TIME_BASE) != 0)
2963 				timerFlags |= B_TIMER_REAL_TIME_BASE;
2964 		}
2965 
2966 		// install the timer
2967 		thread->wait.unblock_timer.user_data = thread;
2968 		add_timer(&thread->wait.unblock_timer, &thread_block_timeout, timeout,
2969 			timerFlags);
2970 	}
2971 
2972 	// block
2973 	status_t error = thread_block_locked(thread);
2974 
2975 	locker.Unlock();
2976 
2977 	// cancel timer, if it didn't fire
2978 	if (error != B_TIMED_OUT && useTimer)
2979 		cancel_timer(&thread->wait.unblock_timer);
2980 
2981 	return error;
2982 }
2983 
2984 
2985 /*!	Unblocks a thread.
2986 
2987 	Acquires the scheduler lock and calls thread_unblock_locked().
2988 	See there for more information.
2989 */
2990 void
2991 thread_unblock(Thread* thread, status_t status)
2992 {
2993 	InterruptsSpinLocker locker(thread->scheduler_lock);
2994 	thread_unblock_locked(thread, status);
2995 }
2996 
2997 
2998 /*!	Unblocks a userland-blocked thread.
2999 	The caller must not hold any locks.
3000 */
3001 static status_t
3002 user_unblock_thread(thread_id threadID, status_t status)
3003 {
3004 	// get the thread
3005 	Thread* thread = Thread::GetAndLock(threadID);
3006 	if (thread == NULL)
3007 		return B_BAD_THREAD_ID;
3008 	BReference<Thread> threadReference(thread, true);
3009 	ThreadLocker threadLocker(thread, true);
3010 
3011 	if (thread->user_thread == NULL)
3012 		return B_NOT_ALLOWED;
3013 
3014 	InterruptsSpinLocker locker(thread->scheduler_lock);
3015 
3016 	status_t waitStatus;
3017 	if (user_memcpy(&waitStatus, &thread->user_thread->wait_status,
3018 			sizeof(waitStatus)) < B_OK) {
3019 		return B_BAD_ADDRESS;
3020 	}
3021 	if (waitStatus > 0) {
3022 		if (user_memcpy(&thread->user_thread->wait_status, &status,
3023 				sizeof(status)) < B_OK) {
3024 			return B_BAD_ADDRESS;
3025 		}
3026 
3027 		// Even if the user_thread->wait_status was > 0, it may be the
3028 		// case that this thread is actually blocked on something else.
3029 		if (thread->wait.status > 0
3030 				&& thread->wait.type == THREAD_BLOCK_TYPE_USER) {
3031 			thread_unblock_locked(thread, status);
3032 		}
3033 	}
3034 	return B_OK;
3035 }
3036 
3037 
3038 static bool
3039 thread_check_permissions(const Thread* currentThread, const Thread* thread,
3040 	bool kernel)
3041 {
3042 	if (kernel)
3043 		return true;
3044 
3045 	if (thread->team->id == team_get_kernel_team_id())
3046 		return false;
3047 
3048 	if (thread->team == currentThread->team
3049 			|| currentThread->team->effective_uid == 0
3050 			|| thread->team->real_uid == currentThread->team->real_uid)
3051 		return true;
3052 
3053 	return false;
3054 }
3055 
3056 
3057 static status_t
3058 thread_send_signal(thread_id id, uint32 number, int32 signalCode,
3059 	int32 errorCode, bool kernel)
3060 {
3061 	if (id <= 0)
3062 		return B_BAD_VALUE;
3063 
3064 	Thread* currentThread = thread_get_current_thread();
3065 	Thread* thread = Thread::Get(id);
3066 	if (thread == NULL)
3067 		return B_BAD_THREAD_ID;
3068 	BReference<Thread> threadReference(thread, true);
3069 
3070 	// check whether sending the signal is allowed
3071 	if (!thread_check_permissions(currentThread, thread, kernel))
3072 		return B_NOT_ALLOWED;
3073 
3074 	Signal signal(number, signalCode, errorCode, currentThread->team->id);
3075 	return send_signal_to_thread(thread, signal, 0);
3076 }
3077 
3078 
3079 //	#pragma mark - public kernel API
3080 
3081 
3082 void
3083 exit_thread(status_t returnValue)
3084 {
3085 	Thread *thread = thread_get_current_thread();
3086 	Team* team = thread->team;
3087 
3088 	thread->exit.status = returnValue;
3089 
3090 	// if called from a kernel thread, we don't deliver the signal,
3091 	// we just exit directly to keep the user space behaviour of
3092 	// this function
3093 	if (team != team_get_kernel_team()) {
3094 		// If this is its main thread, set the team's exit status.
3095 		if (thread == team->main_thread) {
3096 			TeamLocker teamLocker(team);
3097 
3098 			if (!team->exit.initialized) {
3099 				team->exit.reason = CLD_EXITED;
3100 				team->exit.signal = 0;
3101 				team->exit.signaling_user = 0;
3102 				team->exit.status = returnValue;
3103 				team->exit.initialized = true;
3104 			}
3105 
3106 			teamLocker.Unlock();
3107 		}
3108 
3109 		Signal signal(SIGKILLTHR, SI_USER, B_OK, team->id);
3110 		send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE);
3111 	} else
3112 		thread_exit();
3113 }
3114 
3115 
3116 static status_t
3117 thread_kill_thread(thread_id id, bool kernel)
3118 {
3119 	return thread_send_signal(id, SIGKILLTHR, SI_USER, B_OK, kernel);
3120 }
3121 
3122 
3123 status_t
3124 kill_thread(thread_id id)
3125 {
3126 	return thread_kill_thread(id, true);
3127 }
3128 
3129 
3130 status_t
3131 send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize)
3132 {
3133 	return send_data_etc(thread, code, buffer, bufferSize, 0);
3134 }
3135 
3136 
3137 int32
3138 receive_data(thread_id *sender, void *buffer, size_t bufferSize)
3139 {
3140 	return receive_data_etc(sender, buffer, bufferSize, 0);
3141 }
3142 
3143 
3144 static bool
3145 thread_has_data(thread_id id, bool kernel)
3146 {
3147 	Thread* currentThread = thread_get_current_thread();
3148 	Thread* thread;
3149 	BReference<Thread> threadReference;
3150 	if (id == currentThread->id) {
3151 		thread = currentThread;
3152 	} else {
3153 		thread = Thread::Get(id);
3154 		if (thread == NULL)
3155 			return false;
3156 
3157 		threadReference.SetTo(thread, true);
3158 	}
3159 
3160 	if (!kernel && thread->team != currentThread->team)
3161 		return false;
3162 
3163 	int32 count;
3164 	if (get_sem_count(thread->msg.read_sem, &count) != B_OK)
3165 		return false;
3166 
3167 	return count == 0 ? false : true;
3168 }
3169 
3170 
3171 bool
3172 has_data(thread_id thread)
3173 {
3174 	return thread_has_data(thread, true);
3175 }
3176 
3177 
3178 status_t
3179 _get_thread_info(thread_id id, thread_info *info, size_t size)
3180 {
3181 	if (info == NULL || size != sizeof(thread_info) || id < B_OK)
3182 		return B_BAD_VALUE;
3183 
3184 	// get the thread
3185 	Thread* thread = Thread::GetAndLock(id);
3186 	if (thread == NULL)
3187 		return B_BAD_THREAD_ID;
3188 	BReference<Thread> threadReference(thread, true);
3189 	ThreadLocker threadLocker(thread, true);
3190 
3191 	// fill the info -- also requires the scheduler lock to be held
3192 	InterruptsSpinLocker locker(thread->scheduler_lock);
3193 
3194 	fill_thread_info(thread, info, size);
3195 
3196 	return B_OK;
3197 }
3198 
3199 
3200 status_t
3201 _get_next_thread_info(team_id teamID, int32 *_cookie, thread_info *info,
3202 	size_t size)
3203 {
3204 	if (info == NULL || size != sizeof(thread_info) || teamID < 0)
3205 		return B_BAD_VALUE;
3206 
3207 	int32 lastID = *_cookie;
3208 
3209 	// get the team
3210 	Team* team = Team::GetAndLock(teamID);
3211 	if (team == NULL)
3212 		return B_BAD_VALUE;
3213 	BReference<Team> teamReference(team, true);
3214 	TeamLocker teamLocker(team, true);
3215 
3216 	Thread* thread = NULL;
3217 
3218 	if (lastID == 0) {
3219 		// We start with the main thread
3220 		thread = team->main_thread;
3221 	} else {
3222 		// Find the one thread with an ID greater than ours (as long as the IDs
3223 		// don't wrap they are always sorted from highest to lowest).
3224 		// TODO: That is broken not only when the IDs wrap, but also for the
3225 		// kernel team, to which threads are added when they are dying.
3226 		for (Thread* next = team->thread_list; next != NULL;
3227 				next = next->team_next) {
3228 			if (next->id <= lastID)
3229 				break;
3230 
3231 			thread = next;
3232 		}
3233 	}
3234 
3235 	if (thread == NULL)
3236 		return B_BAD_VALUE;
3237 
3238 	lastID = thread->id;
3239 	*_cookie = lastID;
3240 
3241 	ThreadLocker threadLocker(thread);
3242 	InterruptsSpinLocker locker(thread->scheduler_lock);
3243 
3244 	fill_thread_info(thread, info, size);
3245 
3246 	return B_OK;
3247 }
3248 
3249 
3250 thread_id
3251 find_thread(const char* name)
3252 {
3253 	if (name == NULL)
3254 		return thread_get_current_thread_id();
3255 
3256 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
3257 
3258 	// Scanning the whole hash with the thread hash lock held isn't exactly
3259 	// cheap, but since this function is probably used very rarely, and we
3260 	// only need a read lock, it's probably acceptable.
3261 
3262 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
3263 			Thread* thread = it.Next();) {
3264 		if (!thread->visible)
3265 			continue;
3266 
3267 		if (strcmp(thread->name, name) == 0)
3268 			return thread->id;
3269 	}
3270 
3271 	return B_NAME_NOT_FOUND;
3272 }
3273 
3274 
3275 status_t
3276 rename_thread(thread_id id, const char* name)
3277 {
3278 	if (name == NULL)
3279 		return B_BAD_VALUE;
3280 
3281 	// get the thread
3282 	Thread* thread = Thread::GetAndLock(id);
3283 	if (thread == NULL)
3284 		return B_BAD_THREAD_ID;
3285 	BReference<Thread> threadReference(thread, true);
3286 	ThreadLocker threadLocker(thread, true);
3287 
3288 	// check whether the operation is allowed
3289 	if (thread->team != thread_get_current_thread()->team)
3290 		return B_NOT_ALLOWED;
3291 
3292 	strlcpy(thread->name, name, B_OS_NAME_LENGTH);
3293 
3294 	team_id teamID = thread->team->id;
3295 
3296 	threadLocker.Unlock();
3297 
3298 	// notify listeners
3299 	sNotificationService.Notify(THREAD_NAME_CHANGED, teamID, id);
3300 		// don't pass the thread structure, as it's unsafe, if it isn't ours
3301 
3302 	return B_OK;
3303 }
3304 
3305 
3306 static status_t
3307 thread_set_thread_priority(thread_id id, int32 priority, bool kernel)
3308 {
3309 	// make sure the passed in priority is within bounds
3310 	if (priority > THREAD_MAX_SET_PRIORITY)
3311 		priority = THREAD_MAX_SET_PRIORITY;
3312 	if (priority < THREAD_MIN_SET_PRIORITY)
3313 		priority = THREAD_MIN_SET_PRIORITY;
3314 
3315 	// get the thread
3316 	Thread* thread = Thread::GetAndLock(id);
3317 	if (thread == NULL)
3318 		return B_BAD_THREAD_ID;
3319 	BReference<Thread> threadReference(thread, true);
3320 	ThreadLocker threadLocker(thread, true);
3321 
3322 	// check whether the change is allowed
3323 	if (thread_is_idle_thread(thread) || !thread_check_permissions(
3324 			thread_get_current_thread(), thread, kernel))
3325 		return B_NOT_ALLOWED;
3326 
3327 	return scheduler_set_thread_priority(thread, priority);
3328 }
3329 
3330 
3331 status_t
3332 set_thread_priority(thread_id id, int32 priority)
3333 {
3334 	return thread_set_thread_priority(id, priority, true);
3335 }
3336 
3337 
3338 status_t
3339 snooze_etc(bigtime_t timeout, int timebase, uint32 flags)
3340 {
3341 	return common_snooze_etc(timeout, timebase, flags, NULL);
3342 }
3343 
3344 
3345 /*!	snooze() for internal kernel use only; doesn't interrupt on signals. */
3346 status_t
3347 snooze(bigtime_t timeout)
3348 {
3349 	return snooze_etc(timeout, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT);
3350 }
3351 
3352 
3353 /*!	snooze_until() for internal kernel use only; doesn't interrupt on
3354 	signals.
3355 */
3356 status_t
3357 snooze_until(bigtime_t timeout, int timebase)
3358 {
3359 	return snooze_etc(timeout, timebase, B_ABSOLUTE_TIMEOUT);
3360 }
3361 
3362 
3363 status_t
3364 wait_for_thread(thread_id thread, status_t *_returnCode)
3365 {
3366 	return wait_for_thread_etc(thread, 0, 0, _returnCode);
3367 }
3368 
3369 
3370 static status_t
3371 thread_suspend_thread(thread_id id, bool kernel)
3372 {
3373 	return thread_send_signal(id, SIGSTOP, SI_USER, B_OK, kernel);
3374 }
3375 
3376 
3377 status_t
3378 suspend_thread(thread_id id)
3379 {
3380 	return thread_suspend_thread(id, true);
3381 }
3382 
3383 
3384 static status_t
3385 thread_resume_thread(thread_id id, bool kernel)
3386 {
3387 	// Using the kernel internal SIGNAL_CONTINUE_THREAD signal retains
3388 	// compatibility to BeOS which documents the combination of suspend_thread()
3389 	// and resume_thread() to interrupt threads waiting on semaphores.
3390 	return thread_send_signal(id, SIGNAL_CONTINUE_THREAD, SI_USER, B_OK, kernel);
3391 }
3392 
3393 
3394 status_t
3395 resume_thread(thread_id id)
3396 {
3397 	return thread_resume_thread(id, true);
3398 }
3399 
3400 
3401 thread_id
3402 spawn_kernel_thread(thread_func function, const char *name, int32 priority,
3403 	void *arg)
3404 {
3405 	return thread_create_thread(
3406 		ThreadCreationAttributes(function, name, priority, arg),
3407 		true);
3408 }
3409 
3410 
3411 int
3412 getrlimit(int resource, struct rlimit * rlp)
3413 {
3414 	status_t error = common_getrlimit(resource, rlp);
3415 	if (error != B_OK) {
3416 		errno = error;
3417 		return -1;
3418 	}
3419 
3420 	return 0;
3421 }
3422 
3423 
3424 int
3425 setrlimit(int resource, const struct rlimit * rlp)
3426 {
3427 	status_t error = common_setrlimit(resource, rlp);
3428 	if (error != B_OK) {
3429 		errno = error;
3430 		return -1;
3431 	}
3432 
3433 	return 0;
3434 }
3435 
3436 
3437 //	#pragma mark - syscalls
3438 
3439 
3440 void
3441 _user_exit_thread(status_t returnValue)
3442 {
3443 	exit_thread(returnValue);
3444 }
3445 
3446 
3447 status_t
3448 _user_kill_thread(thread_id thread)
3449 {
3450 	return thread_kill_thread(thread, false);
3451 }
3452 
3453 
3454 status_t
3455 _user_cancel_thread(thread_id threadID, void (*cancelFunction)(int))
3456 {
3457 	// check the cancel function
3458 	if (cancelFunction == NULL || !IS_USER_ADDRESS(cancelFunction))
3459 		return B_BAD_VALUE;
3460 
3461 	// get and lock the thread
3462 	Thread* thread = Thread::GetAndLock(threadID);
3463 	if (thread == NULL)
3464 		return B_BAD_THREAD_ID;
3465 	BReference<Thread> threadReference(thread, true);
3466 	ThreadLocker threadLocker(thread, true);
3467 
3468 	// only threads of the same team can be canceled
3469 	if (thread->team != thread_get_current_thread()->team)
3470 		return B_NOT_ALLOWED;
3471 
3472 	// set the cancel function
3473 	thread->cancel_function = cancelFunction;
3474 
3475 	// send the cancellation signal to the thread
3476 	InterruptsReadSpinLocker teamLocker(thread->team_lock);
3477 	SpinLocker locker(thread->team->signal_lock);
3478 	return send_signal_to_thread_locked(thread, SIGNAL_CANCEL_THREAD, NULL, 0);
3479 }
3480 
3481 
3482 status_t
3483 _user_resume_thread(thread_id thread)
3484 {
3485 	return thread_resume_thread(thread, false);
3486 }
3487 
3488 
3489 status_t
3490 _user_suspend_thread(thread_id thread)
3491 {
3492 	return thread_suspend_thread(thread, false);
3493 }
3494 
3495 
3496 status_t
3497 _user_rename_thread(thread_id thread, const char *userName)
3498 {
3499 	char name[B_OS_NAME_LENGTH];
3500 
3501 	if (!IS_USER_ADDRESS(userName)
3502 		|| userName == NULL
3503 		|| user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK)
3504 		return B_BAD_ADDRESS;
3505 
3506 	// rename_thread() forbids thread renames across teams, so we don't
3507 	// need a "kernel" flag here.
3508 	return rename_thread(thread, name);
3509 }
3510 
3511 
3512 int32
3513 _user_set_thread_priority(thread_id thread, int32 newPriority)
3514 {
3515 	return thread_set_thread_priority(thread, newPriority, false);
3516 }
3517 
3518 
3519 thread_id
3520 _user_spawn_thread(thread_creation_attributes* userAttributes)
3521 {
3522 	// copy the userland structure to the kernel
3523 	char nameBuffer[B_OS_NAME_LENGTH];
3524 	ThreadCreationAttributes attributes;
3525 	status_t error = attributes.InitFromUserAttributes(userAttributes,
3526 		nameBuffer);
3527 	if (error != B_OK)
3528 		return error;
3529 
3530 	// create the thread
3531 	thread_id threadID = thread_create_thread(attributes, false);
3532 
3533 	if (threadID >= 0)
3534 		user_debug_thread_created(threadID);
3535 
3536 	return threadID;
3537 }
3538 
3539 
3540 status_t
3541 _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags,
3542 	bigtime_t* userRemainingTime)
3543 {
3544 	// We need to store more syscall restart parameters than usual and need a
3545 	// somewhat different handling. Hence we can't use
3546 	// syscall_restart_handle_timeout_pre() but do the job ourselves.
3547 	struct restart_parameters {
3548 		bigtime_t	timeout;
3549 		clockid_t	timebase;
3550 		uint32		flags;
3551 	};
3552 
3553 	Thread* thread = thread_get_current_thread();
3554 
3555 	if ((thread->flags & THREAD_FLAGS_SYSCALL_RESTARTED) != 0) {
3556 		// The syscall was restarted. Fetch the parameters from the stored
3557 		// restart parameters.
3558 		restart_parameters* restartParameters
3559 			= (restart_parameters*)thread->syscall_restart.parameters;
3560 		timeout = restartParameters->timeout;
3561 		timebase = restartParameters->timebase;
3562 		flags = restartParameters->flags;
3563 	} else {
3564 		// convert relative timeouts to absolute ones
3565 		if ((flags & B_RELATIVE_TIMEOUT) != 0) {
3566 			// not restarted yet and the flags indicate a relative timeout
3567 
3568 			// Make sure we use the system time base, so real-time clock changes
3569 			// won't affect our wait.
3570 			flags &= ~(uint32)B_TIMEOUT_REAL_TIME_BASE;
3571 			if (timebase == CLOCK_REALTIME)
3572 				timebase = CLOCK_MONOTONIC;
3573 
3574 			// get the current time and make the timeout absolute
3575 			bigtime_t now;
3576 			status_t error = user_timer_get_clock(timebase, now);
3577 			if (error != B_OK)
3578 				return error;
3579 
3580 			timeout += now;
3581 
3582 			// deal with overflow
3583 			if (timeout < 0)
3584 				timeout = B_INFINITE_TIMEOUT;
3585 
3586 			flags = (flags & ~B_RELATIVE_TIMEOUT) | B_ABSOLUTE_TIMEOUT;
3587 		} else
3588 			flags |= B_ABSOLUTE_TIMEOUT;
3589 	}
3590 
3591 	// snooze
3592 	bigtime_t remainingTime;
3593 	status_t error = common_snooze_etc(timeout, timebase,
3594 		flags | B_CAN_INTERRUPT | B_CHECK_PERMISSION,
3595 		userRemainingTime != NULL ? &remainingTime : NULL);
3596 
3597 	// If interrupted, copy the remaining time back to userland and prepare the
3598 	// syscall restart.
3599 	if (error == B_INTERRUPTED) {
3600 		if (userRemainingTime != NULL
3601 			&& (!IS_USER_ADDRESS(userRemainingTime)
3602 				|| user_memcpy(userRemainingTime, &remainingTime,
3603 					sizeof(remainingTime)) != B_OK)) {
3604 			return B_BAD_ADDRESS;
3605 		}
3606 
3607 		// store the normalized values in the restart parameters
3608 		restart_parameters* restartParameters
3609 			= (restart_parameters*)thread->syscall_restart.parameters;
3610 		restartParameters->timeout = timeout;
3611 		restartParameters->timebase = timebase;
3612 		restartParameters->flags = flags;
3613 
3614 		// restart the syscall, if possible
3615 		atomic_or(&thread->flags, THREAD_FLAGS_RESTART_SYSCALL);
3616 	}
3617 
3618 	return error;
3619 }
3620 
3621 
3622 void
3623 _user_thread_yield(void)
3624 {
3625 	thread_yield();
3626 }
3627 
3628 
3629 status_t
3630 _user_get_thread_info(thread_id id, thread_info *userInfo)
3631 {
3632 	thread_info info;
3633 	status_t status;
3634 
3635 	if (!IS_USER_ADDRESS(userInfo))
3636 		return B_BAD_ADDRESS;
3637 
3638 	status = _get_thread_info(id, &info, sizeof(thread_info));
3639 
3640 	if (status >= B_OK
3641 		&& user_memcpy(userInfo, &info, sizeof(thread_info)) < B_OK)
3642 		return B_BAD_ADDRESS;
3643 
3644 	return status;
3645 }
3646 
3647 
3648 status_t
3649 _user_get_next_thread_info(team_id team, int32 *userCookie,
3650 	thread_info *userInfo)
3651 {
3652 	status_t status;
3653 	thread_info info;
3654 	int32 cookie;
3655 
3656 	if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo)
3657 		|| user_memcpy(&cookie, userCookie, sizeof(int32)) < B_OK)
3658 		return B_BAD_ADDRESS;
3659 
3660 	status = _get_next_thread_info(team, &cookie, &info, sizeof(thread_info));
3661 	if (status < B_OK)
3662 		return status;
3663 
3664 	if (user_memcpy(userCookie, &cookie, sizeof(int32)) < B_OK
3665 		|| user_memcpy(userInfo, &info, sizeof(thread_info)) < B_OK)
3666 		return B_BAD_ADDRESS;
3667 
3668 	return status;
3669 }
3670 
3671 
3672 thread_id
3673 _user_find_thread(const char *userName)
3674 {
3675 	char name[B_OS_NAME_LENGTH];
3676 
3677 	if (userName == NULL)
3678 		return find_thread(NULL);
3679 
3680 	if (!IS_USER_ADDRESS(userName)
3681 		|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
3682 		return B_BAD_ADDRESS;
3683 
3684 	return find_thread(name);
3685 }
3686 
3687 
3688 status_t
3689 _user_wait_for_thread(thread_id id, status_t *userReturnCode)
3690 {
3691 	status_t returnCode;
3692 	status_t status;
3693 
3694 	if (userReturnCode != NULL && !IS_USER_ADDRESS(userReturnCode))
3695 		return B_BAD_ADDRESS;
3696 
3697 	status = wait_for_thread_etc(id, B_CAN_INTERRUPT, 0, &returnCode);
3698 
3699 	if (status == B_OK && userReturnCode != NULL
3700 		&& user_memcpy(userReturnCode, &returnCode, sizeof(status_t)) < B_OK) {
3701 		return B_BAD_ADDRESS;
3702 	}
3703 
3704 	return syscall_restart_handle_post(status);
3705 }
3706 
3707 
3708 status_t
3709 _user_wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout, status_t *userReturnCode)
3710 {
3711 	status_t returnCode;
3712 	status_t status;
3713 
3714 	if (userReturnCode != NULL && !IS_USER_ADDRESS(userReturnCode))
3715 		return B_BAD_ADDRESS;
3716 
3717 	syscall_restart_handle_timeout_pre(flags, timeout);
3718 
3719 	status = wait_for_thread_etc(id, flags | B_CAN_INTERRUPT, timeout, &returnCode);
3720 
3721 	if (status == B_OK && userReturnCode != NULL
3722 		&& user_memcpy(userReturnCode, &returnCode, sizeof(status_t)) < B_OK) {
3723 		return B_BAD_ADDRESS;
3724 	}
3725 
3726 	return syscall_restart_handle_timeout_post(status, timeout);
3727 }
3728 
3729 
3730 bool
3731 _user_has_data(thread_id thread)
3732 {
3733 	return thread_has_data(thread, false);
3734 }
3735 
3736 
3737 status_t
3738 _user_send_data(thread_id thread, int32 code, const void *buffer,
3739 	size_t bufferSize)
3740 {
3741 	if (buffer != NULL && !IS_USER_ADDRESS(buffer))
3742 		return B_BAD_ADDRESS;
3743 
3744 	return send_data_etc(thread, code, buffer, bufferSize,
3745 		B_KILL_CAN_INTERRUPT);
3746 		// supports userland buffers
3747 }
3748 
3749 
3750 status_t
3751 _user_receive_data(thread_id *_userSender, void *buffer, size_t bufferSize)
3752 {
3753 	thread_id sender;
3754 	status_t code;
3755 
3756 	if ((!IS_USER_ADDRESS(_userSender) && _userSender != NULL)
3757 		|| (!IS_USER_ADDRESS(buffer) && buffer != NULL)) {
3758 		return B_BAD_ADDRESS;
3759 	}
3760 
3761 	code = receive_data_etc(&sender, buffer, bufferSize, B_KILL_CAN_INTERRUPT);
3762 		// supports userland buffers
3763 
3764 	if (_userSender != NULL)
3765 		if (user_memcpy(_userSender, &sender, sizeof(thread_id)) < B_OK)
3766 			return B_BAD_ADDRESS;
3767 
3768 	return code;
3769 }
3770 
3771 
3772 status_t
3773 _user_block_thread(uint32 flags, bigtime_t timeout)
3774 {
3775 	syscall_restart_handle_timeout_pre(flags, timeout);
3776 	flags |= B_CAN_INTERRUPT;
3777 
3778 	Thread* thread = thread_get_current_thread();
3779 	ThreadLocker threadLocker(thread);
3780 
3781 	// check, if already done
3782 	status_t waitStatus;
3783 	if (user_memcpy(&waitStatus, &thread->user_thread->wait_status,
3784 			sizeof(waitStatus)) < B_OK) {
3785 		return B_BAD_ADDRESS;
3786 	}
3787 	if (waitStatus <= 0)
3788 		return waitStatus;
3789 
3790 	// nope, so wait
3791 	thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_USER, NULL);
3792 
3793 	threadLocker.Unlock();
3794 
3795 	status_t status = thread_block_with_timeout(flags, timeout);
3796 
3797 	threadLocker.Lock();
3798 
3799 	// Interruptions or timeouts can race with other threads unblocking us.
3800 	// Favor a wake-up by another thread, i.e. if someone changed the wait
3801 	// status, use that.
3802 	status_t oldStatus;
3803 	if (user_memcpy(&oldStatus, &thread->user_thread->wait_status,
3804 		sizeof(oldStatus)) < B_OK) {
3805 		return B_BAD_ADDRESS;
3806 	}
3807 	if (oldStatus > 0) {
3808 		if (user_memcpy(&thread->user_thread->wait_status, &status,
3809 				sizeof(status)) < B_OK) {
3810 			return B_BAD_ADDRESS;
3811 		}
3812 	} else {
3813 		status = oldStatus;
3814 	}
3815 
3816 	threadLocker.Unlock();
3817 
3818 	return syscall_restart_handle_timeout_post(status, timeout);
3819 }
3820 
3821 
3822 status_t
3823 _user_unblock_thread(thread_id threadID, status_t status)
3824 {
3825 	status_t error = user_unblock_thread(threadID, status);
3826 
3827 	if (error == B_OK)
3828 		scheduler_reschedule_if_necessary();
3829 
3830 	return error;
3831 }
3832 
3833 
3834 status_t
3835 _user_unblock_threads(thread_id* userThreads, uint32 count, status_t status)
3836 {
3837 	enum {
3838 		MAX_USER_THREADS_TO_UNBLOCK	= 128
3839 	};
3840 
3841 	if (userThreads == NULL || !IS_USER_ADDRESS(userThreads))
3842 		return B_BAD_ADDRESS;
3843 	if (count > MAX_USER_THREADS_TO_UNBLOCK)
3844 		return B_BAD_VALUE;
3845 
3846 	thread_id threads[MAX_USER_THREADS_TO_UNBLOCK];
3847 	if (user_memcpy(threads, userThreads, count * sizeof(thread_id)) != B_OK)
3848 		return B_BAD_ADDRESS;
3849 
3850 	for (uint32 i = 0; i < count; i++)
3851 		user_unblock_thread(threads[i], status);
3852 
3853 	scheduler_reschedule_if_necessary();
3854 
3855 	return B_OK;
3856 }
3857 
3858 
3859 // TODO: the following two functions don't belong here
3860 
3861 
3862 int
3863 _user_getrlimit(int resource, struct rlimit *urlp)
3864 {
3865 	struct rlimit rl;
3866 	int ret;
3867 
3868 	if (urlp == NULL)
3869 		return EINVAL;
3870 
3871 	if (!IS_USER_ADDRESS(urlp))
3872 		return B_BAD_ADDRESS;
3873 
3874 	ret = common_getrlimit(resource, &rl);
3875 
3876 	if (ret == 0) {
3877 		ret = user_memcpy(urlp, &rl, sizeof(struct rlimit));
3878 		if (ret < 0)
3879 			return ret;
3880 
3881 		return 0;
3882 	}
3883 
3884 	return ret;
3885 }
3886 
3887 
3888 int
3889 _user_setrlimit(int resource, const struct rlimit *userResourceLimit)
3890 {
3891 	struct rlimit resourceLimit;
3892 
3893 	if (userResourceLimit == NULL)
3894 		return EINVAL;
3895 
3896 	if (!IS_USER_ADDRESS(userResourceLimit)
3897 		|| user_memcpy(&resourceLimit, userResourceLimit,
3898 			sizeof(struct rlimit)) < B_OK)
3899 		return B_BAD_ADDRESS;
3900 
3901 	return common_setrlimit(resource, &resourceLimit);
3902 }
3903