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