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