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