xref: /haiku/src/system/kernel/thread.cpp (revision 16ad15142c48ee36cd6a807a24efc99c88d4310d)
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 (the limit is not yet enforced)
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 
1033 		if (userThread != NULL)
1034 			team_free_user_thread(team, userThread);
1035 
1036 		return B_NO_MORE_THREADS;
1037 	}
1038 
1039 	// make thread visible in global hash/list
1040 	thread->visible = true;
1041 	sUsedThreads++;
1042 
1043 	scheduler_on_thread_init(thread);
1044 
1045 	thread->AcquireReference();
1046 
1047 	// Debug the new thread, if the parent thread required that (see above),
1048 	// or the respective global team debug flag is set. But only, if a
1049 	// debugger is installed for the team.
1050 	if (!kernel) {
1051 		int32 teamDebugFlags = atomic_get(&team->debug_info.flags);
1052 		debugNewThread |= (teamDebugFlags & B_TEAM_DEBUG_STOP_NEW_THREADS) != 0;
1053 		if (debugNewThread
1054 			&& (teamDebugFlags & B_TEAM_DEBUG_DEBUGGER_INSTALLED) != 0) {
1055 			thread->debug_info.flags |= B_THREAD_DEBUG_STOP;
1056 		}
1057 	}
1058 
1059 	{
1060 		SpinLocker signalLocker(team->signal_lock);
1061 		SpinLocker timeLocker(team->time_lock);
1062 
1063 		// insert thread into team
1064 		insert_thread_into_team(team, thread);
1065 	}
1066 
1067 	threadHashLocker.Unlock();
1068 	threadCreationLocker.Unlock();
1069 	threadLocker.Unlock();
1070 	teamLocker.Unlock();
1071 
1072 	// notify listeners
1073 	sNotificationService.Notify(THREAD_ADDED, thread);
1074 
1075 	return thread->id;
1076 }
1077 
1078 
1079 static status_t
1080 undertaker(void* /*args*/)
1081 {
1082 	while (true) {
1083 		// wait for a thread to bury
1084 		InterruptsSpinLocker locker(sUndertakerLock);
1085 
1086 		while (sUndertakerEntries.IsEmpty()) {
1087 			ConditionVariableEntry conditionEntry;
1088 			sUndertakerCondition.Add(&conditionEntry);
1089 			locker.Unlock();
1090 
1091 			conditionEntry.Wait();
1092 
1093 			locker.Lock();
1094 		}
1095 
1096 		UndertakerEntry* _entry = sUndertakerEntries.RemoveHead();
1097 		locker.Unlock();
1098 
1099 		UndertakerEntry entry = *_entry;
1100 			// we need a copy, since the original entry is on the thread's stack
1101 
1102 		// we've got an entry
1103 		Thread* thread = entry.thread;
1104 
1105 		// make sure the thread isn't running anymore
1106 		InterruptsSpinLocker schedulerLocker(thread->scheduler_lock);
1107 		ASSERT(thread->state == THREAD_STATE_FREE_ON_RESCHED);
1108 		schedulerLocker.Unlock();
1109 
1110 		// remove this thread from from the kernel team -- this makes it
1111 		// unaccessible
1112 		Team* kernelTeam = team_get_kernel_team();
1113 		TeamLocker kernelTeamLocker(kernelTeam);
1114 		thread->Lock();
1115 
1116 		InterruptsSpinLocker threadCreationLocker(gThreadCreationLock);
1117 		SpinLocker signalLocker(kernelTeam->signal_lock);
1118 		SpinLocker timeLocker(kernelTeam->time_lock);
1119 
1120 		remove_thread_from_team(kernelTeam, thread);
1121 
1122 		timeLocker.Unlock();
1123 		signalLocker.Unlock();
1124 		threadCreationLocker.Unlock();
1125 
1126 		kernelTeamLocker.Unlock();
1127 
1128 		// free the thread structure
1129 		thread->UnlockAndReleaseReference();
1130 	}
1131 
1132 	// can never get here
1133 	return B_OK;
1134 }
1135 
1136 
1137 /*!	Returns the semaphore the thread is currently waiting on.
1138 
1139 	The return value is purely informative.
1140 	The caller must hold the scheduler lock.
1141 
1142 	\param thread The thread.
1143 	\return The ID of the semaphore the thread is currently waiting on or \c -1,
1144 		if it isn't waiting on a semaphore.
1145 */
1146 static sem_id
1147 get_thread_wait_sem(Thread* thread)
1148 {
1149 	if (thread->state == B_THREAD_WAITING
1150 		&& thread->wait.type == THREAD_BLOCK_TYPE_SEMAPHORE) {
1151 		return (sem_id)(addr_t)thread->wait.object;
1152 	}
1153 	return -1;
1154 }
1155 
1156 
1157 /*!	Fills the thread_info structure with information from the specified thread.
1158 	The caller must hold the thread's lock and the scheduler lock.
1159 */
1160 static void
1161 fill_thread_info(Thread *thread, thread_info *info, size_t size)
1162 {
1163 	info->thread = thread->id;
1164 	info->team = thread->team->id;
1165 
1166 	strlcpy(info->name, thread->name, B_OS_NAME_LENGTH);
1167 
1168 	info->sem = -1;
1169 
1170 	if (thread->state == B_THREAD_WAITING) {
1171 		info->state = B_THREAD_WAITING;
1172 
1173 		switch (thread->wait.type) {
1174 			case THREAD_BLOCK_TYPE_SNOOZE:
1175 				info->state = B_THREAD_ASLEEP;
1176 				break;
1177 
1178 			case THREAD_BLOCK_TYPE_SEMAPHORE:
1179 			{
1180 				sem_id sem = (sem_id)(addr_t)thread->wait.object;
1181 				if (sem == thread->msg.read_sem)
1182 					info->state = B_THREAD_RECEIVING;
1183 				else
1184 					info->sem = sem;
1185 				break;
1186 			}
1187 
1188 			case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1189 			default:
1190 				break;
1191 		}
1192 	} else
1193 		info->state = (thread_state)thread->state;
1194 
1195 	info->priority = thread->priority;
1196 	info->stack_base = (void *)thread->user_stack_base;
1197 	info->stack_end = (void *)(thread->user_stack_base
1198 		+ thread->user_stack_size);
1199 
1200 	InterruptsSpinLocker threadTimeLocker(thread->time_lock);
1201 	info->user_time = thread->user_time;
1202 	info->kernel_time = thread->kernel_time;
1203 }
1204 
1205 
1206 static status_t
1207 send_data_etc(thread_id id, int32 code, const void *buffer, size_t bufferSize,
1208 	int32 flags)
1209 {
1210 	// get the thread
1211 	Thread *target = Thread::Get(id);
1212 	if (target == NULL)
1213 		return B_BAD_THREAD_ID;
1214 	BReference<Thread> targetReference(target, true);
1215 
1216 	// get the write semaphore
1217 	ThreadLocker targetLocker(target);
1218 	sem_id cachedSem = target->msg.write_sem;
1219 	targetLocker.Unlock();
1220 
1221 	if (bufferSize > THREAD_MAX_MESSAGE_SIZE)
1222 		return B_NO_MEMORY;
1223 
1224 	status_t status = acquire_sem_etc(cachedSem, 1, flags, 0);
1225 	if (status == B_INTERRUPTED) {
1226 		// we got interrupted by a signal
1227 		return status;
1228 	}
1229 	if (status != B_OK) {
1230 		// Any other acquisition problems may be due to thread deletion
1231 		return B_BAD_THREAD_ID;
1232 	}
1233 
1234 	void* data;
1235 	if (bufferSize > 0) {
1236 		data = malloc(bufferSize);
1237 		if (data == NULL)
1238 			return B_NO_MEMORY;
1239 		if (user_memcpy(data, buffer, bufferSize) != B_OK) {
1240 			free(data);
1241 			return B_BAD_DATA;
1242 		}
1243 	} else
1244 		data = NULL;
1245 
1246 	targetLocker.Lock();
1247 
1248 	// The target thread could have been deleted at this point.
1249 	if (!target->IsAlive()) {
1250 		targetLocker.Unlock();
1251 		free(data);
1252 		return B_BAD_THREAD_ID;
1253 	}
1254 
1255 	// Save message informations
1256 	target->msg.sender = thread_get_current_thread()->id;
1257 	target->msg.code = code;
1258 	target->msg.size = bufferSize;
1259 	target->msg.buffer = data;
1260 	cachedSem = target->msg.read_sem;
1261 
1262 	targetLocker.Unlock();
1263 
1264 	release_sem(cachedSem);
1265 	return B_OK;
1266 }
1267 
1268 
1269 static int32
1270 receive_data_etc(thread_id *_sender, void *buffer, size_t bufferSize,
1271 	int32 flags)
1272 {
1273 	Thread *thread = thread_get_current_thread();
1274 	size_t size;
1275 	int32 code;
1276 
1277 	status_t status = acquire_sem_etc(thread->msg.read_sem, 1, flags, 0);
1278 	if (status != B_OK) {
1279 		// Actually, we're not supposed to return error codes
1280 		// but since the only reason this can fail is that we
1281 		// were killed, it's probably okay to do so (but also
1282 		// meaningless).
1283 		return status;
1284 	}
1285 
1286 	if (buffer != NULL && bufferSize != 0 && thread->msg.buffer != NULL) {
1287 		size = min_c(bufferSize, thread->msg.size);
1288 		status = user_memcpy(buffer, thread->msg.buffer, size);
1289 		if (status != B_OK) {
1290 			free(thread->msg.buffer);
1291 			release_sem(thread->msg.write_sem);
1292 			return status;
1293 		}
1294 	}
1295 
1296 	*_sender = thread->msg.sender;
1297 	code = thread->msg.code;
1298 
1299 	free(thread->msg.buffer);
1300 	release_sem(thread->msg.write_sem);
1301 
1302 	return code;
1303 }
1304 
1305 
1306 static status_t
1307 common_getrlimit(int resource, struct rlimit * rlp)
1308 {
1309 	if (!rlp)
1310 		return B_BAD_ADDRESS;
1311 
1312 	switch (resource) {
1313 		case RLIMIT_AS:
1314 			rlp->rlim_cur = __HAIKU_ADDR_MAX;
1315 			rlp->rlim_max = __HAIKU_ADDR_MAX;
1316 			return B_OK;
1317 
1318 		case RLIMIT_CORE:
1319 			rlp->rlim_cur = 0;
1320 			rlp->rlim_max = 0;
1321 			return B_OK;
1322 
1323 		case RLIMIT_DATA:
1324 			rlp->rlim_cur = RLIM_INFINITY;
1325 			rlp->rlim_max = RLIM_INFINITY;
1326 			return B_OK;
1327 
1328 		case RLIMIT_NOFILE:
1329 		case RLIMIT_NOVMON:
1330 			return vfs_getrlimit(resource, rlp);
1331 
1332 		case RLIMIT_STACK:
1333 		{
1334 			rlp->rlim_cur = USER_MAIN_THREAD_STACK_SIZE;
1335 			rlp->rlim_max = USER_MAIN_THREAD_STACK_SIZE;
1336 			return B_OK;
1337 		}
1338 
1339 		default:
1340 			return EINVAL;
1341 	}
1342 
1343 	return B_OK;
1344 }
1345 
1346 
1347 static status_t
1348 common_setrlimit(int resource, const struct rlimit * rlp)
1349 {
1350 	if (!rlp)
1351 		return B_BAD_ADDRESS;
1352 
1353 	switch (resource) {
1354 		case RLIMIT_CORE:
1355 			// We don't support core file, so allow settings to 0/0 only.
1356 			if (rlp->rlim_cur != 0 || rlp->rlim_max != 0)
1357 				return EINVAL;
1358 			return B_OK;
1359 
1360 		case RLIMIT_NOFILE:
1361 		case RLIMIT_NOVMON:
1362 			return vfs_setrlimit(resource, rlp);
1363 
1364 		default:
1365 			return EINVAL;
1366 	}
1367 
1368 	return B_OK;
1369 }
1370 
1371 
1372 static status_t
1373 common_snooze_etc(bigtime_t timeout, clockid_t clockID, uint32 flags,
1374 	bigtime_t* _remainingTime)
1375 {
1376 #if KDEBUG
1377 	if (!are_interrupts_enabled()) {
1378 		panic("common_snooze_etc(): called with interrupts disabled, timeout "
1379 			"%" B_PRIdBIGTIME, timeout);
1380 	}
1381 #endif
1382 
1383 	switch (clockID) {
1384 		case CLOCK_REALTIME:
1385 			// make sure the B_TIMEOUT_REAL_TIME_BASE flag is set and fall
1386 			// through
1387 			flags |= B_TIMEOUT_REAL_TIME_BASE;
1388 		case CLOCK_MONOTONIC:
1389 		{
1390 			// Store the start time, for the case that we get interrupted and
1391 			// need to return the remaining time. For absolute timeouts we can
1392 			// still get he time later, if needed.
1393 			bigtime_t startTime
1394 				= _remainingTime != NULL && (flags & B_RELATIVE_TIMEOUT) != 0
1395 					? system_time() : 0;
1396 
1397 			Thread* thread = thread_get_current_thread();
1398 
1399 			thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_SNOOZE,
1400 				NULL);
1401 			status_t status = thread_block_with_timeout(flags, timeout);
1402 
1403 			if (status == B_TIMED_OUT || status == B_WOULD_BLOCK)
1404 				return B_OK;
1405 
1406 			// If interrupted, compute the remaining time, if requested.
1407 			if (status == B_INTERRUPTED && _remainingTime != NULL) {
1408 				if ((flags & B_RELATIVE_TIMEOUT) != 0) {
1409 					*_remainingTime = std::max(
1410 						startTime + timeout - system_time(), (bigtime_t)0);
1411 				} else {
1412 					bigtime_t now = (flags & B_TIMEOUT_REAL_TIME_BASE) != 0
1413 						? real_time_clock_usecs() : system_time();
1414 					*_remainingTime = std::max(timeout - now, (bigtime_t)0);
1415 				}
1416 			}
1417 
1418 			return status;
1419 		}
1420 
1421 		case CLOCK_THREAD_CPUTIME_ID:
1422 			// Waiting for ourselves to do something isn't particularly
1423 			// productive.
1424 			return B_BAD_VALUE;
1425 
1426 		case CLOCK_PROCESS_CPUTIME_ID:
1427 		default:
1428 			// We don't have to support those, but we are allowed to. Could be
1429 			// done be creating a UserTimer on the fly with a custom UserEvent
1430 			// that would just wake us up.
1431 			return ENOTSUP;
1432 	}
1433 }
1434 
1435 
1436 //	#pragma mark - debugger calls
1437 
1438 
1439 static int
1440 make_thread_unreal(int argc, char **argv)
1441 {
1442 	int32 id = -1;
1443 
1444 	if (argc > 2) {
1445 		print_debugger_command_usage(argv[0]);
1446 		return 0;
1447 	}
1448 
1449 	if (argc > 1)
1450 		id = strtoul(argv[1], NULL, 0);
1451 
1452 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1453 			Thread* thread = it.Next();) {
1454 		if (id != -1 && thread->id != id)
1455 			continue;
1456 
1457 		if (thread->priority > B_DISPLAY_PRIORITY) {
1458 			scheduler_set_thread_priority(thread, B_NORMAL_PRIORITY);
1459 			kprintf("thread %" B_PRId32 " made unreal\n", thread->id);
1460 		}
1461 	}
1462 
1463 	return 0;
1464 }
1465 
1466 
1467 static int
1468 set_thread_prio(int argc, char **argv)
1469 {
1470 	int32 id;
1471 	int32 prio;
1472 
1473 	if (argc > 3 || argc < 2) {
1474 		print_debugger_command_usage(argv[0]);
1475 		return 0;
1476 	}
1477 
1478 	prio = strtoul(argv[1], NULL, 0);
1479 	if (prio > THREAD_MAX_SET_PRIORITY)
1480 		prio = THREAD_MAX_SET_PRIORITY;
1481 	if (prio < THREAD_MIN_SET_PRIORITY)
1482 		prio = THREAD_MIN_SET_PRIORITY;
1483 
1484 	if (argc > 2)
1485 		id = strtoul(argv[2], NULL, 0);
1486 	else
1487 		id = thread_get_current_thread()->id;
1488 
1489 	bool found = false;
1490 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1491 			Thread* thread = it.Next();) {
1492 		if (thread->id != id)
1493 			continue;
1494 		scheduler_set_thread_priority(thread, prio);
1495 		kprintf("thread %" B_PRId32 " set to priority %" B_PRId32 "\n", id, prio);
1496 		found = true;
1497 		break;
1498 	}
1499 	if (!found)
1500 		kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1501 
1502 	return 0;
1503 }
1504 
1505 
1506 static int
1507 make_thread_suspended(int argc, char **argv)
1508 {
1509 	int32 id;
1510 
1511 	if (argc > 2) {
1512 		print_debugger_command_usage(argv[0]);
1513 		return 0;
1514 	}
1515 
1516 	if (argc == 1)
1517 		id = thread_get_current_thread()->id;
1518 	else
1519 		id = strtoul(argv[1], NULL, 0);
1520 
1521 	bool found = false;
1522 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1523 			Thread* thread = it.Next();) {
1524 		if (thread->id != id)
1525 			continue;
1526 
1527 		Signal signal(SIGSTOP, SI_USER, B_OK, team_get_kernel_team()->id);
1528 		send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE);
1529 
1530 		kprintf("thread %" B_PRId32 " suspended\n", id);
1531 		found = true;
1532 		break;
1533 	}
1534 	if (!found)
1535 		kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1536 
1537 	return 0;
1538 }
1539 
1540 
1541 static int
1542 make_thread_resumed(int argc, char **argv)
1543 {
1544 	int32 id;
1545 
1546 	if (argc != 2) {
1547 		print_debugger_command_usage(argv[0]);
1548 		return 0;
1549 	}
1550 
1551 	// force user to enter a thread id, as using
1552 	// the current thread is usually not intended
1553 	id = strtoul(argv[1], NULL, 0);
1554 
1555 	bool found = false;
1556 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1557 			Thread* thread = it.Next();) {
1558 		if (thread->id != id)
1559 			continue;
1560 
1561 		if (thread->state == B_THREAD_SUSPENDED || thread->state == B_THREAD_ASLEEP
1562 				|| thread->state == B_THREAD_WAITING) {
1563 			scheduler_enqueue_in_run_queue(thread);
1564 			kprintf("thread %" B_PRId32 " resumed\n", thread->id);
1565 		} else
1566 			kprintf("thread %" B_PRId32 " is already running\n", thread->id);
1567 		found = true;
1568 		break;
1569 	}
1570 	if (!found)
1571 		kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1572 
1573 	return 0;
1574 }
1575 
1576 
1577 static int
1578 drop_into_debugger(int argc, char **argv)
1579 {
1580 	status_t err;
1581 	int32 id;
1582 
1583 	if (argc > 2) {
1584 		print_debugger_command_usage(argv[0]);
1585 		return 0;
1586 	}
1587 
1588 	if (argc == 1)
1589 		id = thread_get_current_thread()->id;
1590 	else
1591 		id = strtoul(argv[1], NULL, 0);
1592 
1593 	err = _user_debug_thread(id);
1594 		// TODO: This is a non-trivial syscall doing some locking, so this is
1595 		// really nasty and may go seriously wrong.
1596 	if (err)
1597 		kprintf("drop failed\n");
1598 	else
1599 		kprintf("thread %" B_PRId32 " dropped into user debugger\n", id);
1600 
1601 	return 0;
1602 }
1603 
1604 
1605 /*!	Returns a user-readable string for a thread state.
1606 	Only for use in the kernel debugger.
1607 */
1608 static const char *
1609 state_to_text(Thread *thread, int32 state)
1610 {
1611 	switch (state) {
1612 		case B_THREAD_READY:
1613 			return "ready";
1614 
1615 		case B_THREAD_RUNNING:
1616 			return "running";
1617 
1618 		case B_THREAD_WAITING:
1619 		{
1620 			if (thread != NULL) {
1621 				switch (thread->wait.type) {
1622 					case THREAD_BLOCK_TYPE_SNOOZE:
1623 						return "zzz";
1624 
1625 					case THREAD_BLOCK_TYPE_SEMAPHORE:
1626 					{
1627 						sem_id sem = (sem_id)(addr_t)thread->wait.object;
1628 						if (sem == thread->msg.read_sem)
1629 							return "receive";
1630 						break;
1631 					}
1632 				}
1633 			}
1634 
1635 			return "waiting";
1636 		}
1637 
1638 		case B_THREAD_SUSPENDED:
1639 			return "suspended";
1640 
1641 		case THREAD_STATE_FREE_ON_RESCHED:
1642 			return "death";
1643 
1644 		default:
1645 			return "UNKNOWN";
1646 	}
1647 }
1648 
1649 
1650 static void
1651 print_thread_list_table_head()
1652 {
1653 	kprintf("%-*s       id  state     wait for  %-*s    cpu pri  %-*s   team  "
1654 		"name\n",
1655 		B_PRINTF_POINTER_WIDTH, "thread", B_PRINTF_POINTER_WIDTH, "object",
1656 		B_PRINTF_POINTER_WIDTH, "stack");
1657 }
1658 
1659 
1660 static void
1661 _dump_thread_info(Thread *thread, bool shortInfo)
1662 {
1663 	if (shortInfo) {
1664 		kprintf("%p %6" B_PRId32 "  %-10s", thread, thread->id,
1665 			state_to_text(thread, thread->state));
1666 
1667 		// does it block on a semaphore or a condition variable?
1668 		if (thread->state == B_THREAD_WAITING) {
1669 			switch (thread->wait.type) {
1670 				case THREAD_BLOCK_TYPE_SEMAPHORE:
1671 				{
1672 					sem_id sem = (sem_id)(addr_t)thread->wait.object;
1673 					if (sem == thread->msg.read_sem)
1674 						kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, "");
1675 					else {
1676 						kprintf("sem       %-*" B_PRId32,
1677 							B_PRINTF_POINTER_WIDTH + 5, sem);
1678 					}
1679 					break;
1680 				}
1681 
1682 				case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1683 					kprintf("cvar      %p   ", thread->wait.object);
1684 					break;
1685 
1686 				case THREAD_BLOCK_TYPE_SNOOZE:
1687 					kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, "");
1688 					break;
1689 
1690 				case THREAD_BLOCK_TYPE_SIGNAL:
1691 					kprintf("signal%*s", B_PRINTF_POINTER_WIDTH + 9, "");
1692 					break;
1693 
1694 				case THREAD_BLOCK_TYPE_MUTEX:
1695 					kprintf("mutex     %p   ", thread->wait.object);
1696 					break;
1697 
1698 				case THREAD_BLOCK_TYPE_RW_LOCK:
1699 					kprintf("rwlock    %p   ", thread->wait.object);
1700 					break;
1701 
1702 				case THREAD_BLOCK_TYPE_USER:
1703 					kprintf("user%*s", B_PRINTF_POINTER_WIDTH + 11, "");
1704 					break;
1705 
1706 				case THREAD_BLOCK_TYPE_OTHER:
1707 					kprintf("other%*s", B_PRINTF_POINTER_WIDTH + 10, "");
1708 					break;
1709 
1710 				default:
1711 					kprintf("???       %p   ", thread->wait.object);
1712 					break;
1713 			}
1714 		} else
1715 			kprintf("-%*s", B_PRINTF_POINTER_WIDTH + 14, "");
1716 
1717 		// on which CPU does it run?
1718 		if (thread->cpu)
1719 			kprintf("%2d", thread->cpu->cpu_num);
1720 		else
1721 			kprintf(" -");
1722 
1723 		kprintf("%4" B_PRId32 "  %p%5" B_PRId32 "  %s\n", thread->priority,
1724 			(void *)thread->kernel_stack_base, thread->team->id, thread->name);
1725 
1726 		return;
1727 	}
1728 
1729 	// print the long info
1730 
1731 	struct thread_death_entry *death = NULL;
1732 
1733 	kprintf("THREAD: %p\n", thread);
1734 	kprintf("id:                 %" B_PRId32 " (%#" B_PRIx32 ")\n", thread->id,
1735 		thread->id);
1736 	kprintf("serial_number:      %" B_PRId64 "\n", thread->serial_number);
1737 	kprintf("name:               \"%s\"\n", thread->name);
1738 	kprintf("hash_next:          %p\nteam_next:          %p\n",
1739 		thread->hash_next, thread->team_next);
1740 	kprintf("priority:           %" B_PRId32 " (I/O: %" B_PRId32 ")\n",
1741 		thread->priority, thread->io_priority);
1742 	kprintf("state:              %s\n", state_to_text(thread, thread->state));
1743 	kprintf("cpu:                %p ", thread->cpu);
1744 	if (thread->cpu)
1745 		kprintf("(%d)\n", thread->cpu->cpu_num);
1746 	else
1747 		kprintf("\n");
1748 	kprintf("sig_pending:        %#" B_PRIx64 " (blocked: %#" B_PRIx64
1749 		", before sigsuspend(): %#" B_PRIx64 ")\n",
1750 		(int64)thread->ThreadPendingSignals(),
1751 		(int64)thread->sig_block_mask,
1752 		(int64)thread->sigsuspend_original_unblocked_mask);
1753 	kprintf("in_kernel:          %d\n", thread->in_kernel);
1754 
1755 	if (thread->state == B_THREAD_WAITING) {
1756 		kprintf("waiting for:        ");
1757 
1758 		switch (thread->wait.type) {
1759 			case THREAD_BLOCK_TYPE_SEMAPHORE:
1760 			{
1761 				sem_id sem = (sem_id)(addr_t)thread->wait.object;
1762 				if (sem == thread->msg.read_sem)
1763 					kprintf("data\n");
1764 				else
1765 					kprintf("semaphore %" B_PRId32 "\n", sem);
1766 				break;
1767 			}
1768 
1769 			case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1770 				kprintf("condition variable %p\n", thread->wait.object);
1771 				break;
1772 
1773 			case THREAD_BLOCK_TYPE_SNOOZE:
1774 				kprintf("snooze()\n");
1775 				break;
1776 
1777 			case THREAD_BLOCK_TYPE_SIGNAL:
1778 				kprintf("signal\n");
1779 				break;
1780 
1781 			case THREAD_BLOCK_TYPE_MUTEX:
1782 				kprintf("mutex %p\n", thread->wait.object);
1783 				break;
1784 
1785 			case THREAD_BLOCK_TYPE_RW_LOCK:
1786 				kprintf("rwlock %p\n", thread->wait.object);
1787 				break;
1788 
1789 			case THREAD_BLOCK_TYPE_USER:
1790 				kprintf("user\n");
1791 				break;
1792 
1793 			case THREAD_BLOCK_TYPE_OTHER:
1794 				kprintf("other (%s)\n", (char*)thread->wait.object);
1795 				break;
1796 
1797 			default:
1798 				kprintf("unknown (%p)\n", thread->wait.object);
1799 				break;
1800 		}
1801 	}
1802 
1803 	kprintf("fault_handler:      %p\n", (void *)thread->fault_handler);
1804 	kprintf("team:               %p, \"%s\"\n", thread->team,
1805 		thread->team->Name());
1806 	kprintf("  exit.sem:         %" B_PRId32 "\n", thread->exit.sem);
1807 	kprintf("  exit.status:      %#" B_PRIx32 " (%s)\n", thread->exit.status,
1808 		strerror(thread->exit.status));
1809 	kprintf("  exit.waiters:\n");
1810 	while ((death = (struct thread_death_entry*)list_get_next_item(
1811 			&thread->exit.waiters, death)) != NULL) {
1812 		kprintf("\t%p (thread %" B_PRId32 ")\n", death, death->thread);
1813 	}
1814 
1815 	kprintf("kernel_stack_area:  %" B_PRId32 "\n", thread->kernel_stack_area);
1816 	kprintf("kernel_stack_base:  %p\n", (void *)thread->kernel_stack_base);
1817 	kprintf("user_stack_area:    %" B_PRId32 "\n", thread->user_stack_area);
1818 	kprintf("user_stack_base:    %p\n", (void *)thread->user_stack_base);
1819 	kprintf("user_local_storage: %p\n", (void *)thread->user_local_storage);
1820 	kprintf("user_thread:        %p\n", (void *)thread->user_thread);
1821 	kprintf("kernel_errno:       %#x (%s)\n", thread->kernel_errno,
1822 		strerror(thread->kernel_errno));
1823 	kprintf("kernel_time:        %" B_PRId64 "\n", thread->kernel_time);
1824 	kprintf("user_time:          %" B_PRId64 "\n", thread->user_time);
1825 	kprintf("flags:              0x%" B_PRIx32 "\n", thread->flags);
1826 	kprintf("architecture dependant section:\n");
1827 	arch_thread_dump_info(&thread->arch_info);
1828 	kprintf("scheduler data:\n");
1829 	scheduler_dump_thread_data(thread);
1830 }
1831 
1832 
1833 static int
1834 dump_thread_info(int argc, char **argv)
1835 {
1836 	bool shortInfo = false;
1837 	int argi = 1;
1838 	if (argi < argc && strcmp(argv[argi], "-s") == 0) {
1839 		shortInfo = true;
1840 		print_thread_list_table_head();
1841 		argi++;
1842 	}
1843 
1844 	if (argi == argc) {
1845 		_dump_thread_info(thread_get_current_thread(), shortInfo);
1846 		return 0;
1847 	}
1848 
1849 	for (; argi < argc; argi++) {
1850 		const char *name = argv[argi];
1851 		ulong arg = strtoul(name, NULL, 0);
1852 
1853 		if (IS_KERNEL_ADDRESS(arg)) {
1854 			// semi-hack
1855 			_dump_thread_info((Thread *)arg, shortInfo);
1856 			continue;
1857 		}
1858 
1859 		// walk through the thread list, trying to match name or id
1860 		bool found = false;
1861 		for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1862 				Thread* thread = it.Next();) {
1863 			if (!strcmp(name, thread->name) || thread->id == (thread_id)arg) {
1864 				_dump_thread_info(thread, shortInfo);
1865 				found = true;
1866 				break;
1867 			}
1868 		}
1869 
1870 		if (!found)
1871 			kprintf("thread \"%s\" (%" B_PRId32 ") doesn't exist!\n", name, (thread_id)arg);
1872 	}
1873 
1874 	return 0;
1875 }
1876 
1877 
1878 static int
1879 dump_thread_list(int argc, char **argv)
1880 {
1881 	bool realTimeOnly = false;
1882 	bool calling = false;
1883 	const char *callSymbol = NULL;
1884 	addr_t callStart = 0;
1885 	addr_t callEnd = 0;
1886 	int32 requiredState = 0;
1887 	team_id team = -1;
1888 	sem_id sem = -1;
1889 
1890 	if (!strcmp(argv[0], "realtime"))
1891 		realTimeOnly = true;
1892 	else if (!strcmp(argv[0], "ready"))
1893 		requiredState = B_THREAD_READY;
1894 	else if (!strcmp(argv[0], "running"))
1895 		requiredState = B_THREAD_RUNNING;
1896 	else if (!strcmp(argv[0], "waiting")) {
1897 		requiredState = B_THREAD_WAITING;
1898 
1899 		if (argc > 1) {
1900 			sem = strtoul(argv[1], NULL, 0);
1901 			if (sem == 0)
1902 				kprintf("ignoring invalid semaphore argument.\n");
1903 		}
1904 	} else if (!strcmp(argv[0], "calling")) {
1905 		if (argc < 2) {
1906 			kprintf("Need to give a symbol name or start and end arguments.\n");
1907 			return 0;
1908 		} else if (argc == 3) {
1909 			callStart = parse_expression(argv[1]);
1910 			callEnd = parse_expression(argv[2]);
1911 		} else
1912 			callSymbol = argv[1];
1913 
1914 		calling = true;
1915 	} else if (argc > 1) {
1916 		team = strtoul(argv[1], NULL, 0);
1917 		if (team == 0)
1918 			kprintf("ignoring invalid team argument.\n");
1919 	}
1920 
1921 	print_thread_list_table_head();
1922 
1923 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1924 			Thread* thread = it.Next();) {
1925 		// filter out threads not matching the search criteria
1926 		if ((requiredState && thread->state != requiredState)
1927 			|| (calling && !arch_debug_contains_call(thread, callSymbol,
1928 					callStart, callEnd))
1929 			|| (sem > 0 && get_thread_wait_sem(thread) != sem)
1930 			|| (team > 0 && thread->team->id != team)
1931 			|| (realTimeOnly && thread->priority < B_REAL_TIME_DISPLAY_PRIORITY))
1932 			continue;
1933 
1934 		_dump_thread_info(thread, true);
1935 	}
1936 	return 0;
1937 }
1938 
1939 
1940 //	#pragma mark - private kernel API
1941 
1942 
1943 void
1944 thread_exit(void)
1945 {
1946 	cpu_status state;
1947 	Thread* thread = thread_get_current_thread();
1948 	Team* team = thread->team;
1949 	Team* kernelTeam = team_get_kernel_team();
1950 	status_t status;
1951 	struct thread_debug_info debugInfo;
1952 	team_id teamID = team->id;
1953 
1954 	TRACE(("thread %" B_PRId32 " exiting w/return code %#" B_PRIx32 "\n",
1955 		thread->id, thread->exit.status));
1956 
1957 	if (!are_interrupts_enabled())
1958 		panic("thread_exit() called with interrupts disabled!\n");
1959 
1960 	// boost our priority to get this over with
1961 	scheduler_set_thread_priority(thread, B_URGENT_DISPLAY_PRIORITY);
1962 
1963 	if (team != kernelTeam) {
1964 		// Delete all user timers associated with the thread.
1965 		ThreadLocker threadLocker(thread);
1966 		thread->DeleteUserTimers(false);
1967 
1968 		// detach the thread's user thread
1969 		user_thread* userThread = thread->user_thread;
1970 		thread->user_thread = NULL;
1971 
1972 		threadLocker.Unlock();
1973 
1974 		// Delete the thread's user thread, if it's not the main thread. If it
1975 		// is, we can save the work, since it will be deleted with the team's
1976 		// address space.
1977 		if (thread != team->main_thread)
1978 			team_free_user_thread(team, userThread);
1979 	}
1980 
1981 	// remember the user stack area -- we will delete it below
1982 	area_id userStackArea = -1;
1983 	if (team->address_space != NULL && thread->user_stack_area >= 0) {
1984 		userStackArea = thread->user_stack_area;
1985 		thread->user_stack_area = -1;
1986 	}
1987 
1988 	struct job_control_entry *death = NULL;
1989 	struct thread_death_entry* threadDeathEntry = NULL;
1990 	bool deleteTeam = false;
1991 	port_id debuggerPort = -1;
1992 
1993 	if (team != kernelTeam) {
1994 		user_debug_thread_exiting(thread);
1995 
1996 		if (team->main_thread == thread) {
1997 			// The main thread is exiting. Shut down the whole team.
1998 			deleteTeam = true;
1999 
2000 			// kill off all other threads and the user debugger facilities
2001 			debuggerPort = team_shutdown_team(team);
2002 
2003 			// acquire necessary locks, which are: process group lock, kernel
2004 			// team lock, parent team lock, and the team lock
2005 			team->LockProcessGroup();
2006 			kernelTeam->Lock();
2007 			team->LockTeamAndParent(true);
2008 		} else {
2009 			threadDeathEntry
2010 				= (thread_death_entry*)malloc(sizeof(thread_death_entry));
2011 
2012 			// acquire necessary locks, which are: kernel team lock and the team
2013 			// lock
2014 			kernelTeam->Lock();
2015 			team->Lock();
2016 		}
2017 
2018 		ThreadLocker threadLocker(thread);
2019 
2020 		state = disable_interrupts();
2021 
2022 		// swap address spaces, to make sure we're running on the kernel's pgdir
2023 		vm_swap_address_space(team->address_space, VMAddressSpace::Kernel());
2024 
2025 		WriteSpinLocker teamLocker(thread->team_lock);
2026 		SpinLocker threadCreationLocker(gThreadCreationLock);
2027 			// removing the thread and putting its death entry to the parent
2028 			// team needs to be an atomic operation
2029 
2030 		// remember how long this thread lasted
2031 		bigtime_t now = system_time();
2032 
2033 		InterruptsSpinLocker signalLocker(kernelTeam->signal_lock);
2034 		SpinLocker teamTimeLocker(kernelTeam->time_lock);
2035 		SpinLocker threadTimeLocker(thread->time_lock);
2036 
2037 		thread->kernel_time += now - thread->last_time;
2038 		thread->last_time = now;
2039 
2040 		team->dead_threads_kernel_time += thread->kernel_time;
2041 		team->dead_threads_user_time += thread->user_time;
2042 
2043 		// stop/update thread/team CPU time user timers
2044 		if (thread->HasActiveCPUTimeUserTimers()
2045 			|| team->HasActiveCPUTimeUserTimers()) {
2046 			user_timer_stop_cpu_timers(thread, NULL);
2047 		}
2048 
2049 		// deactivate CPU time user timers for the thread
2050 		if (thread->HasActiveCPUTimeUserTimers())
2051 			thread->DeactivateCPUTimeUserTimers();
2052 
2053 		threadTimeLocker.Unlock();
2054 
2055 		// put the thread into the kernel team until it dies
2056 		remove_thread_from_team(team, thread);
2057 		insert_thread_into_team(kernelTeam, thread);
2058 
2059 		teamTimeLocker.Unlock();
2060 		signalLocker.Unlock();
2061 
2062 		teamLocker.Unlock();
2063 
2064 		if (team->death_entry != NULL) {
2065 			if (--team->death_entry->remaining_threads == 0)
2066 				team->death_entry->condition.NotifyOne();
2067 		}
2068 
2069 		if (deleteTeam) {
2070 			Team* parent = team->parent;
2071 
2072 			// Set the team job control state to "dead" and detach the job
2073 			// control entry from our team struct.
2074 			team_set_job_control_state(team, JOB_CONTROL_STATE_DEAD, NULL);
2075 			death = team->job_control_entry;
2076 			team->job_control_entry = NULL;
2077 
2078 			if (death != NULL) {
2079 				death->InitDeadState();
2080 
2081 				// team_set_job_control_state() already moved our entry
2082 				// into the parent's list. We just check the soft limit of
2083 				// death entries.
2084 				if (parent->dead_children.count > MAX_DEAD_CHILDREN) {
2085 					death = parent->dead_children.entries.RemoveHead();
2086 					parent->dead_children.count--;
2087 				} else
2088 					death = NULL;
2089 			}
2090 
2091 			threadCreationLocker.Unlock();
2092 			restore_interrupts(state);
2093 
2094 			threadLocker.Unlock();
2095 
2096 			// Get a temporary reference to the team's process group
2097 			// -- team_remove_team() removes the team from the group, which
2098 			// might destroy it otherwise and we wouldn't be able to unlock it.
2099 			ProcessGroup* group = team->group;
2100 			group->AcquireReference();
2101 
2102 			pid_t foregroundGroupToSignal;
2103 			team_remove_team(team, foregroundGroupToSignal);
2104 
2105 			// unlock everything but the parent team
2106 			team->Unlock();
2107 			if (parent != kernelTeam)
2108 				kernelTeam->Unlock();
2109 			group->Unlock();
2110 			group->ReleaseReference();
2111 
2112 			// Send SIGCHLD to the parent as long as we still have its lock.
2113 			// This makes job control state change + signalling atomic.
2114 			Signal childSignal(SIGCHLD, team->exit.reason, B_OK, team->id);
2115 			if (team->exit.reason == CLD_EXITED) {
2116 				childSignal.SetStatus(team->exit.status);
2117 			} else {
2118 				childSignal.SetStatus(team->exit.signal);
2119 				childSignal.SetSendingUser(team->exit.signaling_user);
2120 			}
2121 			send_signal_to_team(parent, childSignal, B_DO_NOT_RESCHEDULE);
2122 
2123 			// also unlock the parent
2124 			parent->Unlock();
2125 
2126 			// If the team was a session leader with controlling TTY, we have
2127 			// to send SIGHUP to the foreground process group.
2128 			if (foregroundGroupToSignal >= 0) {
2129 				Signal groupSignal(SIGHUP, SI_USER, B_OK, team->id);
2130 				send_signal_to_process_group(foregroundGroupToSignal,
2131 					groupSignal, B_DO_NOT_RESCHEDULE);
2132 			}
2133 		} else {
2134 			// The thread is not the main thread. We store a thread death entry
2135 			// for it, unless someone is already waiting for it.
2136 			if (threadDeathEntry != NULL
2137 				&& list_is_empty(&thread->exit.waiters)) {
2138 				threadDeathEntry->thread = thread->id;
2139 				threadDeathEntry->status = thread->exit.status;
2140 
2141 				// add entry -- remove an old one, if we hit the limit
2142 				list_add_item(&team->dead_threads, threadDeathEntry);
2143 				team->dead_threads_count++;
2144 				threadDeathEntry = NULL;
2145 
2146 				if (team->dead_threads_count > MAX_DEAD_THREADS) {
2147 					threadDeathEntry
2148 						= (thread_death_entry*)list_remove_head_item(
2149 							&team->dead_threads);
2150 					team->dead_threads_count--;
2151 				}
2152 			}
2153 
2154 			threadCreationLocker.Unlock();
2155 			restore_interrupts(state);
2156 
2157 			threadLocker.Unlock();
2158 			team->Unlock();
2159 			kernelTeam->Unlock();
2160 		}
2161 
2162 		TRACE(("thread_exit: thread %" B_PRId32 " now a kernel thread!\n",
2163 			thread->id));
2164 	}
2165 
2166 	free(threadDeathEntry);
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 	// track kernel time
2332 	bigtime_t now = system_time();
2333 	SpinLocker threadTimeLocker(thread->time_lock);
2334 	thread->in_kernel = false;
2335 	thread->kernel_time += now - thread->last_time;
2336 	thread->last_time = now;
2337 }
2338 
2339 
2340 /*!	The quick version of thread_kernel_exit(), in case no signals are pending
2341 	and no debugging shall be done.
2342 	Interrupts must be disabled.
2343 */
2344 void
2345 thread_at_kernel_exit_no_signals(void)
2346 {
2347 	Thread *thread = thread_get_current_thread();
2348 
2349 	TRACE(("thread_at_kernel_exit_no_signals: exit thread %" B_PRId32 "\n",
2350 		thread->id));
2351 
2352 	// track kernel time
2353 	bigtime_t now = system_time();
2354 	SpinLocker threadTimeLocker(thread->time_lock);
2355 	thread->in_kernel = false;
2356 	thread->kernel_time += now - thread->last_time;
2357 	thread->last_time = now;
2358 }
2359 
2360 
2361 void
2362 thread_reset_for_exec(void)
2363 {
2364 	Thread* thread = thread_get_current_thread();
2365 
2366 	ThreadLocker threadLocker(thread);
2367 
2368 	// delete user-defined timers
2369 	thread->DeleteUserTimers(true);
2370 
2371 	// cancel pre-defined timer
2372 	if (UserTimer* timer = thread->UserTimerFor(USER_TIMER_REAL_TIME_ID))
2373 		timer->Cancel();
2374 
2375 	// reset user_thread and user stack
2376 	thread->user_thread = NULL;
2377 	thread->user_stack_area = -1;
2378 	thread->user_stack_base = 0;
2379 	thread->user_stack_size = 0;
2380 
2381 	// reset signals
2382 	thread->ResetSignalsOnExec();
2383 
2384 	// reset thread CPU time clock
2385 	InterruptsSpinLocker timeLocker(thread->time_lock);
2386 	thread->cpu_clock_offset = -thread->CPUTime(false);
2387 }
2388 
2389 
2390 thread_id
2391 allocate_thread_id()
2392 {
2393 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
2394 
2395 	// find the next unused ID
2396 	thread_id id;
2397 	do {
2398 		id = sNextThreadID++;
2399 
2400 		// deal with integer overflow
2401 		if (sNextThreadID < 0)
2402 			sNextThreadID = 2;
2403 
2404 		// check whether the ID is already in use
2405 	} while (sThreadHash.Lookup(id, false) != NULL);
2406 
2407 	return id;
2408 }
2409 
2410 
2411 thread_id
2412 peek_next_thread_id()
2413 {
2414 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
2415 	return sNextThreadID;
2416 }
2417 
2418 
2419 /*!	Yield the CPU to other threads.
2420 	Thread will continue to run, if there's no other thread in ready
2421 	state, and if it has a higher priority than the other ready threads, it
2422 	still has a good chance to continue.
2423 */
2424 void
2425 thread_yield(void)
2426 {
2427 	Thread *thread = thread_get_current_thread();
2428 	if (thread == NULL)
2429 		return;
2430 
2431 	InterruptsSpinLocker _(thread->scheduler_lock);
2432 
2433 	thread->has_yielded = true;
2434 	scheduler_reschedule(B_THREAD_READY);
2435 }
2436 
2437 
2438 void
2439 thread_map(void (*function)(Thread* thread, void* data), void* data)
2440 {
2441 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
2442 
2443 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
2444 		Thread* thread = it.Next();) {
2445 		function(thread, data);
2446 	}
2447 }
2448 
2449 
2450 /*!	Kernel private thread creation function.
2451 */
2452 thread_id
2453 spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority,
2454 	void *arg, team_id team)
2455 {
2456 	return thread_create_thread(
2457 		ThreadCreationAttributes(function, name, priority, arg, team),
2458 		true);
2459 }
2460 
2461 
2462 status_t
2463 wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
2464 	status_t *_returnCode)
2465 {
2466 	if (id < 0)
2467 		return B_BAD_THREAD_ID;
2468 
2469 	// get the thread, queue our death entry, and fetch the semaphore we have to
2470 	// wait on
2471 	sem_id exitSem = B_BAD_THREAD_ID;
2472 	struct thread_death_entry death;
2473 
2474 	Thread* thread = Thread::GetAndLock(id);
2475 	if (thread != NULL) {
2476 		// remember the semaphore we have to wait on and place our death entry
2477 		exitSem = thread->exit.sem;
2478 		if (exitSem >= 0)
2479 			list_add_link_to_head(&thread->exit.waiters, &death);
2480 
2481 		thread->UnlockAndReleaseReference();
2482 
2483 		if (exitSem < 0)
2484 			return B_BAD_THREAD_ID;
2485 	} else {
2486 		// we couldn't find this thread -- maybe it's already gone, and we'll
2487 		// find its death entry in our team
2488 		Team* team = thread_get_current_thread()->team;
2489 		TeamLocker teamLocker(team);
2490 
2491 		// check the child death entries first (i.e. main threads of child
2492 		// teams)
2493 		bool deleteEntry;
2494 		job_control_entry* freeDeath
2495 			= team_get_death_entry(team, id, &deleteEntry);
2496 		if (freeDeath != NULL) {
2497 			death.status = freeDeath->status;
2498 			if (deleteEntry)
2499 				delete freeDeath;
2500 		} else {
2501 			// check the thread death entries of the team (non-main threads)
2502 			thread_death_entry* threadDeathEntry = NULL;
2503 			while ((threadDeathEntry = (thread_death_entry*)list_get_next_item(
2504 					&team->dead_threads, threadDeathEntry)) != NULL) {
2505 				if (threadDeathEntry->thread == id) {
2506 					list_remove_item(&team->dead_threads, threadDeathEntry);
2507 					team->dead_threads_count--;
2508 					death.status = threadDeathEntry->status;
2509 					free(threadDeathEntry);
2510 					break;
2511 				}
2512 			}
2513 
2514 			if (threadDeathEntry == NULL)
2515 				return B_BAD_THREAD_ID;
2516 		}
2517 
2518 		// we found the thread's death entry in our team
2519 		if (_returnCode)
2520 			*_returnCode = death.status;
2521 
2522 		return B_OK;
2523 	}
2524 
2525 	// we need to wait for the death of the thread
2526 
2527 	resume_thread(id);
2528 		// make sure we don't wait forever on a suspended thread
2529 
2530 	status_t status = acquire_sem_etc(exitSem, 1, flags, timeout);
2531 
2532 	if (status == B_OK) {
2533 		// this should never happen as the thread deletes the semaphore on exit
2534 		panic("could acquire exit_sem for thread %" B_PRId32 "\n", id);
2535 	} else if (status == B_BAD_SEM_ID) {
2536 		// this is the way the thread normally exits
2537 		status = B_OK;
2538 	} else {
2539 		// We were probably interrupted or the timeout occurred; we need to
2540 		// remove our death entry now.
2541 		thread = Thread::GetAndLock(id);
2542 		if (thread != NULL) {
2543 			list_remove_link(&death);
2544 			thread->UnlockAndReleaseReference();
2545 		} else {
2546 			// The thread is already gone, so we need to wait uninterruptibly
2547 			// for its exit semaphore to make sure our death entry stays valid.
2548 			// It won't take long, since the thread is apparently already in the
2549 			// middle of the cleanup.
2550 			acquire_sem(exitSem);
2551 			status = B_OK;
2552 		}
2553 	}
2554 
2555 	if (status == B_OK && _returnCode != NULL)
2556 		*_returnCode = death.status;
2557 
2558 	return status;
2559 }
2560 
2561 
2562 status_t
2563 select_thread(int32 id, struct select_info* info, bool kernel)
2564 {
2565 	// get and lock the thread
2566 	Thread* thread = Thread::GetAndLock(id);
2567 	if (thread == NULL)
2568 		return B_BAD_THREAD_ID;
2569 	BReference<Thread> threadReference(thread, true);
2570 	ThreadLocker threadLocker(thread, true);
2571 
2572 	// We support only B_EVENT_INVALID at the moment.
2573 	info->selected_events &= B_EVENT_INVALID;
2574 
2575 	// add info to list
2576 	if (info->selected_events != 0) {
2577 		info->next = thread->select_infos;
2578 		thread->select_infos = info;
2579 
2580 		// we need a sync reference
2581 		atomic_add(&info->sync->ref_count, 1);
2582 	}
2583 
2584 	return B_OK;
2585 }
2586 
2587 
2588 status_t
2589 deselect_thread(int32 id, struct select_info* info, bool kernel)
2590 {
2591 	// get and lock the thread
2592 	Thread* thread = Thread::GetAndLock(id);
2593 	if (thread == NULL)
2594 		return B_BAD_THREAD_ID;
2595 	BReference<Thread> threadReference(thread, true);
2596 	ThreadLocker threadLocker(thread, true);
2597 
2598 	// remove info from list
2599 	select_info** infoLocation = &thread->select_infos;
2600 	while (*infoLocation != NULL && *infoLocation != info)
2601 		infoLocation = &(*infoLocation)->next;
2602 
2603 	if (*infoLocation != info)
2604 		return B_OK;
2605 
2606 	*infoLocation = info->next;
2607 
2608 	threadLocker.Unlock();
2609 
2610 	// surrender sync reference
2611 	put_select_sync(info->sync);
2612 
2613 	return B_OK;
2614 }
2615 
2616 
2617 int32
2618 thread_max_threads(void)
2619 {
2620 	return sMaxThreads;
2621 }
2622 
2623 
2624 int32
2625 thread_used_threads(void)
2626 {
2627 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
2628 	return sUsedThreads;
2629 }
2630 
2631 
2632 /*!	Returns a user-readable string for a thread state.
2633 	Only for use in the kernel debugger.
2634 */
2635 const char*
2636 thread_state_to_text(Thread* thread, int32 state)
2637 {
2638 	return state_to_text(thread, state);
2639 }
2640 
2641 
2642 int32
2643 thread_get_io_priority(thread_id id)
2644 {
2645 	Thread* thread = Thread::GetAndLock(id);
2646 	if (thread == NULL)
2647 		return B_BAD_THREAD_ID;
2648 	BReference<Thread> threadReference(thread, true);
2649 	ThreadLocker threadLocker(thread, true);
2650 
2651 	int32 priority = thread->io_priority;
2652 	if (priority < 0) {
2653 		// negative I/O priority means using the (CPU) priority
2654 		priority = thread->priority;
2655 	}
2656 
2657 	return priority;
2658 }
2659 
2660 
2661 void
2662 thread_set_io_priority(int32 priority)
2663 {
2664 	Thread* thread = thread_get_current_thread();
2665 	ThreadLocker threadLocker(thread);
2666 
2667 	thread->io_priority = priority;
2668 }
2669 
2670 
2671 status_t
2672 thread_init(kernel_args *args)
2673 {
2674 	TRACE(("thread_init: entry\n"));
2675 
2676 	// create the thread hash table
2677 	new(&sThreadHash) ThreadHashTable();
2678 	if (sThreadHash.Init(128) != B_OK)
2679 		panic("thread_init(): failed to init thread hash table!");
2680 
2681 	// create the thread structure object cache
2682 	sThreadCache = create_object_cache("threads", sizeof(Thread), 64, NULL,
2683 		NULL, NULL);
2684 		// Note: The x86 port requires 64 byte alignment of thread structures.
2685 	if (sThreadCache == NULL)
2686 		panic("thread_init(): failed to allocate thread object cache!");
2687 
2688 	if (arch_thread_init(args) < B_OK)
2689 		panic("arch_thread_init() failed!\n");
2690 
2691 	// skip all thread IDs including B_SYSTEM_TEAM, which is reserved
2692 	sNextThreadID = B_SYSTEM_TEAM + 1;
2693 
2694 	// create an idle thread for each cpu
2695 	for (uint32 i = 0; i < args->num_cpus; i++) {
2696 		Thread *thread;
2697 		area_info info;
2698 		char name[64];
2699 
2700 		sprintf(name, "idle thread %" B_PRIu32, i + 1);
2701 		thread = new(&sIdleThreads[i]) Thread(name,
2702 			i == 0 ? team_get_kernel_team_id() : -1, &gCPU[i]);
2703 		if (thread == NULL || thread->Init(true) != B_OK) {
2704 			panic("error creating idle thread struct\n");
2705 			return B_NO_MEMORY;
2706 		}
2707 
2708 		gCPU[i].running_thread = thread;
2709 
2710 		thread->team = team_get_kernel_team();
2711 		thread->priority = B_IDLE_PRIORITY;
2712 		thread->state = B_THREAD_RUNNING;
2713 		sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1);
2714 		thread->kernel_stack_area = find_area(name);
2715 
2716 		if (get_area_info(thread->kernel_stack_area, &info) != B_OK)
2717 			panic("error finding idle kstack area\n");
2718 
2719 		thread->kernel_stack_base = (addr_t)info.address;
2720 		thread->kernel_stack_top = thread->kernel_stack_base + info.size;
2721 
2722 		thread->visible = true;
2723 		insert_thread_into_team(thread->team, thread);
2724 
2725 		scheduler_on_thread_init(thread);
2726 	}
2727 	sUsedThreads = args->num_cpus;
2728 
2729 	// init the notification service
2730 	new(&sNotificationService) ThreadNotificationService();
2731 
2732 	sNotificationService.Register();
2733 
2734 	// start the undertaker thread
2735 	new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>();
2736 	sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries");
2737 
2738 	thread_id undertakerThread = spawn_kernel_thread(&undertaker, "undertaker",
2739 		B_DISPLAY_PRIORITY, NULL);
2740 	if (undertakerThread < 0)
2741 		panic("Failed to create undertaker thread!");
2742 	resume_thread(undertakerThread);
2743 
2744 	// set up some debugger commands
2745 	add_debugger_command_etc("threads", &dump_thread_list, "List all threads",
2746 		"[ <team> ]\n"
2747 		"Prints a list of all existing threads, or, if a team ID is given,\n"
2748 		"all threads of the specified team.\n"
2749 		"  <team>  - The ID of the team whose threads shall be listed.\n", 0);
2750 	add_debugger_command_etc("ready", &dump_thread_list,
2751 		"List all ready threads",
2752 		"\n"
2753 		"Prints a list of all threads in ready state.\n", 0);
2754 	add_debugger_command_etc("running", &dump_thread_list,
2755 		"List all running threads",
2756 		"\n"
2757 		"Prints a list of all threads in running state.\n", 0);
2758 	add_debugger_command_etc("waiting", &dump_thread_list,
2759 		"List all waiting threads (optionally for a specific semaphore)",
2760 		"[ <sem> ]\n"
2761 		"Prints a list of all threads in waiting state. If a semaphore is\n"
2762 		"specified, only the threads waiting on that semaphore are listed.\n"
2763 		"  <sem>  - ID of the semaphore.\n", 0);
2764 	add_debugger_command_etc("realtime", &dump_thread_list,
2765 		"List all realtime threads",
2766 		"\n"
2767 		"Prints a list of all threads with realtime priority.\n", 0);
2768 	add_debugger_command_etc("thread", &dump_thread_info,
2769 		"Dump info about a particular thread",
2770 		"[ -s ] ( <id> | <address> | <name> )*\n"
2771 		"Prints information about the specified thread. If no argument is\n"
2772 		"given the current thread is selected.\n"
2773 		"  -s         - Print info in compact table form (like \"threads\").\n"
2774 		"  <id>       - The ID of the thread.\n"
2775 		"  <address>  - The address of the thread structure.\n"
2776 		"  <name>     - The thread's name.\n", 0);
2777 	add_debugger_command_etc("calling", &dump_thread_list,
2778 		"Show all threads that have a specific address in their call chain",
2779 		"{ <symbol-pattern> | <start> <end> }\n", 0);
2780 	add_debugger_command_etc("unreal", &make_thread_unreal,
2781 		"Set realtime priority threads to normal priority",
2782 		"[ <id> ]\n"
2783 		"Sets the priority of all realtime threads or, if given, the one\n"
2784 		"with the specified ID to \"normal\" priority.\n"
2785 		"  <id>  - The ID of the thread.\n", 0);
2786 	add_debugger_command_etc("suspend", &make_thread_suspended,
2787 		"Suspend a thread",
2788 		"[ <id> ]\n"
2789 		"Suspends the thread with the given ID. If no ID argument is given\n"
2790 		"the current thread is selected.\n"
2791 		"  <id>  - The ID of the thread.\n", 0);
2792 	add_debugger_command_etc("resume", &make_thread_resumed, "Resume a thread",
2793 		"<id>\n"
2794 		"Resumes the specified thread, if it is currently suspended.\n"
2795 		"  <id>  - The ID of the thread.\n", 0);
2796 	add_debugger_command_etc("drop", &drop_into_debugger,
2797 		"Drop a thread into the userland debugger",
2798 		"<id>\n"
2799 		"Drops the specified (userland) thread into the userland debugger\n"
2800 		"after leaving the kernel debugger.\n"
2801 		"  <id>  - The ID of the thread.\n", 0);
2802 	add_debugger_command_etc("priority", &set_thread_prio,
2803 		"Set a thread's priority",
2804 		"<priority> [ <id> ]\n"
2805 		"Sets the priority of the thread with the specified ID to the given\n"
2806 		"priority. If no thread ID is given, the current thread is selected.\n"
2807 		"  <priority>  - The thread's new priority (0 - 120)\n"
2808 		"  <id>        - The ID of the thread.\n", 0);
2809 
2810 	return B_OK;
2811 }
2812 
2813 
2814 status_t
2815 thread_preboot_init_percpu(struct kernel_args *args, int32 cpuNum)
2816 {
2817 	// set up the cpu pointer in the not yet initialized per-cpu idle thread
2818 	// so that get_current_cpu and friends will work, which is crucial for
2819 	// a lot of low level routines
2820 	sIdleThreads[cpuNum].cpu = &gCPU[cpuNum];
2821 	arch_thread_set_current_thread(&sIdleThreads[cpuNum]);
2822 	return B_OK;
2823 }
2824 
2825 
2826 //	#pragma mark - thread blocking API
2827 
2828 
2829 static status_t
2830 thread_block_timeout(timer* timer)
2831 {
2832 	Thread* thread = (Thread*)timer->user_data;
2833 	thread_unblock(thread, B_TIMED_OUT);
2834 
2835 	return B_HANDLED_INTERRUPT;
2836 }
2837 
2838 
2839 /*!	Blocks the current thread.
2840 
2841 	The thread is blocked until someone else unblock it. Must be called after a
2842 	call to thread_prepare_to_block(). If the thread has already been unblocked
2843 	after the previous call to thread_prepare_to_block(), this function will
2844 	return immediately. Cf. the documentation of thread_prepare_to_block() for
2845 	more details.
2846 
2847 	The caller must hold the scheduler lock.
2848 
2849 	\param thread The current thread.
2850 	\return The error code passed to the unblocking function. thread_interrupt()
2851 		uses \c B_INTERRUPTED. By convention \c B_OK means that the wait was
2852 		successful while another error code indicates a failure (what that means
2853 		depends on the client code).
2854 */
2855 static inline status_t
2856 thread_block_locked(Thread* thread)
2857 {
2858 	if (thread->wait.status == 1) {
2859 		// check for signals, if interruptible
2860 		if (thread_is_interrupted(thread, thread->wait.flags)) {
2861 			thread->wait.status = B_INTERRUPTED;
2862 		} else
2863 			scheduler_reschedule(B_THREAD_WAITING);
2864 	}
2865 
2866 	return thread->wait.status;
2867 }
2868 
2869 
2870 /*!	Blocks the current thread.
2871 
2872 	The function acquires the scheduler lock and calls thread_block_locked().
2873 	See there for more information.
2874 */
2875 status_t
2876 thread_block()
2877 {
2878 	InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock);
2879 	return thread_block_locked(thread_get_current_thread());
2880 }
2881 
2882 
2883 /*!	Blocks the current thread with a timeout.
2884 
2885 	The current thread is blocked until someone else unblock it or the specified
2886 	timeout occurs. Must be called after a call to thread_prepare_to_block(). If
2887 	the thread has already been unblocked after the previous call to
2888 	thread_prepare_to_block(), this function will return immediately. See
2889 	thread_prepare_to_block() for more details.
2890 
2891 	The caller must not hold the scheduler lock.
2892 
2893 	\param timeoutFlags The standard timeout flags:
2894 		- \c B_RELATIVE_TIMEOUT: \a timeout specifies the time to wait.
2895 		- \c B_ABSOLUTE_TIMEOUT: \a timeout specifies the absolute end time when
2896 			the timeout shall occur.
2897 		- \c B_TIMEOUT_REAL_TIME_BASE: Only relevant when \c B_ABSOLUTE_TIMEOUT
2898 			is specified, too. Specifies that \a timeout is a real time, not a
2899 			system time.
2900 		If neither \c B_RELATIVE_TIMEOUT nor \c B_ABSOLUTE_TIMEOUT are
2901 		specified, an infinite timeout is implied and the function behaves like
2902 		thread_block_locked().
2903 	\return The error code passed to the unblocking function. thread_interrupt()
2904 		uses \c B_INTERRUPTED. When the timeout occurred, \c B_TIMED_OUT is
2905 		returned. By convention \c B_OK means that the wait was successful while
2906 		another error code indicates a failure (what that means depends on the
2907 		client code).
2908 */
2909 status_t
2910 thread_block_with_timeout(uint32 timeoutFlags, bigtime_t timeout)
2911 {
2912 	Thread* thread = thread_get_current_thread();
2913 
2914 	InterruptsSpinLocker locker(thread->scheduler_lock);
2915 
2916 	if (thread->wait.status != 1)
2917 		return thread->wait.status;
2918 
2919 	bool useTimer = (timeoutFlags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT))
2920 		&& timeout != B_INFINITE_TIMEOUT;
2921 
2922 	if (useTimer) {
2923 		// Timer flags: absolute/relative.
2924 		uint32 timerFlags;
2925 		if ((timeoutFlags & B_RELATIVE_TIMEOUT) != 0) {
2926 			timerFlags = B_ONE_SHOT_RELATIVE_TIMER;
2927 		} else {
2928 			timerFlags = B_ONE_SHOT_ABSOLUTE_TIMER;
2929 			if ((timeoutFlags & B_TIMEOUT_REAL_TIME_BASE) != 0)
2930 				timerFlags |= B_TIMER_REAL_TIME_BASE;
2931 		}
2932 
2933 		// install the timer
2934 		thread->wait.unblock_timer.user_data = thread;
2935 		add_timer(&thread->wait.unblock_timer, &thread_block_timeout, timeout,
2936 			timerFlags);
2937 	}
2938 
2939 	// block
2940 	status_t error = thread_block_locked(thread);
2941 
2942 	locker.Unlock();
2943 
2944 	// cancel timer, if it didn't fire
2945 	if (error != B_TIMED_OUT && useTimer)
2946 		cancel_timer(&thread->wait.unblock_timer);
2947 
2948 	return error;
2949 }
2950 
2951 
2952 /*!	Unblocks a thread.
2953 
2954 	Acquires the scheduler lock and calls thread_unblock_locked().
2955 	See there for more information.
2956 */
2957 void
2958 thread_unblock(Thread* thread, status_t status)
2959 {
2960 	InterruptsSpinLocker locker(thread->scheduler_lock);
2961 	thread_unblock_locked(thread, status);
2962 }
2963 
2964 
2965 /*!	Unblocks a userland-blocked thread.
2966 	The caller must not hold any locks.
2967 */
2968 static status_t
2969 user_unblock_thread(thread_id threadID, status_t status)
2970 {
2971 	// get the thread
2972 	Thread* thread = Thread::GetAndLock(threadID);
2973 	if (thread == NULL)
2974 		return B_BAD_THREAD_ID;
2975 	BReference<Thread> threadReference(thread, true);
2976 	ThreadLocker threadLocker(thread, true);
2977 
2978 	if (thread->user_thread == NULL)
2979 		return B_NOT_ALLOWED;
2980 
2981 	InterruptsSpinLocker locker(thread->scheduler_lock);
2982 
2983 	set_ac();
2984 	if (thread->user_thread->wait_status > 0) {
2985 		thread->user_thread->wait_status = status;
2986 		clear_ac();
2987 
2988 		// Even if the user_thread->wait_status was > 0, it may be the
2989 		// case that this thread is actually blocked on something else.
2990 		if (thread->wait.status > 0
2991 				&& thread->wait.type == THREAD_BLOCK_TYPE_USER) {
2992 			thread_unblock_locked(thread, status);
2993 		}
2994 	} else
2995 		clear_ac();
2996 
2997 	return B_OK;
2998 }
2999 
3000 
3001 static bool
3002 thread_check_permissions(const Thread* currentThread, const Thread* thread,
3003 	bool kernel)
3004 {
3005 	if (kernel)
3006 		return true;
3007 
3008 	if (thread->team->id == team_get_kernel_team_id())
3009 		return false;
3010 
3011 	if (thread->team == currentThread->team
3012 			|| currentThread->team->effective_uid == 0
3013 			|| thread->team->real_uid == currentThread->team->real_uid)
3014 		return true;
3015 
3016 	return false;
3017 }
3018 
3019 
3020 static status_t
3021 thread_send_signal(thread_id id, uint32 number, int32 signalCode,
3022 	int32 errorCode, bool kernel)
3023 {
3024 	if (id <= 0)
3025 		return B_BAD_VALUE;
3026 
3027 	Thread* currentThread = thread_get_current_thread();
3028 	Thread* thread = Thread::Get(id);
3029 	if (thread == NULL)
3030 		return B_BAD_THREAD_ID;
3031 	BReference<Thread> threadReference(thread, true);
3032 
3033 	// check whether sending the signal is allowed
3034 	if (!thread_check_permissions(currentThread, thread, kernel))
3035 		return B_NOT_ALLOWED;
3036 
3037 	Signal signal(number, signalCode, errorCode, currentThread->team->id);
3038 	return send_signal_to_thread(thread, signal, 0);
3039 }
3040 
3041 
3042 //	#pragma mark - public kernel API
3043 
3044 
3045 void
3046 exit_thread(status_t returnValue)
3047 {
3048 	Thread *thread = thread_get_current_thread();
3049 	Team* team = thread->team;
3050 
3051 	thread->exit.status = returnValue;
3052 
3053 	// if called from a kernel thread, we don't deliver the signal,
3054 	// we just exit directly to keep the user space behaviour of
3055 	// this function
3056 	if (team != team_get_kernel_team()) {
3057 		// If this is its main thread, set the team's exit status.
3058 		if (thread == team->main_thread) {
3059 			TeamLocker teamLocker(team);
3060 
3061 			if (!team->exit.initialized) {
3062 				team->exit.reason = CLD_EXITED;
3063 				team->exit.signal = 0;
3064 				team->exit.signaling_user = 0;
3065 				team->exit.status = returnValue;
3066 				team->exit.initialized = true;
3067 			}
3068 
3069 			teamLocker.Unlock();
3070 		}
3071 
3072 		Signal signal(SIGKILLTHR, SI_USER, B_OK, team->id);
3073 		send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE);
3074 	} else
3075 		thread_exit();
3076 }
3077 
3078 
3079 static status_t
3080 thread_kill_thread(thread_id id, bool kernel)
3081 {
3082 	return thread_send_signal(id, SIGKILLTHR, SI_USER, B_OK, kernel);
3083 }
3084 
3085 
3086 status_t
3087 kill_thread(thread_id id)
3088 {
3089 	return thread_kill_thread(id, true);
3090 }
3091 
3092 
3093 status_t
3094 send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize)
3095 {
3096 	return send_data_etc(thread, code, buffer, bufferSize, 0);
3097 }
3098 
3099 
3100 int32
3101 receive_data(thread_id *sender, void *buffer, size_t bufferSize)
3102 {
3103 	return receive_data_etc(sender, buffer, bufferSize, 0);
3104 }
3105 
3106 
3107 static bool
3108 thread_has_data(thread_id id, bool kernel)
3109 {
3110 	Thread* currentThread = thread_get_current_thread();
3111 	Thread* thread;
3112 	BReference<Thread> threadReference;
3113 	if (id == currentThread->id) {
3114 		thread = currentThread;
3115 	} else {
3116 		thread = Thread::Get(id);
3117 		if (thread == NULL)
3118 			return false;
3119 
3120 		threadReference.SetTo(thread, true);
3121 	}
3122 
3123 	if (!kernel && thread->team != currentThread->team)
3124 		return false;
3125 
3126 	int32 count;
3127 	if (get_sem_count(thread->msg.read_sem, &count) != B_OK)
3128 		return false;
3129 
3130 	return count == 0 ? false : true;
3131 }
3132 
3133 
3134 bool
3135 has_data(thread_id thread)
3136 {
3137 	return thread_has_data(thread, true);
3138 }
3139 
3140 
3141 status_t
3142 _get_thread_info(thread_id id, thread_info *info, size_t size)
3143 {
3144 	if (info == NULL || size != sizeof(thread_info) || id < B_OK)
3145 		return B_BAD_VALUE;
3146 
3147 	// get the thread
3148 	Thread* thread = Thread::GetAndLock(id);
3149 	if (thread == NULL)
3150 		return B_BAD_THREAD_ID;
3151 	BReference<Thread> threadReference(thread, true);
3152 	ThreadLocker threadLocker(thread, true);
3153 
3154 	// fill the info -- also requires the scheduler lock to be held
3155 	InterruptsSpinLocker locker(thread->scheduler_lock);
3156 
3157 	fill_thread_info(thread, info, size);
3158 
3159 	return B_OK;
3160 }
3161 
3162 
3163 status_t
3164 _get_next_thread_info(team_id teamID, int32 *_cookie, thread_info *info,
3165 	size_t size)
3166 {
3167 	if (info == NULL || size != sizeof(thread_info) || teamID < 0)
3168 		return B_BAD_VALUE;
3169 
3170 	int32 lastID = *_cookie;
3171 
3172 	// get the team
3173 	Team* team = Team::GetAndLock(teamID);
3174 	if (team == NULL)
3175 		return B_BAD_VALUE;
3176 	BReference<Team> teamReference(team, true);
3177 	TeamLocker teamLocker(team, true);
3178 
3179 	Thread* thread = NULL;
3180 
3181 	if (lastID == 0) {
3182 		// We start with the main thread
3183 		thread = team->main_thread;
3184 	} else {
3185 		// Find the one thread with an ID greater than ours (as long as the IDs
3186 		// don't wrap they are always sorted from highest to lowest).
3187 		// TODO: That is broken not only when the IDs wrap, but also for the
3188 		// kernel team, to which threads are added when they are dying.
3189 		for (Thread* next = team->thread_list; next != NULL;
3190 				next = next->team_next) {
3191 			if (next->id <= lastID)
3192 				break;
3193 
3194 			thread = next;
3195 		}
3196 	}
3197 
3198 	if (thread == NULL)
3199 		return B_BAD_VALUE;
3200 
3201 	lastID = thread->id;
3202 	*_cookie = lastID;
3203 
3204 	ThreadLocker threadLocker(thread);
3205 	InterruptsSpinLocker locker(thread->scheduler_lock);
3206 
3207 	fill_thread_info(thread, info, size);
3208 
3209 	return B_OK;
3210 }
3211 
3212 
3213 thread_id
3214 find_thread(const char* name)
3215 {
3216 	if (name == NULL)
3217 		return thread_get_current_thread_id();
3218 
3219 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
3220 
3221 	// Scanning the whole hash with the thread hash lock held isn't exactly
3222 	// cheap, but since this function is probably used very rarely, and we
3223 	// only need a read lock, it's probably acceptable.
3224 
3225 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
3226 			Thread* thread = it.Next();) {
3227 		if (!thread->visible)
3228 			continue;
3229 
3230 		if (strcmp(thread->name, name) == 0)
3231 			return thread->id;
3232 	}
3233 
3234 	return B_NAME_NOT_FOUND;
3235 }
3236 
3237 
3238 status_t
3239 rename_thread(thread_id id, const char* name)
3240 {
3241 	if (name == NULL)
3242 		return B_BAD_VALUE;
3243 
3244 	// get the thread
3245 	Thread* thread = Thread::GetAndLock(id);
3246 	if (thread == NULL)
3247 		return B_BAD_THREAD_ID;
3248 	BReference<Thread> threadReference(thread, true);
3249 	ThreadLocker threadLocker(thread, true);
3250 
3251 	// check whether the operation is allowed
3252 	if (thread->team != thread_get_current_thread()->team)
3253 		return B_NOT_ALLOWED;
3254 
3255 	strlcpy(thread->name, name, B_OS_NAME_LENGTH);
3256 
3257 	team_id teamID = thread->team->id;
3258 
3259 	threadLocker.Unlock();
3260 
3261 	// notify listeners
3262 	sNotificationService.Notify(THREAD_NAME_CHANGED, teamID, id);
3263 		// don't pass the thread structure, as it's unsafe, if it isn't ours
3264 
3265 	return B_OK;
3266 }
3267 
3268 
3269 static status_t
3270 thread_set_thread_priority(thread_id id, int32 priority, bool kernel)
3271 {
3272 	// make sure the passed in priority is within bounds
3273 	if (priority > THREAD_MAX_SET_PRIORITY)
3274 		priority = THREAD_MAX_SET_PRIORITY;
3275 	if (priority < THREAD_MIN_SET_PRIORITY)
3276 		priority = THREAD_MIN_SET_PRIORITY;
3277 
3278 	// get the thread
3279 	Thread* thread = Thread::GetAndLock(id);
3280 	if (thread == NULL)
3281 		return B_BAD_THREAD_ID;
3282 	BReference<Thread> threadReference(thread, true);
3283 	ThreadLocker threadLocker(thread, true);
3284 
3285 	// check whether the change is allowed
3286 	if (thread_is_idle_thread(thread) || !thread_check_permissions(
3287 			thread_get_current_thread(), thread, kernel))
3288 		return B_NOT_ALLOWED;
3289 
3290 	return scheduler_set_thread_priority(thread, priority);
3291 }
3292 
3293 
3294 status_t
3295 set_thread_priority(thread_id id, int32 priority)
3296 {
3297 	return thread_set_thread_priority(id, priority, true);
3298 }
3299 
3300 
3301 status_t
3302 snooze_etc(bigtime_t timeout, int timebase, uint32 flags)
3303 {
3304 	return common_snooze_etc(timeout, timebase, flags, NULL);
3305 }
3306 
3307 
3308 /*!	snooze() for internal kernel use only; doesn't interrupt on signals. */
3309 status_t
3310 snooze(bigtime_t timeout)
3311 {
3312 	return snooze_etc(timeout, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT);
3313 }
3314 
3315 
3316 /*!	snooze_until() for internal kernel use only; doesn't interrupt on
3317 	signals.
3318 */
3319 status_t
3320 snooze_until(bigtime_t timeout, int timebase)
3321 {
3322 	return snooze_etc(timeout, timebase, B_ABSOLUTE_TIMEOUT);
3323 }
3324 
3325 
3326 status_t
3327 wait_for_thread(thread_id thread, status_t *_returnCode)
3328 {
3329 	return wait_for_thread_etc(thread, 0, 0, _returnCode);
3330 }
3331 
3332 
3333 static status_t
3334 thread_suspend_thread(thread_id id, bool kernel)
3335 {
3336 	return thread_send_signal(id, SIGSTOP, SI_USER, B_OK, kernel);
3337 }
3338 
3339 
3340 status_t
3341 suspend_thread(thread_id id)
3342 {
3343 	return thread_suspend_thread(id, true);
3344 }
3345 
3346 
3347 static status_t
3348 thread_resume_thread(thread_id id, bool kernel)
3349 {
3350 	// Using the kernel internal SIGNAL_CONTINUE_THREAD signal retains
3351 	// compatibility to BeOS which documents the combination of suspend_thread()
3352 	// and resume_thread() to interrupt threads waiting on semaphores.
3353 	return thread_send_signal(id, SIGNAL_CONTINUE_THREAD, SI_USER, B_OK, kernel);
3354 }
3355 
3356 
3357 status_t
3358 resume_thread(thread_id id)
3359 {
3360 	return thread_resume_thread(id, true);
3361 }
3362 
3363 
3364 thread_id
3365 spawn_kernel_thread(thread_func function, const char *name, int32 priority,
3366 	void *arg)
3367 {
3368 	return thread_create_thread(
3369 		ThreadCreationAttributes(function, name, priority, arg),
3370 		true);
3371 }
3372 
3373 
3374 int
3375 getrlimit(int resource, struct rlimit * rlp)
3376 {
3377 	status_t error = common_getrlimit(resource, rlp);
3378 	if (error != B_OK) {
3379 		errno = error;
3380 		return -1;
3381 	}
3382 
3383 	return 0;
3384 }
3385 
3386 
3387 int
3388 setrlimit(int resource, const struct rlimit * rlp)
3389 {
3390 	status_t error = common_setrlimit(resource, rlp);
3391 	if (error != B_OK) {
3392 		errno = error;
3393 		return -1;
3394 	}
3395 
3396 	return 0;
3397 }
3398 
3399 
3400 //	#pragma mark - syscalls
3401 
3402 
3403 void
3404 _user_exit_thread(status_t returnValue)
3405 {
3406 	exit_thread(returnValue);
3407 }
3408 
3409 
3410 status_t
3411 _user_kill_thread(thread_id thread)
3412 {
3413 	return thread_kill_thread(thread, false);
3414 }
3415 
3416 
3417 status_t
3418 _user_cancel_thread(thread_id threadID, void (*cancelFunction)(int))
3419 {
3420 	// check the cancel function
3421 	if (cancelFunction == NULL || !IS_USER_ADDRESS(cancelFunction))
3422 		return B_BAD_VALUE;
3423 
3424 	// get and lock the thread
3425 	Thread* thread = Thread::GetAndLock(threadID);
3426 	if (thread == NULL)
3427 		return B_BAD_THREAD_ID;
3428 	BReference<Thread> threadReference(thread, true);
3429 	ThreadLocker threadLocker(thread, true);
3430 
3431 	// only threads of the same team can be canceled
3432 	if (thread->team != thread_get_current_thread()->team)
3433 		return B_NOT_ALLOWED;
3434 
3435 	// set the cancel function
3436 	thread->cancel_function = cancelFunction;
3437 
3438 	// send the cancellation signal to the thread
3439 	InterruptsReadSpinLocker teamLocker(thread->team_lock);
3440 	SpinLocker locker(thread->team->signal_lock);
3441 	return send_signal_to_thread_locked(thread, SIGNAL_CANCEL_THREAD, NULL, 0);
3442 }
3443 
3444 
3445 status_t
3446 _user_resume_thread(thread_id thread)
3447 {
3448 	return thread_resume_thread(thread, false);
3449 }
3450 
3451 
3452 status_t
3453 _user_suspend_thread(thread_id thread)
3454 {
3455 	return thread_suspend_thread(thread, false);
3456 }
3457 
3458 
3459 status_t
3460 _user_rename_thread(thread_id thread, const char *userName)
3461 {
3462 	char name[B_OS_NAME_LENGTH];
3463 
3464 	if (!IS_USER_ADDRESS(userName)
3465 		|| userName == NULL
3466 		|| user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK)
3467 		return B_BAD_ADDRESS;
3468 
3469 	// rename_thread() forbids thread renames across teams, so we don't
3470 	// need a "kernel" flag here.
3471 	return rename_thread(thread, name);
3472 }
3473 
3474 
3475 int32
3476 _user_set_thread_priority(thread_id thread, int32 newPriority)
3477 {
3478 	return thread_set_thread_priority(thread, newPriority, false);
3479 }
3480 
3481 
3482 thread_id
3483 _user_spawn_thread(thread_creation_attributes* userAttributes)
3484 {
3485 	// copy the userland structure to the kernel
3486 	char nameBuffer[B_OS_NAME_LENGTH];
3487 	ThreadCreationAttributes attributes;
3488 	status_t error = attributes.InitFromUserAttributes(userAttributes,
3489 		nameBuffer);
3490 	if (error != B_OK)
3491 		return error;
3492 
3493 	// create the thread
3494 	thread_id threadID = thread_create_thread(attributes, false);
3495 
3496 	if (threadID >= 0)
3497 		user_debug_thread_created(threadID);
3498 
3499 	return threadID;
3500 }
3501 
3502 
3503 status_t
3504 _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags,
3505 	bigtime_t* userRemainingTime)
3506 {
3507 	// We need to store more syscall restart parameters than usual and need a
3508 	// somewhat different handling. Hence we can't use
3509 	// syscall_restart_handle_timeout_pre() but do the job ourselves.
3510 	struct restart_parameters {
3511 		bigtime_t	timeout;
3512 		clockid_t	timebase;
3513 		uint32		flags;
3514 	};
3515 
3516 	Thread* thread = thread_get_current_thread();
3517 
3518 	if ((thread->flags & THREAD_FLAGS_SYSCALL_RESTARTED) != 0) {
3519 		// The syscall was restarted. Fetch the parameters from the stored
3520 		// restart parameters.
3521 		restart_parameters* restartParameters
3522 			= (restart_parameters*)thread->syscall_restart.parameters;
3523 		timeout = restartParameters->timeout;
3524 		timebase = restartParameters->timebase;
3525 		flags = restartParameters->flags;
3526 	} else {
3527 		// convert relative timeouts to absolute ones
3528 		if ((flags & B_RELATIVE_TIMEOUT) != 0) {
3529 			// not restarted yet and the flags indicate a relative timeout
3530 
3531 			// Make sure we use the system time base, so real-time clock changes
3532 			// won't affect our wait.
3533 			flags &= ~(uint32)B_TIMEOUT_REAL_TIME_BASE;
3534 			if (timebase == CLOCK_REALTIME)
3535 				timebase = CLOCK_MONOTONIC;
3536 
3537 			// get the current time and make the timeout absolute
3538 			bigtime_t now;
3539 			status_t error = user_timer_get_clock(timebase, now);
3540 			if (error != B_OK)
3541 				return error;
3542 
3543 			timeout += now;
3544 
3545 			// deal with overflow
3546 			if (timeout < 0)
3547 				timeout = B_INFINITE_TIMEOUT;
3548 
3549 			flags = (flags & ~B_RELATIVE_TIMEOUT) | B_ABSOLUTE_TIMEOUT;
3550 		} else
3551 			flags |= B_ABSOLUTE_TIMEOUT;
3552 	}
3553 
3554 	// snooze
3555 	bigtime_t remainingTime;
3556 	status_t error = common_snooze_etc(timeout, timebase,
3557 		flags | B_CAN_INTERRUPT | B_CHECK_PERMISSION,
3558 		userRemainingTime != NULL ? &remainingTime : NULL);
3559 
3560 	// If interrupted, copy the remaining time back to userland and prepare the
3561 	// syscall restart.
3562 	if (error == B_INTERRUPTED) {
3563 		if (userRemainingTime != NULL
3564 			&& (!IS_USER_ADDRESS(userRemainingTime)
3565 				|| user_memcpy(userRemainingTime, &remainingTime,
3566 					sizeof(remainingTime)) != B_OK)) {
3567 			return B_BAD_ADDRESS;
3568 		}
3569 
3570 		// store the normalized values in the restart parameters
3571 		restart_parameters* restartParameters
3572 			= (restart_parameters*)thread->syscall_restart.parameters;
3573 		restartParameters->timeout = timeout;
3574 		restartParameters->timebase = timebase;
3575 		restartParameters->flags = flags;
3576 
3577 		// restart the syscall, if possible
3578 		atomic_or(&thread->flags, THREAD_FLAGS_RESTART_SYSCALL);
3579 	}
3580 
3581 	return error;
3582 }
3583 
3584 
3585 void
3586 _user_thread_yield(void)
3587 {
3588 	thread_yield();
3589 }
3590 
3591 
3592 status_t
3593 _user_get_thread_info(thread_id id, thread_info *userInfo)
3594 {
3595 	thread_info info;
3596 	status_t status;
3597 
3598 	if (!IS_USER_ADDRESS(userInfo))
3599 		return B_BAD_ADDRESS;
3600 
3601 	status = _get_thread_info(id, &info, sizeof(thread_info));
3602 
3603 	if (status >= B_OK
3604 		&& user_memcpy(userInfo, &info, sizeof(thread_info)) < B_OK)
3605 		return B_BAD_ADDRESS;
3606 
3607 	return status;
3608 }
3609 
3610 
3611 status_t
3612 _user_get_next_thread_info(team_id team, int32 *userCookie,
3613 	thread_info *userInfo)
3614 {
3615 	status_t status;
3616 	thread_info info;
3617 	int32 cookie;
3618 
3619 	if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo)
3620 		|| user_memcpy(&cookie, userCookie, sizeof(int32)) < B_OK)
3621 		return B_BAD_ADDRESS;
3622 
3623 	status = _get_next_thread_info(team, &cookie, &info, sizeof(thread_info));
3624 	if (status < B_OK)
3625 		return status;
3626 
3627 	if (user_memcpy(userCookie, &cookie, sizeof(int32)) < B_OK
3628 		|| user_memcpy(userInfo, &info, sizeof(thread_info)) < B_OK)
3629 		return B_BAD_ADDRESS;
3630 
3631 	return status;
3632 }
3633 
3634 
3635 thread_id
3636 _user_find_thread(const char *userName)
3637 {
3638 	char name[B_OS_NAME_LENGTH];
3639 
3640 	if (userName == NULL)
3641 		return find_thread(NULL);
3642 
3643 	if (!IS_USER_ADDRESS(userName)
3644 		|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
3645 		return B_BAD_ADDRESS;
3646 
3647 	return find_thread(name);
3648 }
3649 
3650 
3651 status_t
3652 _user_wait_for_thread(thread_id id, status_t *userReturnCode)
3653 {
3654 	status_t returnCode;
3655 	status_t status;
3656 
3657 	if (userReturnCode != NULL && !IS_USER_ADDRESS(userReturnCode))
3658 		return B_BAD_ADDRESS;
3659 
3660 	status = wait_for_thread_etc(id, B_CAN_INTERRUPT, 0, &returnCode);
3661 
3662 	if (status == B_OK && userReturnCode != NULL
3663 		&& user_memcpy(userReturnCode, &returnCode, sizeof(status_t)) < B_OK) {
3664 		return B_BAD_ADDRESS;
3665 	}
3666 
3667 	return syscall_restart_handle_post(status);
3668 }
3669 
3670 
3671 bool
3672 _user_has_data(thread_id thread)
3673 {
3674 	return thread_has_data(thread, false);
3675 }
3676 
3677 
3678 status_t
3679 _user_send_data(thread_id thread, int32 code, const void *buffer,
3680 	size_t bufferSize)
3681 {
3682 	if (buffer != NULL && !IS_USER_ADDRESS(buffer))
3683 		return B_BAD_ADDRESS;
3684 
3685 	return send_data_etc(thread, code, buffer, bufferSize,
3686 		B_KILL_CAN_INTERRUPT);
3687 		// supports userland buffers
3688 }
3689 
3690 
3691 status_t
3692 _user_receive_data(thread_id *_userSender, void *buffer, size_t bufferSize)
3693 {
3694 	thread_id sender;
3695 	status_t code;
3696 
3697 	if ((!IS_USER_ADDRESS(_userSender) && _userSender != NULL)
3698 		|| (!IS_USER_ADDRESS(buffer) && buffer != NULL)) {
3699 		return B_BAD_ADDRESS;
3700 	}
3701 
3702 	code = receive_data_etc(&sender, buffer, bufferSize, B_KILL_CAN_INTERRUPT);
3703 		// supports userland buffers
3704 
3705 	if (_userSender != NULL)
3706 		if (user_memcpy(_userSender, &sender, sizeof(thread_id)) < B_OK)
3707 			return B_BAD_ADDRESS;
3708 
3709 	return code;
3710 }
3711 
3712 
3713 status_t
3714 _user_block_thread(uint32 flags, bigtime_t timeout)
3715 {
3716 	syscall_restart_handle_timeout_pre(flags, timeout);
3717 	flags |= B_CAN_INTERRUPT;
3718 
3719 	Thread* thread = thread_get_current_thread();
3720 	ThreadLocker threadLocker(thread);
3721 
3722 	// check, if already done
3723 	set_ac();
3724 	if (thread->user_thread->wait_status <= 0) {
3725 		status_t status = thread->user_thread->wait_status;
3726 		clear_ac();
3727 		return status;
3728 	}
3729 	clear_ac();
3730 
3731 	// nope, so wait
3732 	thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_USER, NULL);
3733 
3734 	threadLocker.Unlock();
3735 
3736 	status_t status = thread_block_with_timeout(flags, timeout);
3737 
3738 	threadLocker.Lock();
3739 
3740 	// Interruptions or timeouts can race with other threads unblocking us.
3741 	// Favor a wake-up by another thread, i.e. if someone changed the wait
3742 	// status, use that.
3743 	set_ac();
3744 	status_t oldStatus = thread->user_thread->wait_status;
3745 	if (oldStatus > 0) {
3746 		thread->user_thread->wait_status = status;
3747 		clear_ac();
3748 	} else {
3749 		clear_ac();
3750 		status = oldStatus;
3751 	}
3752 
3753 	threadLocker.Unlock();
3754 
3755 	return syscall_restart_handle_timeout_post(status, timeout);
3756 }
3757 
3758 
3759 status_t
3760 _user_unblock_thread(thread_id threadID, status_t status)
3761 {
3762 	status_t error = user_unblock_thread(threadID, status);
3763 
3764 	if (error == B_OK)
3765 		scheduler_reschedule_if_necessary();
3766 
3767 	return error;
3768 }
3769 
3770 
3771 status_t
3772 _user_unblock_threads(thread_id* userThreads, uint32 count, status_t status)
3773 {
3774 	enum {
3775 		MAX_USER_THREADS_TO_UNBLOCK	= 128
3776 	};
3777 
3778 	if (userThreads == NULL || !IS_USER_ADDRESS(userThreads))
3779 		return B_BAD_ADDRESS;
3780 	if (count > MAX_USER_THREADS_TO_UNBLOCK)
3781 		return B_BAD_VALUE;
3782 
3783 	thread_id threads[MAX_USER_THREADS_TO_UNBLOCK];
3784 	if (user_memcpy(threads, userThreads, count * sizeof(thread_id)) != B_OK)
3785 		return B_BAD_ADDRESS;
3786 
3787 	for (uint32 i = 0; i < count; i++)
3788 		user_unblock_thread(threads[i], status);
3789 
3790 	scheduler_reschedule_if_necessary();
3791 
3792 	return B_OK;
3793 }
3794 
3795 
3796 // TODO: the following two functions don't belong here
3797 
3798 
3799 int
3800 _user_getrlimit(int resource, struct rlimit *urlp)
3801 {
3802 	struct rlimit rl;
3803 	int ret;
3804 
3805 	if (urlp == NULL)
3806 		return EINVAL;
3807 
3808 	if (!IS_USER_ADDRESS(urlp))
3809 		return B_BAD_ADDRESS;
3810 
3811 	ret = common_getrlimit(resource, &rl);
3812 
3813 	if (ret == 0) {
3814 		ret = user_memcpy(urlp, &rl, sizeof(struct rlimit));
3815 		if (ret < 0)
3816 			return ret;
3817 
3818 		return 0;
3819 	}
3820 
3821 	return ret;
3822 }
3823 
3824 
3825 int
3826 _user_setrlimit(int resource, const struct rlimit *userResourceLimit)
3827 {
3828 	struct rlimit resourceLimit;
3829 
3830 	if (userResourceLimit == NULL)
3831 		return EINVAL;
3832 
3833 	if (!IS_USER_ADDRESS(userResourceLimit)
3834 		|| user_memcpy(&resourceLimit, userResourceLimit,
3835 			sizeof(struct rlimit)) < B_OK)
3836 		return B_BAD_ADDRESS;
3837 
3838 	return common_setrlimit(resource, &resourceLimit);
3839 }
3840