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