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