xref: /haiku/src/system/kernel/thread.cpp (revision 5b189b0e1e2f51f367bfcb126b2f00a3702f352d)
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_OTHER:
1703 					kprintf("other%*s", B_PRINTF_POINTER_WIDTH + 10, "");
1704 					break;
1705 
1706 				default:
1707 					kprintf("???       %p   ", thread->wait.object);
1708 					break;
1709 			}
1710 		} else
1711 			kprintf("-%*s", B_PRINTF_POINTER_WIDTH + 14, "");
1712 
1713 		// on which CPU does it run?
1714 		if (thread->cpu)
1715 			kprintf("%2d", thread->cpu->cpu_num);
1716 		else
1717 			kprintf(" -");
1718 
1719 		kprintf("%4" B_PRId32 "  %p%5" B_PRId32 "  %s\n", thread->priority,
1720 			(void *)thread->kernel_stack_base, thread->team->id, thread->name);
1721 
1722 		return;
1723 	}
1724 
1725 	// print the long info
1726 
1727 	struct thread_death_entry *death = NULL;
1728 
1729 	kprintf("THREAD: %p\n", thread);
1730 	kprintf("id:                 %" B_PRId32 " (%#" B_PRIx32 ")\n", thread->id,
1731 		thread->id);
1732 	kprintf("serial_number:      %" B_PRId64 "\n", thread->serial_number);
1733 	kprintf("name:               \"%s\"\n", thread->name);
1734 	kprintf("hash_next:          %p\nteam_next:          %p\n",
1735 		thread->hash_next, thread->team_next);
1736 	kprintf("priority:           %" B_PRId32 " (I/O: %" B_PRId32 ")\n",
1737 		thread->priority, thread->io_priority);
1738 	kprintf("state:              %s\n", state_to_text(thread, thread->state));
1739 	kprintf("cpu:                %p ", thread->cpu);
1740 	if (thread->cpu)
1741 		kprintf("(%d)\n", thread->cpu->cpu_num);
1742 	else
1743 		kprintf("\n");
1744 	kprintf("sig_pending:        %#" B_PRIx64 " (blocked: %#" B_PRIx64
1745 		", before sigsuspend(): %#" B_PRIx64 ")\n",
1746 		(int64)thread->ThreadPendingSignals(),
1747 		(int64)thread->sig_block_mask,
1748 		(int64)thread->sigsuspend_original_unblocked_mask);
1749 	kprintf("in_kernel:          %d\n", thread->in_kernel);
1750 
1751 	if (thread->state == B_THREAD_WAITING) {
1752 		kprintf("waiting for:        ");
1753 
1754 		switch (thread->wait.type) {
1755 			case THREAD_BLOCK_TYPE_SEMAPHORE:
1756 			{
1757 				sem_id sem = (sem_id)(addr_t)thread->wait.object;
1758 				if (sem == thread->msg.read_sem)
1759 					kprintf("data\n");
1760 				else
1761 					kprintf("semaphore %" B_PRId32 "\n", sem);
1762 				break;
1763 			}
1764 
1765 			case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1766 				kprintf("condition variable %p\n", thread->wait.object);
1767 				break;
1768 
1769 			case THREAD_BLOCK_TYPE_SNOOZE:
1770 				kprintf("snooze()\n");
1771 				break;
1772 
1773 			case THREAD_BLOCK_TYPE_SIGNAL:
1774 				kprintf("signal\n");
1775 				break;
1776 
1777 			case THREAD_BLOCK_TYPE_MUTEX:
1778 				kprintf("mutex %p\n", thread->wait.object);
1779 				break;
1780 
1781 			case THREAD_BLOCK_TYPE_RW_LOCK:
1782 				kprintf("rwlock %p\n", thread->wait.object);
1783 				break;
1784 
1785 			case THREAD_BLOCK_TYPE_OTHER:
1786 				kprintf("other (%s)\n", (char*)thread->wait.object);
1787 				break;
1788 
1789 			default:
1790 				kprintf("unknown (%p)\n", thread->wait.object);
1791 				break;
1792 		}
1793 	}
1794 
1795 	kprintf("fault_handler:      %p\n", (void *)thread->fault_handler);
1796 	kprintf("team:               %p, \"%s\"\n", thread->team,
1797 		thread->team->Name());
1798 	kprintf("  exit.sem:         %" B_PRId32 "\n", thread->exit.sem);
1799 	kprintf("  exit.status:      %#" B_PRIx32 " (%s)\n", thread->exit.status,
1800 		strerror(thread->exit.status));
1801 	kprintf("  exit.waiters:\n");
1802 	while ((death = (struct thread_death_entry*)list_get_next_item(
1803 			&thread->exit.waiters, death)) != NULL) {
1804 		kprintf("\t%p (thread %" B_PRId32 ")\n", death, death->thread);
1805 	}
1806 
1807 	kprintf("kernel_stack_area:  %" B_PRId32 "\n", thread->kernel_stack_area);
1808 	kprintf("kernel_stack_base:  %p\n", (void *)thread->kernel_stack_base);
1809 	kprintf("user_stack_area:    %" B_PRId32 "\n", thread->user_stack_area);
1810 	kprintf("user_stack_base:    %p\n", (void *)thread->user_stack_base);
1811 	kprintf("user_local_storage: %p\n", (void *)thread->user_local_storage);
1812 	kprintf("user_thread:        %p\n", (void *)thread->user_thread);
1813 	kprintf("kernel_errno:       %#x (%s)\n", thread->kernel_errno,
1814 		strerror(thread->kernel_errno));
1815 	kprintf("kernel_time:        %" B_PRId64 "\n", thread->kernel_time);
1816 	kprintf("user_time:          %" B_PRId64 "\n", thread->user_time);
1817 	kprintf("flags:              0x%" B_PRIx32 "\n", thread->flags);
1818 	kprintf("architecture dependant section:\n");
1819 	arch_thread_dump_info(&thread->arch_info);
1820 	kprintf("scheduler data:\n");
1821 	scheduler_dump_thread_data(thread);
1822 }
1823 
1824 
1825 static int
1826 dump_thread_info(int argc, char **argv)
1827 {
1828 	bool shortInfo = false;
1829 	int argi = 1;
1830 	if (argi < argc && strcmp(argv[argi], "-s") == 0) {
1831 		shortInfo = true;
1832 		print_thread_list_table_head();
1833 		argi++;
1834 	}
1835 
1836 	if (argi == argc) {
1837 		_dump_thread_info(thread_get_current_thread(), shortInfo);
1838 		return 0;
1839 	}
1840 
1841 	for (; argi < argc; argi++) {
1842 		const char *name = argv[argi];
1843 		ulong arg = strtoul(name, NULL, 0);
1844 
1845 		if (IS_KERNEL_ADDRESS(arg)) {
1846 			// semi-hack
1847 			_dump_thread_info((Thread *)arg, shortInfo);
1848 			continue;
1849 		}
1850 
1851 		// walk through the thread list, trying to match name or id
1852 		bool found = false;
1853 		for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1854 				Thread* thread = it.Next();) {
1855 			if (!strcmp(name, thread->name) || thread->id == (thread_id)arg) {
1856 				_dump_thread_info(thread, shortInfo);
1857 				found = true;
1858 				break;
1859 			}
1860 		}
1861 
1862 		if (!found)
1863 			kprintf("thread \"%s\" (%" B_PRId32 ") doesn't exist!\n", name, (thread_id)arg);
1864 	}
1865 
1866 	return 0;
1867 }
1868 
1869 
1870 static int
1871 dump_thread_list(int argc, char **argv)
1872 {
1873 	bool realTimeOnly = false;
1874 	bool calling = false;
1875 	const char *callSymbol = NULL;
1876 	addr_t callStart = 0;
1877 	addr_t callEnd = 0;
1878 	int32 requiredState = 0;
1879 	team_id team = -1;
1880 	sem_id sem = -1;
1881 
1882 	if (!strcmp(argv[0], "realtime"))
1883 		realTimeOnly = true;
1884 	else if (!strcmp(argv[0], "ready"))
1885 		requiredState = B_THREAD_READY;
1886 	else if (!strcmp(argv[0], "running"))
1887 		requiredState = B_THREAD_RUNNING;
1888 	else if (!strcmp(argv[0], "waiting")) {
1889 		requiredState = B_THREAD_WAITING;
1890 
1891 		if (argc > 1) {
1892 			sem = strtoul(argv[1], NULL, 0);
1893 			if (sem == 0)
1894 				kprintf("ignoring invalid semaphore argument.\n");
1895 		}
1896 	} else if (!strcmp(argv[0], "calling")) {
1897 		if (argc < 2) {
1898 			kprintf("Need to give a symbol name or start and end arguments.\n");
1899 			return 0;
1900 		} else if (argc == 3) {
1901 			callStart = parse_expression(argv[1]);
1902 			callEnd = parse_expression(argv[2]);
1903 		} else
1904 			callSymbol = argv[1];
1905 
1906 		calling = true;
1907 	} else if (argc > 1) {
1908 		team = strtoul(argv[1], NULL, 0);
1909 		if (team == 0)
1910 			kprintf("ignoring invalid team argument.\n");
1911 	}
1912 
1913 	print_thread_list_table_head();
1914 
1915 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1916 			Thread* thread = it.Next();) {
1917 		// filter out threads not matching the search criteria
1918 		if ((requiredState && thread->state != requiredState)
1919 			|| (calling && !arch_debug_contains_call(thread, callSymbol,
1920 					callStart, callEnd))
1921 			|| (sem > 0 && get_thread_wait_sem(thread) != sem)
1922 			|| (team > 0 && thread->team->id != team)
1923 			|| (realTimeOnly && thread->priority < B_REAL_TIME_DISPLAY_PRIORITY))
1924 			continue;
1925 
1926 		_dump_thread_info(thread, true);
1927 	}
1928 	return 0;
1929 }
1930 
1931 
1932 //	#pragma mark - private kernel API
1933 
1934 
1935 void
1936 thread_exit(void)
1937 {
1938 	cpu_status state;
1939 	Thread* thread = thread_get_current_thread();
1940 	Team* team = thread->team;
1941 	Team* kernelTeam = team_get_kernel_team();
1942 	status_t status;
1943 	struct thread_debug_info debugInfo;
1944 	team_id teamID = team->id;
1945 
1946 	TRACE(("thread %" B_PRId32 " exiting w/return code %#" B_PRIx32 "\n",
1947 		thread->id, thread->exit.status));
1948 
1949 	if (!are_interrupts_enabled())
1950 		panic("thread_exit() called with interrupts disabled!\n");
1951 
1952 	// boost our priority to get this over with
1953 	scheduler_set_thread_priority(thread, B_URGENT_DISPLAY_PRIORITY);
1954 
1955 	if (team != kernelTeam) {
1956 		// Delete all user timers associated with the thread.
1957 		ThreadLocker threadLocker(thread);
1958 		thread->DeleteUserTimers(false);
1959 
1960 		// detach the thread's user thread
1961 		user_thread* userThread = thread->user_thread;
1962 		thread->user_thread = NULL;
1963 
1964 		threadLocker.Unlock();
1965 
1966 		// Delete the thread's user thread, if it's not the main thread. If it
1967 		// is, we can save the work, since it will be deleted with the team's
1968 		// address space.
1969 		if (thread != team->main_thread)
1970 			team_free_user_thread(team, userThread);
1971 	}
1972 
1973 	// remember the user stack area -- we will delete it below
1974 	area_id userStackArea = -1;
1975 	if (team->address_space != NULL && thread->user_stack_area >= 0) {
1976 		userStackArea = thread->user_stack_area;
1977 		thread->user_stack_area = -1;
1978 	}
1979 
1980 	struct job_control_entry *death = NULL;
1981 	struct thread_death_entry* threadDeathEntry = NULL;
1982 	bool deleteTeam = false;
1983 	port_id debuggerPort = -1;
1984 
1985 	if (team != kernelTeam) {
1986 		user_debug_thread_exiting(thread);
1987 
1988 		if (team->main_thread == thread) {
1989 			// The main thread is exiting. Shut down the whole team.
1990 			deleteTeam = true;
1991 
1992 			// kill off all other threads and the user debugger facilities
1993 			debuggerPort = team_shutdown_team(team);
1994 
1995 			// acquire necessary locks, which are: process group lock, kernel
1996 			// team lock, parent team lock, and the team lock
1997 			team->LockProcessGroup();
1998 			kernelTeam->Lock();
1999 			team->LockTeamAndParent(true);
2000 		} else {
2001 			threadDeathEntry
2002 				= (thread_death_entry*)malloc(sizeof(thread_death_entry));
2003 
2004 			// acquire necessary locks, which are: kernel team lock and the team
2005 			// lock
2006 			kernelTeam->Lock();
2007 			team->Lock();
2008 		}
2009 
2010 		ThreadLocker threadLocker(thread);
2011 
2012 		state = disable_interrupts();
2013 
2014 		// swap address spaces, to make sure we're running on the kernel's pgdir
2015 		vm_swap_address_space(team->address_space, VMAddressSpace::Kernel());
2016 
2017 		WriteSpinLocker teamLocker(thread->team_lock);
2018 		SpinLocker threadCreationLocker(gThreadCreationLock);
2019 			// removing the thread and putting its death entry to the parent
2020 			// team needs to be an atomic operation
2021 
2022 		// remember how long this thread lasted
2023 		bigtime_t now = system_time();
2024 
2025 		InterruptsSpinLocker signalLocker(kernelTeam->signal_lock);
2026 		SpinLocker teamTimeLocker(kernelTeam->time_lock);
2027 		SpinLocker threadTimeLocker(thread->time_lock);
2028 
2029 		thread->kernel_time += now - thread->last_time;
2030 		thread->last_time = now;
2031 
2032 		team->dead_threads_kernel_time += thread->kernel_time;
2033 		team->dead_threads_user_time += thread->user_time;
2034 
2035 		// stop/update thread/team CPU time user timers
2036 		if (thread->HasActiveCPUTimeUserTimers()
2037 			|| team->HasActiveCPUTimeUserTimers()) {
2038 			user_timer_stop_cpu_timers(thread, NULL);
2039 		}
2040 
2041 		// deactivate CPU time user timers for the thread
2042 		if (thread->HasActiveCPUTimeUserTimers())
2043 			thread->DeactivateCPUTimeUserTimers();
2044 
2045 		threadTimeLocker.Unlock();
2046 
2047 		// put the thread into the kernel team until it dies
2048 		remove_thread_from_team(team, thread);
2049 		insert_thread_into_team(kernelTeam, thread);
2050 
2051 		teamTimeLocker.Unlock();
2052 		signalLocker.Unlock();
2053 
2054 		teamLocker.Unlock();
2055 
2056 		if (team->death_entry != NULL) {
2057 			if (--team->death_entry->remaining_threads == 0)
2058 				team->death_entry->condition.NotifyOne();
2059 		}
2060 
2061 		if (deleteTeam) {
2062 			Team* parent = team->parent;
2063 
2064 			// Set the team job control state to "dead" and detach the job
2065 			// control entry from our team struct.
2066 			team_set_job_control_state(team, JOB_CONTROL_STATE_DEAD, NULL);
2067 			death = team->job_control_entry;
2068 			team->job_control_entry = NULL;
2069 
2070 			if (death != NULL) {
2071 				death->InitDeadState();
2072 
2073 				// team_set_job_control_state() already moved our entry
2074 				// into the parent's list. We just check the soft limit of
2075 				// death entries.
2076 				if (parent->dead_children.count > MAX_DEAD_CHILDREN) {
2077 					death = parent->dead_children.entries.RemoveHead();
2078 					parent->dead_children.count--;
2079 				} else
2080 					death = NULL;
2081 			}
2082 
2083 			threadCreationLocker.Unlock();
2084 			restore_interrupts(state);
2085 
2086 			threadLocker.Unlock();
2087 
2088 			// Get a temporary reference to the team's process group
2089 			// -- team_remove_team() removes the team from the group, which
2090 			// might destroy it otherwise and we wouldn't be able to unlock it.
2091 			ProcessGroup* group = team->group;
2092 			group->AcquireReference();
2093 
2094 			pid_t foregroundGroupToSignal;
2095 			team_remove_team(team, foregroundGroupToSignal);
2096 
2097 			// unlock everything but the parent team
2098 			team->Unlock();
2099 			if (parent != kernelTeam)
2100 				kernelTeam->Unlock();
2101 			group->Unlock();
2102 			group->ReleaseReference();
2103 
2104 			// Send SIGCHLD to the parent as long as we still have its lock.
2105 			// This makes job control state change + signalling atomic.
2106 			Signal childSignal(SIGCHLD, team->exit.reason, B_OK, team->id);
2107 			if (team->exit.reason == CLD_EXITED) {
2108 				childSignal.SetStatus(team->exit.status);
2109 			} else {
2110 				childSignal.SetStatus(team->exit.signal);
2111 				childSignal.SetSendingUser(team->exit.signaling_user);
2112 			}
2113 			send_signal_to_team(parent, childSignal, B_DO_NOT_RESCHEDULE);
2114 
2115 			// also unlock the parent
2116 			parent->Unlock();
2117 
2118 			// If the team was a session leader with controlling TTY, we have
2119 			// to send SIGHUP to the foreground process group.
2120 			if (foregroundGroupToSignal >= 0) {
2121 				Signal groupSignal(SIGHUP, SI_USER, B_OK, team->id);
2122 				send_signal_to_process_group(foregroundGroupToSignal,
2123 					groupSignal, B_DO_NOT_RESCHEDULE);
2124 			}
2125 		} else {
2126 			// The thread is not the main thread. We store a thread death entry
2127 			// for it, unless someone is already waiting for it.
2128 			if (threadDeathEntry != NULL
2129 				&& list_is_empty(&thread->exit.waiters)) {
2130 				threadDeathEntry->thread = thread->id;
2131 				threadDeathEntry->status = thread->exit.status;
2132 
2133 				// add entry -- remove an old one, if we hit the limit
2134 				list_add_item(&team->dead_threads, threadDeathEntry);
2135 				team->dead_threads_count++;
2136 				threadDeathEntry = NULL;
2137 
2138 				if (team->dead_threads_count > MAX_DEAD_THREADS) {
2139 					threadDeathEntry
2140 						= (thread_death_entry*)list_remove_head_item(
2141 							&team->dead_threads);
2142 					team->dead_threads_count--;
2143 				}
2144 			}
2145 
2146 			threadCreationLocker.Unlock();
2147 			restore_interrupts(state);
2148 
2149 			threadLocker.Unlock();
2150 			team->Unlock();
2151 			kernelTeam->Unlock();
2152 		}
2153 
2154 		TRACE(("thread_exit: thread %" B_PRId32 " now a kernel thread!\n",
2155 			thread->id));
2156 	}
2157 
2158 	free(threadDeathEntry);
2159 
2160 	// delete the team if we're its main thread
2161 	if (deleteTeam) {
2162 		team_delete_team(team, debuggerPort);
2163 
2164 		// we need to delete any death entry that made it to here
2165 		delete death;
2166 	}
2167 
2168 	ThreadLocker threadLocker(thread);
2169 
2170 	state = disable_interrupts();
2171 	SpinLocker threadCreationLocker(gThreadCreationLock);
2172 
2173 	// mark invisible in global hash/list, so it's no longer accessible
2174 	WriteSpinLocker threadHashLocker(sThreadHashLock);
2175 	thread->visible = false;
2176 	sUsedThreads--;
2177 	threadHashLocker.Unlock();
2178 
2179 	// Stop debugging for this thread
2180 	SpinLocker threadDebugInfoLocker(thread->debug_info.lock);
2181 	debugInfo = thread->debug_info;
2182 	clear_thread_debug_info(&thread->debug_info, true);
2183 	threadDebugInfoLocker.Unlock();
2184 
2185 	// Remove the select infos. We notify them a little later.
2186 	select_info* selectInfos = thread->select_infos;
2187 	thread->select_infos = NULL;
2188 
2189 	threadCreationLocker.Unlock();
2190 	restore_interrupts(state);
2191 
2192 	threadLocker.Unlock();
2193 
2194 	destroy_thread_debug_info(&debugInfo);
2195 
2196 	// notify select infos
2197 	select_info* info = selectInfos;
2198 	while (info != NULL) {
2199 		select_sync* sync = info->sync;
2200 
2201 		notify_select_events(info, B_EVENT_INVALID);
2202 		info = info->next;
2203 		put_select_sync(sync);
2204 	}
2205 
2206 	// notify listeners
2207 	sNotificationService.Notify(THREAD_REMOVED, thread);
2208 
2209 	// shutdown the thread messaging
2210 
2211 	status = acquire_sem_etc(thread->msg.write_sem, 1, B_RELATIVE_TIMEOUT, 0);
2212 	if (status == B_WOULD_BLOCK) {
2213 		// there is data waiting for us, so let us eat it
2214 		thread_id sender;
2215 
2216 		delete_sem(thread->msg.write_sem);
2217 			// first, let's remove all possibly waiting writers
2218 		receive_data_etc(&sender, NULL, 0, B_RELATIVE_TIMEOUT);
2219 	} else {
2220 		// we probably own the semaphore here, and we're the last to do so
2221 		delete_sem(thread->msg.write_sem);
2222 	}
2223 	// now we can safely remove the msg.read_sem
2224 	delete_sem(thread->msg.read_sem);
2225 
2226 	// fill all death entries and delete the sem that others will use to wait
2227 	// for us
2228 	{
2229 		sem_id cachedExitSem = thread->exit.sem;
2230 
2231 		ThreadLocker threadLocker(thread);
2232 
2233 		// make sure no one will grab this semaphore again
2234 		thread->exit.sem = -1;
2235 
2236 		// fill all death entries
2237 		thread_death_entry* entry = NULL;
2238 		while ((entry = (thread_death_entry*)list_get_next_item(
2239 				&thread->exit.waiters, entry)) != NULL) {
2240 			entry->status = thread->exit.status;
2241 		}
2242 
2243 		threadLocker.Unlock();
2244 
2245 		delete_sem(cachedExitSem);
2246 	}
2247 
2248 	// delete the user stack, if this was a user thread
2249 	if (!deleteTeam && userStackArea >= 0) {
2250 		// We postponed deleting the user stack until now, since this way all
2251 		// notifications for the thread's death are out already and all other
2252 		// threads waiting for this thread's death and some object on its stack
2253 		// will wake up before we (try to) delete the stack area. Of most
2254 		// relevance is probably the case where this is the main thread and
2255 		// other threads use objects on its stack -- so we want them terminated
2256 		// first.
2257 		// When the team is deleted, all areas are deleted anyway, so we don't
2258 		// need to do that explicitly in that case.
2259 		vm_delete_area(teamID, userStackArea, true);
2260 	}
2261 
2262 	// notify the debugger
2263 	if (teamID != kernelTeam->id)
2264 		user_debug_thread_deleted(teamID, thread->id);
2265 
2266 	// enqueue in the undertaker list and reschedule for the last time
2267 	UndertakerEntry undertakerEntry(thread, teamID);
2268 
2269 	disable_interrupts();
2270 
2271 	SpinLocker schedulerLocker(thread->scheduler_lock);
2272 
2273 	SpinLocker undertakerLocker(sUndertakerLock);
2274 	sUndertakerEntries.Add(&undertakerEntry);
2275 	sUndertakerCondition.NotifyOne();
2276 	undertakerLocker.Unlock();
2277 
2278 	scheduler_reschedule(THREAD_STATE_FREE_ON_RESCHED);
2279 
2280 	panic("never can get here\n");
2281 }
2282 
2283 
2284 /*!	Called in the interrupt handler code when a thread enters
2285 	the kernel for any reason.
2286 	Only tracks time for now.
2287 	Interrupts are disabled.
2288 */
2289 void
2290 thread_at_kernel_entry(bigtime_t now)
2291 {
2292 	Thread *thread = thread_get_current_thread();
2293 
2294 	TRACE(("thread_at_kernel_entry: entry thread %" B_PRId32 "\n", thread->id));
2295 
2296 	// track user time
2297 	SpinLocker threadTimeLocker(thread->time_lock);
2298 	thread->user_time += now - thread->last_time;
2299 	thread->last_time = now;
2300 	thread->in_kernel = true;
2301 	threadTimeLocker.Unlock();
2302 }
2303 
2304 
2305 /*!	Called whenever a thread exits kernel space to user space.
2306 	Tracks time, handles signals, ...
2307 	Interrupts must be enabled. When the function returns, interrupts will be
2308 	disabled.
2309 	The function may not return. This e.g. happens when the thread has received
2310 	a deadly signal.
2311 */
2312 void
2313 thread_at_kernel_exit(void)
2314 {
2315 	Thread *thread = thread_get_current_thread();
2316 
2317 	TRACE(("thread_at_kernel_exit: exit thread %" B_PRId32 "\n", thread->id));
2318 
2319 	handle_signals(thread);
2320 
2321 	disable_interrupts();
2322 
2323 	// track kernel time
2324 	bigtime_t now = system_time();
2325 	SpinLocker threadTimeLocker(thread->time_lock);
2326 	thread->in_kernel = false;
2327 	thread->kernel_time += now - thread->last_time;
2328 	thread->last_time = now;
2329 }
2330 
2331 
2332 /*!	The quick version of thread_kernel_exit(), in case no signals are pending
2333 	and no debugging shall be done.
2334 	Interrupts must be disabled.
2335 */
2336 void
2337 thread_at_kernel_exit_no_signals(void)
2338 {
2339 	Thread *thread = thread_get_current_thread();
2340 
2341 	TRACE(("thread_at_kernel_exit_no_signals: exit thread %" B_PRId32 "\n",
2342 		thread->id));
2343 
2344 	// track kernel time
2345 	bigtime_t now = system_time();
2346 	SpinLocker threadTimeLocker(thread->time_lock);
2347 	thread->in_kernel = false;
2348 	thread->kernel_time += now - thread->last_time;
2349 	thread->last_time = now;
2350 }
2351 
2352 
2353 void
2354 thread_reset_for_exec(void)
2355 {
2356 	Thread* thread = thread_get_current_thread();
2357 
2358 	ThreadLocker threadLocker(thread);
2359 
2360 	// delete user-defined timers
2361 	thread->DeleteUserTimers(true);
2362 
2363 	// cancel pre-defined timer
2364 	if (UserTimer* timer = thread->UserTimerFor(USER_TIMER_REAL_TIME_ID))
2365 		timer->Cancel();
2366 
2367 	// reset user_thread and user stack
2368 	thread->user_thread = NULL;
2369 	thread->user_stack_area = -1;
2370 	thread->user_stack_base = 0;
2371 	thread->user_stack_size = 0;
2372 
2373 	// reset signals
2374 	thread->ResetSignalsOnExec();
2375 
2376 	// reset thread CPU time clock
2377 	InterruptsSpinLocker timeLocker(thread->time_lock);
2378 	thread->cpu_clock_offset = -thread->CPUTime(false);
2379 }
2380 
2381 
2382 thread_id
2383 allocate_thread_id()
2384 {
2385 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
2386 
2387 	// find the next unused ID
2388 	thread_id id;
2389 	do {
2390 		id = sNextThreadID++;
2391 
2392 		// deal with integer overflow
2393 		if (sNextThreadID < 0)
2394 			sNextThreadID = 2;
2395 
2396 		// check whether the ID is already in use
2397 	} while (sThreadHash.Lookup(id, false) != NULL);
2398 
2399 	return id;
2400 }
2401 
2402 
2403 thread_id
2404 peek_next_thread_id()
2405 {
2406 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
2407 	return sNextThreadID;
2408 }
2409 
2410 
2411 /*!	Yield the CPU to other threads.
2412 	Thread will continue to run, if there's no other thread in ready
2413 	state, and if it has a higher priority than the other ready threads, it
2414 	still has a good chance to continue.
2415 */
2416 void
2417 thread_yield(void)
2418 {
2419 	Thread *thread = thread_get_current_thread();
2420 	if (thread == NULL)
2421 		return;
2422 
2423 	InterruptsSpinLocker _(thread->scheduler_lock);
2424 
2425 	thread->has_yielded = true;
2426 	scheduler_reschedule(B_THREAD_READY);
2427 }
2428 
2429 
2430 void
2431 thread_map(void (*function)(Thread* thread, void* data), void* data)
2432 {
2433 	InterruptsWriteSpinLocker threadHashLocker(sThreadHashLock);
2434 
2435 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
2436 		Thread* thread = it.Next();) {
2437 		function(thread, data);
2438 	}
2439 }
2440 
2441 
2442 /*!	Kernel private thread creation function.
2443 */
2444 thread_id
2445 spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority,
2446 	void *arg, team_id team)
2447 {
2448 	return thread_create_thread(
2449 		ThreadCreationAttributes(function, name, priority, arg, team),
2450 		true);
2451 }
2452 
2453 
2454 status_t
2455 wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
2456 	status_t *_returnCode)
2457 {
2458 	if (id < 0)
2459 		return B_BAD_THREAD_ID;
2460 
2461 	// get the thread, queue our death entry, and fetch the semaphore we have to
2462 	// wait on
2463 	sem_id exitSem = B_BAD_THREAD_ID;
2464 	struct thread_death_entry death;
2465 
2466 	Thread* thread = Thread::GetAndLock(id);
2467 	if (thread != NULL) {
2468 		// remember the semaphore we have to wait on and place our death entry
2469 		exitSem = thread->exit.sem;
2470 		if (exitSem >= 0)
2471 			list_add_link_to_head(&thread->exit.waiters, &death);
2472 
2473 		thread->UnlockAndReleaseReference();
2474 
2475 		if (exitSem < 0)
2476 			return B_BAD_THREAD_ID;
2477 	} else {
2478 		// we couldn't find this thread -- maybe it's already gone, and we'll
2479 		// find its death entry in our team
2480 		Team* team = thread_get_current_thread()->team;
2481 		TeamLocker teamLocker(team);
2482 
2483 		// check the child death entries first (i.e. main threads of child
2484 		// teams)
2485 		bool deleteEntry;
2486 		job_control_entry* freeDeath
2487 			= team_get_death_entry(team, id, &deleteEntry);
2488 		if (freeDeath != NULL) {
2489 			death.status = freeDeath->status;
2490 			if (deleteEntry)
2491 				delete freeDeath;
2492 		} else {
2493 			// check the thread death entries of the team (non-main threads)
2494 			thread_death_entry* threadDeathEntry = NULL;
2495 			while ((threadDeathEntry = (thread_death_entry*)list_get_next_item(
2496 					&team->dead_threads, threadDeathEntry)) != NULL) {
2497 				if (threadDeathEntry->thread == id) {
2498 					list_remove_item(&team->dead_threads, threadDeathEntry);
2499 					team->dead_threads_count--;
2500 					death.status = threadDeathEntry->status;
2501 					free(threadDeathEntry);
2502 					break;
2503 				}
2504 			}
2505 
2506 			if (threadDeathEntry == NULL)
2507 				return B_BAD_THREAD_ID;
2508 		}
2509 
2510 		// we found the thread's death entry in our team
2511 		if (_returnCode)
2512 			*_returnCode = death.status;
2513 
2514 		return B_OK;
2515 	}
2516 
2517 	// we need to wait for the death of the thread
2518 
2519 	resume_thread(id);
2520 		// make sure we don't wait forever on a suspended thread
2521 
2522 	status_t status = acquire_sem_etc(exitSem, 1, flags, timeout);
2523 
2524 	if (status == B_OK) {
2525 		// this should never happen as the thread deletes the semaphore on exit
2526 		panic("could acquire exit_sem for thread %" B_PRId32 "\n", id);
2527 	} else if (status == B_BAD_SEM_ID) {
2528 		// this is the way the thread normally exits
2529 		status = B_OK;
2530 	} else {
2531 		// We were probably interrupted or the timeout occurred; we need to
2532 		// remove our death entry now.
2533 		thread = Thread::GetAndLock(id);
2534 		if (thread != NULL) {
2535 			list_remove_link(&death);
2536 			thread->UnlockAndReleaseReference();
2537 		} else {
2538 			// The thread is already gone, so we need to wait uninterruptibly
2539 			// for its exit semaphore to make sure our death entry stays valid.
2540 			// It won't take long, since the thread is apparently already in the
2541 			// middle of the cleanup.
2542 			acquire_sem(exitSem);
2543 			status = B_OK;
2544 		}
2545 	}
2546 
2547 	if (status == B_OK && _returnCode != NULL)
2548 		*_returnCode = death.status;
2549 
2550 	return status;
2551 }
2552 
2553 
2554 status_t
2555 select_thread(int32 id, struct select_info* info, bool kernel)
2556 {
2557 	// get and lock the thread
2558 	Thread* thread = Thread::GetAndLock(id);
2559 	if (thread == NULL)
2560 		return B_BAD_THREAD_ID;
2561 	BReference<Thread> threadReference(thread, true);
2562 	ThreadLocker threadLocker(thread, true);
2563 
2564 	// We support only B_EVENT_INVALID at the moment.
2565 	info->selected_events &= B_EVENT_INVALID;
2566 
2567 	// add info to list
2568 	if (info->selected_events != 0) {
2569 		info->next = thread->select_infos;
2570 		thread->select_infos = info;
2571 
2572 		// we need a sync reference
2573 		atomic_add(&info->sync->ref_count, 1);
2574 	}
2575 
2576 	return B_OK;
2577 }
2578 
2579 
2580 status_t
2581 deselect_thread(int32 id, struct select_info* info, bool kernel)
2582 {
2583 	// get and lock the thread
2584 	Thread* thread = Thread::GetAndLock(id);
2585 	if (thread == NULL)
2586 		return B_BAD_THREAD_ID;
2587 	BReference<Thread> threadReference(thread, true);
2588 	ThreadLocker threadLocker(thread, true);
2589 
2590 	// remove info from list
2591 	select_info** infoLocation = &thread->select_infos;
2592 	while (*infoLocation != NULL && *infoLocation != info)
2593 		infoLocation = &(*infoLocation)->next;
2594 
2595 	if (*infoLocation != info)
2596 		return B_OK;
2597 
2598 	*infoLocation = info->next;
2599 
2600 	threadLocker.Unlock();
2601 
2602 	// surrender sync reference
2603 	put_select_sync(info->sync);
2604 
2605 	return B_OK;
2606 }
2607 
2608 
2609 int32
2610 thread_max_threads(void)
2611 {
2612 	return sMaxThreads;
2613 }
2614 
2615 
2616 int32
2617 thread_used_threads(void)
2618 {
2619 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
2620 	return sUsedThreads;
2621 }
2622 
2623 
2624 /*!	Returns a user-readable string for a thread state.
2625 	Only for use in the kernel debugger.
2626 */
2627 const char*
2628 thread_state_to_text(Thread* thread, int32 state)
2629 {
2630 	return state_to_text(thread, state);
2631 }
2632 
2633 
2634 int32
2635 thread_get_io_priority(thread_id id)
2636 {
2637 	Thread* thread = Thread::GetAndLock(id);
2638 	if (thread == NULL)
2639 		return B_BAD_THREAD_ID;
2640 	BReference<Thread> threadReference(thread, true);
2641 	ThreadLocker threadLocker(thread, true);
2642 
2643 	int32 priority = thread->io_priority;
2644 	if (priority < 0) {
2645 		// negative I/O priority means using the (CPU) priority
2646 		priority = thread->priority;
2647 	}
2648 
2649 	return priority;
2650 }
2651 
2652 
2653 void
2654 thread_set_io_priority(int32 priority)
2655 {
2656 	Thread* thread = thread_get_current_thread();
2657 	ThreadLocker threadLocker(thread);
2658 
2659 	thread->io_priority = priority;
2660 }
2661 
2662 
2663 status_t
2664 thread_init(kernel_args *args)
2665 {
2666 	TRACE(("thread_init: entry\n"));
2667 
2668 	// create the thread hash table
2669 	new(&sThreadHash) ThreadHashTable();
2670 	if (sThreadHash.Init(128) != B_OK)
2671 		panic("thread_init(): failed to init thread hash table!");
2672 
2673 	// create the thread structure object cache
2674 	sThreadCache = create_object_cache("threads", sizeof(Thread), 16, NULL,
2675 		NULL, NULL);
2676 		// Note: The x86 port requires 16 byte alignment of thread structures.
2677 	if (sThreadCache == NULL)
2678 		panic("thread_init(): failed to allocate thread object cache!");
2679 
2680 	if (arch_thread_init(args) < B_OK)
2681 		panic("arch_thread_init() failed!\n");
2682 
2683 	// skip all thread IDs including B_SYSTEM_TEAM, which is reserved
2684 	sNextThreadID = B_SYSTEM_TEAM + 1;
2685 
2686 	// create an idle thread for each cpu
2687 	for (uint32 i = 0; i < args->num_cpus; i++) {
2688 		Thread *thread;
2689 		area_info info;
2690 		char name[64];
2691 
2692 		sprintf(name, "idle thread %" B_PRIu32, i + 1);
2693 		thread = new(&sIdleThreads[i]) Thread(name,
2694 			i == 0 ? team_get_kernel_team_id() : -1, &gCPU[i]);
2695 		if (thread == NULL || thread->Init(true) != B_OK) {
2696 			panic("error creating idle thread struct\n");
2697 			return B_NO_MEMORY;
2698 		}
2699 
2700 		gCPU[i].running_thread = thread;
2701 
2702 		thread->team = team_get_kernel_team();
2703 		thread->priority = B_IDLE_PRIORITY;
2704 		thread->state = B_THREAD_RUNNING;
2705 		sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1);
2706 		thread->kernel_stack_area = find_area(name);
2707 
2708 		if (get_area_info(thread->kernel_stack_area, &info) != B_OK)
2709 			panic("error finding idle kstack area\n");
2710 
2711 		thread->kernel_stack_base = (addr_t)info.address;
2712 		thread->kernel_stack_top = thread->kernel_stack_base + info.size;
2713 
2714 		thread->visible = true;
2715 		insert_thread_into_team(thread->team, thread);
2716 
2717 		scheduler_on_thread_init(thread);
2718 	}
2719 	sUsedThreads = args->num_cpus;
2720 
2721 	// init the notification service
2722 	new(&sNotificationService) ThreadNotificationService();
2723 
2724 	sNotificationService.Register();
2725 
2726 	// start the undertaker thread
2727 	new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>();
2728 	sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries");
2729 
2730 	thread_id undertakerThread = spawn_kernel_thread(&undertaker, "undertaker",
2731 		B_DISPLAY_PRIORITY, NULL);
2732 	if (undertakerThread < 0)
2733 		panic("Failed to create undertaker thread!");
2734 	resume_thread(undertakerThread);
2735 
2736 	// set up some debugger commands
2737 	add_debugger_command_etc("threads", &dump_thread_list, "List all threads",
2738 		"[ <team> ]\n"
2739 		"Prints a list of all existing threads, or, if a team ID is given,\n"
2740 		"all threads of the specified team.\n"
2741 		"  <team>  - The ID of the team whose threads shall be listed.\n", 0);
2742 	add_debugger_command_etc("ready", &dump_thread_list,
2743 		"List all ready threads",
2744 		"\n"
2745 		"Prints a list of all threads in ready state.\n", 0);
2746 	add_debugger_command_etc("running", &dump_thread_list,
2747 		"List all running threads",
2748 		"\n"
2749 		"Prints a list of all threads in running state.\n", 0);
2750 	add_debugger_command_etc("waiting", &dump_thread_list,
2751 		"List all waiting threads (optionally for a specific semaphore)",
2752 		"[ <sem> ]\n"
2753 		"Prints a list of all threads in waiting state. If a semaphore is\n"
2754 		"specified, only the threads waiting on that semaphore are listed.\n"
2755 		"  <sem>  - ID of the semaphore.\n", 0);
2756 	add_debugger_command_etc("realtime", &dump_thread_list,
2757 		"List all realtime threads",
2758 		"\n"
2759 		"Prints a list of all threads with realtime priority.\n", 0);
2760 	add_debugger_command_etc("thread", &dump_thread_info,
2761 		"Dump info about a particular thread",
2762 		"[ -s ] ( <id> | <address> | <name> )*\n"
2763 		"Prints information about the specified thread. If no argument is\n"
2764 		"given the current thread is selected.\n"
2765 		"  -s         - Print info in compact table form (like \"threads\").\n"
2766 		"  <id>       - The ID of the thread.\n"
2767 		"  <address>  - The address of the thread structure.\n"
2768 		"  <name>     - The thread's name.\n", 0);
2769 	add_debugger_command_etc("calling", &dump_thread_list,
2770 		"Show all threads that have a specific address in their call chain",
2771 		"{ <symbol-pattern> | <start> <end> }\n", 0);
2772 	add_debugger_command_etc("unreal", &make_thread_unreal,
2773 		"Set realtime priority threads to normal priority",
2774 		"[ <id> ]\n"
2775 		"Sets the priority of all realtime threads or, if given, the one\n"
2776 		"with the specified ID to \"normal\" priority.\n"
2777 		"  <id>  - The ID of the thread.\n", 0);
2778 	add_debugger_command_etc("suspend", &make_thread_suspended,
2779 		"Suspend a thread",
2780 		"[ <id> ]\n"
2781 		"Suspends the thread with the given ID. If no ID argument is given\n"
2782 		"the current thread is selected.\n"
2783 		"  <id>  - The ID of the thread.\n", 0);
2784 	add_debugger_command_etc("resume", &make_thread_resumed, "Resume a thread",
2785 		"<id>\n"
2786 		"Resumes the specified thread, if it is currently suspended.\n"
2787 		"  <id>  - The ID of the thread.\n", 0);
2788 	add_debugger_command_etc("drop", &drop_into_debugger,
2789 		"Drop a thread into the userland debugger",
2790 		"<id>\n"
2791 		"Drops the specified (userland) thread into the userland debugger\n"
2792 		"after leaving the kernel debugger.\n"
2793 		"  <id>  - The ID of the thread.\n", 0);
2794 	add_debugger_command_etc("priority", &set_thread_prio,
2795 		"Set a thread's priority",
2796 		"<priority> [ <id> ]\n"
2797 		"Sets the priority of the thread with the specified ID to the given\n"
2798 		"priority. If no thread ID is given, the current thread is selected.\n"
2799 		"  <priority>  - The thread's new priority (0 - 120)\n"
2800 		"  <id>        - The ID of the thread.\n", 0);
2801 
2802 	return B_OK;
2803 }
2804 
2805 
2806 status_t
2807 thread_preboot_init_percpu(struct kernel_args *args, int32 cpuNum)
2808 {
2809 	// set up the cpu pointer in the not yet initialized per-cpu idle thread
2810 	// so that get_current_cpu and friends will work, which is crucial for
2811 	// a lot of low level routines
2812 	sIdleThreads[cpuNum].cpu = &gCPU[cpuNum];
2813 	arch_thread_set_current_thread(&sIdleThreads[cpuNum]);
2814 	return B_OK;
2815 }
2816 
2817 
2818 //	#pragma mark - thread blocking API
2819 
2820 
2821 static status_t
2822 thread_block_timeout(timer* timer)
2823 {
2824 	Thread* thread = (Thread*)timer->user_data;
2825 	thread_unblock(thread, B_TIMED_OUT);
2826 
2827 	return B_HANDLED_INTERRUPT;
2828 }
2829 
2830 
2831 /*!	Blocks the current thread.
2832 
2833 	The thread is blocked until someone else unblock it. Must be called after a
2834 	call to thread_prepare_to_block(). If the thread has already been unblocked
2835 	after the previous call to thread_prepare_to_block(), this function will
2836 	return immediately. Cf. the documentation of thread_prepare_to_block() for
2837 	more details.
2838 
2839 	The caller must hold the scheduler lock.
2840 
2841 	\param thread The current thread.
2842 	\return The error code passed to the unblocking function. thread_interrupt()
2843 		uses \c B_INTERRUPTED. By convention \c B_OK means that the wait was
2844 		successful while another error code indicates a failure (what that means
2845 		depends on the client code).
2846 */
2847 static inline status_t
2848 thread_block_locked(Thread* thread)
2849 {
2850 	if (thread->wait.status == 1) {
2851 		// check for signals, if interruptible
2852 		if (thread_is_interrupted(thread, thread->wait.flags)) {
2853 			thread->wait.status = B_INTERRUPTED;
2854 		} else
2855 			scheduler_reschedule(B_THREAD_WAITING);
2856 	}
2857 
2858 	return thread->wait.status;
2859 }
2860 
2861 
2862 /*!	Blocks the current thread.
2863 
2864 	The function acquires the scheduler lock and calls thread_block_locked().
2865 	See there for more information.
2866 */
2867 status_t
2868 thread_block()
2869 {
2870 	InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock);
2871 	return thread_block_locked(thread_get_current_thread());
2872 }
2873 
2874 
2875 /*!	Blocks the current thread with a timeout.
2876 
2877 	The current thread is blocked until someone else unblock it or the specified
2878 	timeout occurs. Must be called after a call to thread_prepare_to_block(). If
2879 	the thread has already been unblocked after the previous call to
2880 	thread_prepare_to_block(), this function will return immediately. See
2881 	thread_prepare_to_block() for more details.
2882 
2883 	The caller must not hold the scheduler lock.
2884 
2885 	\param timeoutFlags The standard timeout flags:
2886 		- \c B_RELATIVE_TIMEOUT: \a timeout specifies the time to wait.
2887 		- \c B_ABSOLUTE_TIMEOUT: \a timeout specifies the absolute end time when
2888 			the timeout shall occur.
2889 		- \c B_TIMEOUT_REAL_TIME_BASE: Only relevant when \c B_ABSOLUTE_TIMEOUT
2890 			is specified, too. Specifies that \a timeout is a real time, not a
2891 			system time.
2892 		If neither \c B_RELATIVE_TIMEOUT nor \c B_ABSOLUTE_TIMEOUT are
2893 		specified, an infinite timeout is implied and the function behaves like
2894 		thread_block_locked().
2895 	\return The error code passed to the unblocking function. thread_interrupt()
2896 		uses \c B_INTERRUPTED. When the timeout occurred, \c B_TIMED_OUT is
2897 		returned. By convention \c B_OK means that the wait was successful while
2898 		another error code indicates a failure (what that means depends on the
2899 		client code).
2900 */
2901 status_t
2902 thread_block_with_timeout(uint32 timeoutFlags, bigtime_t timeout)
2903 {
2904 	Thread* thread = thread_get_current_thread();
2905 
2906 	InterruptsSpinLocker locker(thread->scheduler_lock);
2907 
2908 	if (thread->wait.status != 1)
2909 		return thread->wait.status;
2910 
2911 	bool useTimer = (timeoutFlags & (B_RELATIVE_TIMEOUT | B_ABSOLUTE_TIMEOUT))
2912 		&& timeout != B_INFINITE_TIMEOUT;
2913 
2914 	if (useTimer) {
2915 		// Timer flags: absolute/relative.
2916 		uint32 timerFlags;
2917 		if ((timeoutFlags & B_RELATIVE_TIMEOUT) != 0) {
2918 			timerFlags = B_ONE_SHOT_RELATIVE_TIMER;
2919 		} else {
2920 			timerFlags = B_ONE_SHOT_ABSOLUTE_TIMER;
2921 			if ((timeoutFlags & B_TIMEOUT_REAL_TIME_BASE) != 0)
2922 				timerFlags |= B_TIMER_REAL_TIME_BASE;
2923 		}
2924 
2925 		// install the timer
2926 		thread->wait.unblock_timer.user_data = thread;
2927 		add_timer(&thread->wait.unblock_timer, &thread_block_timeout, timeout,
2928 			timerFlags);
2929 	}
2930 
2931 	// block
2932 	status_t error = thread_block_locked(thread);
2933 
2934 	locker.Unlock();
2935 
2936 	// cancel timer, if it didn't fire
2937 	if (error != B_TIMED_OUT && useTimer)
2938 		cancel_timer(&thread->wait.unblock_timer);
2939 
2940 	return error;
2941 }
2942 
2943 
2944 /*!	Unblocks a thread.
2945 
2946 	Acquires the scheduler lock and calls thread_unblock_locked().
2947 	See there for more information.
2948 */
2949 void
2950 thread_unblock(Thread* thread, status_t status)
2951 {
2952 	InterruptsSpinLocker locker(thread->scheduler_lock);
2953 	thread_unblock_locked(thread, status);
2954 }
2955 
2956 
2957 /*!	Unblocks a userland-blocked thread.
2958 	The caller must not hold any locks.
2959 */
2960 static status_t
2961 user_unblock_thread(thread_id threadID, status_t status)
2962 {
2963 	// get the thread
2964 	Thread* thread = Thread::GetAndLock(threadID);
2965 	if (thread == NULL)
2966 		return B_BAD_THREAD_ID;
2967 	BReference<Thread> threadReference(thread, true);
2968 	ThreadLocker threadLocker(thread, true);
2969 
2970 	if (thread->user_thread == NULL)
2971 		return B_NOT_ALLOWED;
2972 
2973 	InterruptsSpinLocker locker(thread->scheduler_lock);
2974 
2975 	set_ac();
2976 	if (thread->user_thread->wait_status > 0) {
2977 		thread->user_thread->wait_status = status;
2978 		clear_ac();
2979 		thread_unblock_locked(thread, status);
2980 	} else
2981 		clear_ac();
2982 
2983 	return B_OK;
2984 }
2985 
2986 
2987 static bool
2988 thread_check_permissions(const Thread* currentThread, const Thread* thread,
2989 	bool kernel)
2990 {
2991 	if (kernel)
2992 		return true;
2993 
2994 	if (thread->team->id == team_get_kernel_team_id())
2995 		return false;
2996 
2997 	if (thread->team != currentThread->team
2998 			&& currentThread->team->effective_uid != 0
2999 			&& thread->team->real_uid != currentThread->team->real_uid)
3000 		return false;
3001 
3002 	return true;
3003 }
3004 
3005 
3006 static status_t
3007 thread_send_signal(thread_id id, uint32 number, int32 signalCode,
3008 	int32 errorCode, bool kernel)
3009 {
3010 	if (id <= 0)
3011 		return B_BAD_VALUE;
3012 
3013 	Thread* currentThread = thread_get_current_thread();
3014 	Thread* thread = Thread::Get(id);
3015 	if (thread == NULL)
3016 		return B_BAD_THREAD_ID;
3017 	BReference<Thread> threadReference(thread, true);
3018 
3019 	// check whether sending the signal is allowed
3020 	if (!thread_check_permissions(currentThread, thread, kernel))
3021 		return B_NOT_ALLOWED;
3022 
3023 	Signal signal(number, signalCode, errorCode, currentThread->team->id);
3024 	return send_signal_to_thread(thread, signal, 0);
3025 }
3026 
3027 
3028 //	#pragma mark - public kernel API
3029 
3030 
3031 void
3032 exit_thread(status_t returnValue)
3033 {
3034 	Thread *thread = thread_get_current_thread();
3035 	Team* team = thread->team;
3036 
3037 	thread->exit.status = returnValue;
3038 
3039 	// if called from a kernel thread, we don't deliver the signal,
3040 	// we just exit directly to keep the user space behaviour of
3041 	// this function
3042 	if (team != team_get_kernel_team()) {
3043 		// If this is its main thread, set the team's exit status.
3044 		if (thread == team->main_thread) {
3045 			TeamLocker teamLocker(team);
3046 
3047 			if (!team->exit.initialized) {
3048 				team->exit.reason = CLD_EXITED;
3049 				team->exit.signal = 0;
3050 				team->exit.signaling_user = 0;
3051 				team->exit.status = returnValue;
3052 				team->exit.initialized = true;
3053 			}
3054 
3055 			teamLocker.Unlock();
3056 		}
3057 
3058 		Signal signal(SIGKILLTHR, SI_USER, B_OK, team->id);
3059 		send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE);
3060 	} else
3061 		thread_exit();
3062 }
3063 
3064 
3065 static status_t
3066 thread_kill_thread(thread_id id, bool kernel)
3067 {
3068 	return thread_send_signal(id, SIGKILLTHR, SI_USER, B_OK, kernel);
3069 }
3070 
3071 
3072 status_t
3073 kill_thread(thread_id id)
3074 {
3075 	return thread_kill_thread(id, true);
3076 }
3077 
3078 
3079 status_t
3080 send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize)
3081 {
3082 	return send_data_etc(thread, code, buffer, bufferSize, 0);
3083 }
3084 
3085 
3086 int32
3087 receive_data(thread_id *sender, void *buffer, size_t bufferSize)
3088 {
3089 	return receive_data_etc(sender, buffer, bufferSize, 0);
3090 }
3091 
3092 
3093 static bool
3094 thread_has_data(thread_id id, bool kernel)
3095 {
3096 	Thread* currentThread = thread_get_current_thread();
3097 	Thread* thread;
3098 	BReference<Thread> threadReference;
3099 	if (id == currentThread->id) {
3100 		thread = currentThread;
3101 	} else {
3102 		thread = Thread::Get(id);
3103 		if (thread == NULL)
3104 			return false;
3105 
3106 		threadReference.SetTo(thread, true);
3107 	}
3108 
3109 	if (!kernel && thread->team != currentThread->team)
3110 		return false;
3111 
3112 	int32 count;
3113 	if (get_sem_count(thread->msg.read_sem, &count) != B_OK)
3114 		return false;
3115 
3116 	return count == 0 ? false : true;
3117 }
3118 
3119 
3120 bool
3121 has_data(thread_id thread)
3122 {
3123 	return thread_has_data(thread, true);
3124 }
3125 
3126 
3127 status_t
3128 _get_thread_info(thread_id id, thread_info *info, size_t size)
3129 {
3130 	if (info == NULL || size != sizeof(thread_info) || id < B_OK)
3131 		return B_BAD_VALUE;
3132 
3133 	// get the thread
3134 	Thread* thread = Thread::GetAndLock(id);
3135 	if (thread == NULL)
3136 		return B_BAD_THREAD_ID;
3137 	BReference<Thread> threadReference(thread, true);
3138 	ThreadLocker threadLocker(thread, true);
3139 
3140 	// fill the info -- also requires the scheduler lock to be held
3141 	InterruptsSpinLocker locker(thread->scheduler_lock);
3142 
3143 	fill_thread_info(thread, info, size);
3144 
3145 	return B_OK;
3146 }
3147 
3148 
3149 status_t
3150 _get_next_thread_info(team_id teamID, int32 *_cookie, thread_info *info,
3151 	size_t size)
3152 {
3153 	if (info == NULL || size != sizeof(thread_info) || teamID < 0)
3154 		return B_BAD_VALUE;
3155 
3156 	int32 lastID = *_cookie;
3157 
3158 	// get the team
3159 	Team* team = Team::GetAndLock(teamID);
3160 	if (team == NULL)
3161 		return B_BAD_VALUE;
3162 	BReference<Team> teamReference(team, true);
3163 	TeamLocker teamLocker(team, true);
3164 
3165 	Thread* thread = NULL;
3166 
3167 	if (lastID == 0) {
3168 		// We start with the main thread
3169 		thread = team->main_thread;
3170 	} else {
3171 		// Find the one thread with an ID greater than ours (as long as the IDs
3172 		// don't wrap they are always sorted from highest to lowest).
3173 		// TODO: That is broken not only when the IDs wrap, but also for the
3174 		// kernel team, to which threads are added when they are dying.
3175 		for (Thread* next = team->thread_list; next != NULL;
3176 				next = next->team_next) {
3177 			if (next->id <= lastID)
3178 				break;
3179 
3180 			thread = next;
3181 		}
3182 	}
3183 
3184 	if (thread == NULL)
3185 		return B_BAD_VALUE;
3186 
3187 	lastID = thread->id;
3188 	*_cookie = lastID;
3189 
3190 	ThreadLocker threadLocker(thread);
3191 	InterruptsSpinLocker locker(thread->scheduler_lock);
3192 
3193 	fill_thread_info(thread, info, size);
3194 
3195 	return B_OK;
3196 }
3197 
3198 
3199 thread_id
3200 find_thread(const char* name)
3201 {
3202 	if (name == NULL)
3203 		return thread_get_current_thread_id();
3204 
3205 	InterruptsReadSpinLocker threadHashLocker(sThreadHashLock);
3206 
3207 	// Scanning the whole hash with the thread hash lock held isn't exactly
3208 	// cheap, but since this function is probably used very rarely, and we
3209 	// only need a read lock, it's probably acceptable.
3210 
3211 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
3212 			Thread* thread = it.Next();) {
3213 		if (!thread->visible)
3214 			continue;
3215 
3216 		if (strcmp(thread->name, name) == 0)
3217 			return thread->id;
3218 	}
3219 
3220 	return B_NAME_NOT_FOUND;
3221 }
3222 
3223 
3224 status_t
3225 rename_thread(thread_id id, const char* name)
3226 {
3227 	if (name == NULL)
3228 		return B_BAD_VALUE;
3229 
3230 	// get the thread
3231 	Thread* thread = Thread::GetAndLock(id);
3232 	if (thread == NULL)
3233 		return B_BAD_THREAD_ID;
3234 	BReference<Thread> threadReference(thread, true);
3235 	ThreadLocker threadLocker(thread, true);
3236 
3237 	// check whether the operation is allowed
3238 	if (thread->team != thread_get_current_thread()->team)
3239 		return B_NOT_ALLOWED;
3240 
3241 	strlcpy(thread->name, name, B_OS_NAME_LENGTH);
3242 
3243 	team_id teamID = thread->team->id;
3244 
3245 	threadLocker.Unlock();
3246 
3247 	// notify listeners
3248 	sNotificationService.Notify(THREAD_NAME_CHANGED, teamID, id);
3249 		// don't pass the thread structure, as it's unsafe, if it isn't ours
3250 
3251 	return B_OK;
3252 }
3253 
3254 
3255 static status_t
3256 thread_set_thread_priority(thread_id id, int32 priority, bool kernel)
3257 {
3258 	// make sure the passed in priority is within bounds
3259 	if (priority > THREAD_MAX_SET_PRIORITY)
3260 		priority = THREAD_MAX_SET_PRIORITY;
3261 	if (priority < THREAD_MIN_SET_PRIORITY)
3262 		priority = THREAD_MIN_SET_PRIORITY;
3263 
3264 	// get the thread
3265 	Thread* thread = Thread::GetAndLock(id);
3266 	if (thread == NULL)
3267 		return B_BAD_THREAD_ID;
3268 	BReference<Thread> threadReference(thread, true);
3269 	ThreadLocker threadLocker(thread, true);
3270 
3271 	// check whether the change is allowed
3272 	if (thread_is_idle_thread(thread) || !thread_check_permissions(
3273 			thread_get_current_thread(), thread, kernel))
3274 		return B_NOT_ALLOWED;
3275 
3276 	return scheduler_set_thread_priority(thread, priority);
3277 }
3278 
3279 
3280 status_t
3281 set_thread_priority(thread_id id, int32 priority)
3282 {
3283 	return thread_set_thread_priority(id, priority, true);
3284 }
3285 
3286 
3287 status_t
3288 snooze_etc(bigtime_t timeout, int timebase, uint32 flags)
3289 {
3290 	return common_snooze_etc(timeout, timebase, flags, NULL);
3291 }
3292 
3293 
3294 /*!	snooze() for internal kernel use only; doesn't interrupt on signals. */
3295 status_t
3296 snooze(bigtime_t timeout)
3297 {
3298 	return snooze_etc(timeout, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT);
3299 }
3300 
3301 
3302 /*!	snooze_until() for internal kernel use only; doesn't interrupt on
3303 	signals.
3304 */
3305 status_t
3306 snooze_until(bigtime_t timeout, int timebase)
3307 {
3308 	return snooze_etc(timeout, timebase, B_ABSOLUTE_TIMEOUT);
3309 }
3310 
3311 
3312 status_t
3313 wait_for_thread(thread_id thread, status_t *_returnCode)
3314 {
3315 	return wait_for_thread_etc(thread, 0, 0, _returnCode);
3316 }
3317 
3318 
3319 static status_t
3320 thread_suspend_thread(thread_id id, bool kernel)
3321 {
3322 	return thread_send_signal(id, SIGSTOP, SI_USER, B_OK, kernel);
3323 }
3324 
3325 
3326 status_t
3327 suspend_thread(thread_id id)
3328 {
3329 	return thread_suspend_thread(id, true);
3330 }
3331 
3332 
3333 static status_t
3334 thread_resume_thread(thread_id id, bool kernel)
3335 {
3336 	// Using the kernel internal SIGNAL_CONTINUE_THREAD signal retains
3337 	// compatibility to BeOS which documents the combination of suspend_thread()
3338 	// and resume_thread() to interrupt threads waiting on semaphores.
3339 	return thread_send_signal(id, SIGNAL_CONTINUE_THREAD, SI_USER, B_OK, kernel);
3340 }
3341 
3342 
3343 status_t
3344 resume_thread(thread_id id)
3345 {
3346 	return thread_resume_thread(id, true);
3347 }
3348 
3349 
3350 thread_id
3351 spawn_kernel_thread(thread_func function, const char *name, int32 priority,
3352 	void *arg)
3353 {
3354 	return thread_create_thread(
3355 		ThreadCreationAttributes(function, name, priority, arg),
3356 		true);
3357 }
3358 
3359 
3360 int
3361 getrlimit(int resource, struct rlimit * rlp)
3362 {
3363 	status_t error = common_getrlimit(resource, rlp);
3364 	if (error != B_OK) {
3365 		errno = error;
3366 		return -1;
3367 	}
3368 
3369 	return 0;
3370 }
3371 
3372 
3373 int
3374 setrlimit(int resource, const struct rlimit * rlp)
3375 {
3376 	status_t error = common_setrlimit(resource, rlp);
3377 	if (error != B_OK) {
3378 		errno = error;
3379 		return -1;
3380 	}
3381 
3382 	return 0;
3383 }
3384 
3385 
3386 //	#pragma mark - syscalls
3387 
3388 
3389 void
3390 _user_exit_thread(status_t returnValue)
3391 {
3392 	exit_thread(returnValue);
3393 }
3394 
3395 
3396 status_t
3397 _user_kill_thread(thread_id thread)
3398 {
3399 	return thread_kill_thread(thread, false);
3400 }
3401 
3402 
3403 status_t
3404 _user_cancel_thread(thread_id threadID, void (*cancelFunction)(int))
3405 {
3406 	// check the cancel function
3407 	if (cancelFunction == NULL || !IS_USER_ADDRESS(cancelFunction))
3408 		return B_BAD_VALUE;
3409 
3410 	// get and lock the thread
3411 	Thread* thread = Thread::GetAndLock(threadID);
3412 	if (thread == NULL)
3413 		return B_BAD_THREAD_ID;
3414 	BReference<Thread> threadReference(thread, true);
3415 	ThreadLocker threadLocker(thread, true);
3416 
3417 	// only threads of the same team can be canceled
3418 	if (thread->team != thread_get_current_thread()->team)
3419 		return B_NOT_ALLOWED;
3420 
3421 	// set the cancel function
3422 	thread->cancel_function = cancelFunction;
3423 
3424 	// send the cancellation signal to the thread
3425 	InterruptsReadSpinLocker teamLocker(thread->team_lock);
3426 	SpinLocker locker(thread->team->signal_lock);
3427 	return send_signal_to_thread_locked(thread, SIGNAL_CANCEL_THREAD, NULL, 0);
3428 }
3429 
3430 
3431 status_t
3432 _user_resume_thread(thread_id thread)
3433 {
3434 	return thread_resume_thread(thread, false);
3435 }
3436 
3437 
3438 status_t
3439 _user_suspend_thread(thread_id thread)
3440 {
3441 	return thread_suspend_thread(thread, false);
3442 }
3443 
3444 
3445 status_t
3446 _user_rename_thread(thread_id thread, const char *userName)
3447 {
3448 	char name[B_OS_NAME_LENGTH];
3449 
3450 	if (!IS_USER_ADDRESS(userName)
3451 		|| userName == NULL
3452 		|| user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK)
3453 		return B_BAD_ADDRESS;
3454 
3455 	// rename_thread() forbids thread renames across teams, so we don't
3456 	// need a "kernel" flag here.
3457 	return rename_thread(thread, name);
3458 }
3459 
3460 
3461 int32
3462 _user_set_thread_priority(thread_id thread, int32 newPriority)
3463 {
3464 	return thread_set_thread_priority(thread, newPriority, false);
3465 }
3466 
3467 
3468 thread_id
3469 _user_spawn_thread(thread_creation_attributes* userAttributes)
3470 {
3471 	// copy the userland structure to the kernel
3472 	char nameBuffer[B_OS_NAME_LENGTH];
3473 	ThreadCreationAttributes attributes;
3474 	status_t error = attributes.InitFromUserAttributes(userAttributes,
3475 		nameBuffer);
3476 	if (error != B_OK)
3477 		return error;
3478 
3479 	// create the thread
3480 	thread_id threadID = thread_create_thread(attributes, false);
3481 
3482 	if (threadID >= 0)
3483 		user_debug_thread_created(threadID);
3484 
3485 	return threadID;
3486 }
3487 
3488 
3489 status_t
3490 _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags,
3491 	bigtime_t* userRemainingTime)
3492 {
3493 	// We need to store more syscall restart parameters than usual and need a
3494 	// somewhat different handling. Hence we can't use
3495 	// syscall_restart_handle_timeout_pre() but do the job ourselves.
3496 	struct restart_parameters {
3497 		bigtime_t	timeout;
3498 		clockid_t	timebase;
3499 		uint32		flags;
3500 	};
3501 
3502 	Thread* thread = thread_get_current_thread();
3503 
3504 	if ((thread->flags & THREAD_FLAGS_SYSCALL_RESTARTED) != 0) {
3505 		// The syscall was restarted. Fetch the parameters from the stored
3506 		// restart parameters.
3507 		restart_parameters* restartParameters
3508 			= (restart_parameters*)thread->syscall_restart.parameters;
3509 		timeout = restartParameters->timeout;
3510 		timebase = restartParameters->timebase;
3511 		flags = restartParameters->flags;
3512 	} else {
3513 		// convert relative timeouts to absolute ones
3514 		if ((flags & B_RELATIVE_TIMEOUT) != 0) {
3515 			// not restarted yet and the flags indicate a relative timeout
3516 
3517 			// Make sure we use the system time base, so real-time clock changes
3518 			// won't affect our wait.
3519 			flags &= ~(uint32)B_TIMEOUT_REAL_TIME_BASE;
3520 			if (timebase == CLOCK_REALTIME)
3521 				timebase = CLOCK_MONOTONIC;
3522 
3523 			// get the current time and make the timeout absolute
3524 			bigtime_t now;
3525 			status_t error = user_timer_get_clock(timebase, now);
3526 			if (error != B_OK)
3527 				return error;
3528 
3529 			timeout += now;
3530 
3531 			// deal with overflow
3532 			if (timeout < 0)
3533 				timeout = B_INFINITE_TIMEOUT;
3534 
3535 			flags = (flags & ~B_RELATIVE_TIMEOUT) | B_ABSOLUTE_TIMEOUT;
3536 		} else
3537 			flags |= B_ABSOLUTE_TIMEOUT;
3538 	}
3539 
3540 	// snooze
3541 	bigtime_t remainingTime;
3542 	status_t error = common_snooze_etc(timeout, timebase,
3543 		flags | B_CAN_INTERRUPT | B_CHECK_PERMISSION,
3544 		userRemainingTime != NULL ? &remainingTime : NULL);
3545 
3546 	// If interrupted, copy the remaining time back to userland and prepare the
3547 	// syscall restart.
3548 	if (error == B_INTERRUPTED) {
3549 		if (userRemainingTime != NULL
3550 			&& (!IS_USER_ADDRESS(userRemainingTime)
3551 				|| user_memcpy(userRemainingTime, &remainingTime,
3552 					sizeof(remainingTime)) != B_OK)) {
3553 			return B_BAD_ADDRESS;
3554 		}
3555 
3556 		// store the normalized values in the restart parameters
3557 		restart_parameters* restartParameters
3558 			= (restart_parameters*)thread->syscall_restart.parameters;
3559 		restartParameters->timeout = timeout;
3560 		restartParameters->timebase = timebase;
3561 		restartParameters->flags = flags;
3562 
3563 		// restart the syscall, if possible
3564 		atomic_or(&thread->flags, THREAD_FLAGS_RESTART_SYSCALL);
3565 	}
3566 
3567 	return error;
3568 }
3569 
3570 
3571 void
3572 _user_thread_yield(void)
3573 {
3574 	thread_yield();
3575 }
3576 
3577 
3578 status_t
3579 _user_get_thread_info(thread_id id, thread_info *userInfo)
3580 {
3581 	thread_info info;
3582 	status_t status;
3583 
3584 	if (!IS_USER_ADDRESS(userInfo))
3585 		return B_BAD_ADDRESS;
3586 
3587 	status = _get_thread_info(id, &info, sizeof(thread_info));
3588 
3589 	if (status >= B_OK
3590 		&& user_memcpy(userInfo, &info, sizeof(thread_info)) < B_OK)
3591 		return B_BAD_ADDRESS;
3592 
3593 	return status;
3594 }
3595 
3596 
3597 status_t
3598 _user_get_next_thread_info(team_id team, int32 *userCookie,
3599 	thread_info *userInfo)
3600 {
3601 	status_t status;
3602 	thread_info info;
3603 	int32 cookie;
3604 
3605 	if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo)
3606 		|| user_memcpy(&cookie, userCookie, sizeof(int32)) < B_OK)
3607 		return B_BAD_ADDRESS;
3608 
3609 	status = _get_next_thread_info(team, &cookie, &info, sizeof(thread_info));
3610 	if (status < B_OK)
3611 		return status;
3612 
3613 	if (user_memcpy(userCookie, &cookie, sizeof(int32)) < B_OK
3614 		|| user_memcpy(userInfo, &info, sizeof(thread_info)) < B_OK)
3615 		return B_BAD_ADDRESS;
3616 
3617 	return status;
3618 }
3619 
3620 
3621 thread_id
3622 _user_find_thread(const char *userName)
3623 {
3624 	char name[B_OS_NAME_LENGTH];
3625 
3626 	if (userName == NULL)
3627 		return find_thread(NULL);
3628 
3629 	if (!IS_USER_ADDRESS(userName)
3630 		|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
3631 		return B_BAD_ADDRESS;
3632 
3633 	return find_thread(name);
3634 }
3635 
3636 
3637 status_t
3638 _user_wait_for_thread(thread_id id, status_t *userReturnCode)
3639 {
3640 	status_t returnCode;
3641 	status_t status;
3642 
3643 	if (userReturnCode != NULL && !IS_USER_ADDRESS(userReturnCode))
3644 		return B_BAD_ADDRESS;
3645 
3646 	status = wait_for_thread_etc(id, B_CAN_INTERRUPT, 0, &returnCode);
3647 
3648 	if (status == B_OK && userReturnCode != NULL
3649 		&& user_memcpy(userReturnCode, &returnCode, sizeof(status_t)) < B_OK) {
3650 		return B_BAD_ADDRESS;
3651 	}
3652 
3653 	return syscall_restart_handle_post(status);
3654 }
3655 
3656 
3657 bool
3658 _user_has_data(thread_id thread)
3659 {
3660 	return thread_has_data(thread, false);
3661 }
3662 
3663 
3664 status_t
3665 _user_send_data(thread_id thread, int32 code, const void *buffer,
3666 	size_t bufferSize)
3667 {
3668 	if (buffer != NULL && !IS_USER_ADDRESS(buffer))
3669 		return B_BAD_ADDRESS;
3670 
3671 	return send_data_etc(thread, code, buffer, bufferSize,
3672 		B_KILL_CAN_INTERRUPT);
3673 		// supports userland buffers
3674 }
3675 
3676 
3677 status_t
3678 _user_receive_data(thread_id *_userSender, void *buffer, size_t bufferSize)
3679 {
3680 	thread_id sender;
3681 	status_t code;
3682 
3683 	if ((!IS_USER_ADDRESS(_userSender) && _userSender != NULL)
3684 		|| (!IS_USER_ADDRESS(buffer) && buffer != NULL)) {
3685 		return B_BAD_ADDRESS;
3686 	}
3687 
3688 	code = receive_data_etc(&sender, buffer, bufferSize, B_KILL_CAN_INTERRUPT);
3689 		// supports userland buffers
3690 
3691 	if (_userSender != NULL)
3692 		if (user_memcpy(_userSender, &sender, sizeof(thread_id)) < B_OK)
3693 			return B_BAD_ADDRESS;
3694 
3695 	return code;
3696 }
3697 
3698 
3699 status_t
3700 _user_block_thread(uint32 flags, bigtime_t timeout)
3701 {
3702 	syscall_restart_handle_timeout_pre(flags, timeout);
3703 	flags |= B_CAN_INTERRUPT;
3704 
3705 	Thread* thread = thread_get_current_thread();
3706 	ThreadLocker threadLocker(thread);
3707 
3708 	// check, if already done
3709 	set_ac();
3710 	if (thread->user_thread->wait_status <= 0) {
3711 		status_t status = thread->user_thread->wait_status;
3712 		clear_ac();
3713 		return status;
3714 	}
3715 	clear_ac();
3716 
3717 	// nope, so wait
3718 	thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_OTHER, "user");
3719 
3720 	threadLocker.Unlock();
3721 
3722 	status_t status = thread_block_with_timeout(flags, timeout);
3723 
3724 	threadLocker.Lock();
3725 
3726 	// Interruptions or timeouts can race with other threads unblocking us.
3727 	// Favor a wake-up by another thread, i.e. if someone changed the wait
3728 	// status, use that.
3729 	set_ac();
3730 	status_t oldStatus = thread->user_thread->wait_status;
3731 	if (oldStatus > 0) {
3732 		thread->user_thread->wait_status = status;
3733 		clear_ac();
3734 	} else {
3735 		clear_ac();
3736 		status = oldStatus;
3737 	}
3738 
3739 	threadLocker.Unlock();
3740 
3741 	return syscall_restart_handle_timeout_post(status, timeout);
3742 }
3743 
3744 
3745 status_t
3746 _user_unblock_thread(thread_id threadID, status_t status)
3747 {
3748 	status_t error = user_unblock_thread(threadID, status);
3749 
3750 	if (error == B_OK)
3751 		scheduler_reschedule_if_necessary();
3752 
3753 	return error;
3754 }
3755 
3756 
3757 status_t
3758 _user_unblock_threads(thread_id* userThreads, uint32 count, status_t status)
3759 {
3760 	enum {
3761 		MAX_USER_THREADS_TO_UNBLOCK	= 128
3762 	};
3763 
3764 	if (userThreads == NULL || !IS_USER_ADDRESS(userThreads))
3765 		return B_BAD_ADDRESS;
3766 	if (count > MAX_USER_THREADS_TO_UNBLOCK)
3767 		return B_BAD_VALUE;
3768 
3769 	thread_id threads[MAX_USER_THREADS_TO_UNBLOCK];
3770 	if (user_memcpy(threads, userThreads, count * sizeof(thread_id)) != B_OK)
3771 		return B_BAD_ADDRESS;
3772 
3773 	for (uint32 i = 0; i < count; i++)
3774 		user_unblock_thread(threads[i], status);
3775 
3776 	scheduler_reschedule_if_necessary();
3777 
3778 	return B_OK;
3779 }
3780 
3781 
3782 // TODO: the following two functions don't belong here
3783 
3784 
3785 int
3786 _user_getrlimit(int resource, struct rlimit *urlp)
3787 {
3788 	struct rlimit rl;
3789 	int ret;
3790 
3791 	if (urlp == NULL)
3792 		return EINVAL;
3793 
3794 	if (!IS_USER_ADDRESS(urlp))
3795 		return B_BAD_ADDRESS;
3796 
3797 	ret = common_getrlimit(resource, &rl);
3798 
3799 	if (ret == 0) {
3800 		ret = user_memcpy(urlp, &rl, sizeof(struct rlimit));
3801 		if (ret < 0)
3802 			return ret;
3803 
3804 		return 0;
3805 	}
3806 
3807 	return ret;
3808 }
3809 
3810 
3811 int
3812 _user_setrlimit(int resource, const struct rlimit *userResourceLimit)
3813 {
3814 	struct rlimit resourceLimit;
3815 
3816 	if (userResourceLimit == NULL)
3817 		return EINVAL;
3818 
3819 	if (!IS_USER_ADDRESS(userResourceLimit)
3820 		|| user_memcpy(&resourceLimit, userResourceLimit,
3821 			sizeof(struct rlimit)) < B_OK)
3822 		return B_BAD_ADDRESS;
3823 
3824 	return common_setrlimit(resource, &resourceLimit);
3825 }
3826