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