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