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