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