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