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