xref: /haiku/src/system/kernel/thread.cpp (revision ab3e2cf4bc58c8cb63a554448b8df14a52869172)
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 || thread->state == B_THREAD_ASLEEP
1555 				|| thread->state == B_THREAD_WAITING) {
1556 			scheduler_enqueue_in_run_queue(thread);
1557 			kprintf("thread %" B_PRId32 " resumed\n", thread->id);
1558 		} else
1559 			kprintf("thread %" B_PRId32 " is already running\n", thread->id);
1560 		found = true;
1561 		break;
1562 	}
1563 	if (!found)
1564 		kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1565 
1566 	return 0;
1567 }
1568 
1569 
1570 static int
1571 drop_into_debugger(int argc, char **argv)
1572 {
1573 	status_t err;
1574 	int32 id;
1575 
1576 	if (argc > 2) {
1577 		print_debugger_command_usage(argv[0]);
1578 		return 0;
1579 	}
1580 
1581 	if (argc == 1)
1582 		id = thread_get_current_thread()->id;
1583 	else
1584 		id = strtoul(argv[1], NULL, 0);
1585 
1586 	err = _user_debug_thread(id);
1587 		// TODO: This is a non-trivial syscall doing some locking, so this is
1588 		// really nasty and may go seriously wrong.
1589 	if (err)
1590 		kprintf("drop failed\n");
1591 	else
1592 		kprintf("thread %" B_PRId32 " dropped into user debugger\n", id);
1593 
1594 	return 0;
1595 }
1596 
1597 
1598 /*!	Returns a user-readable string for a thread state.
1599 	Only for use in the kernel debugger.
1600 */
1601 static const char *
1602 state_to_text(Thread *thread, int32 state)
1603 {
1604 	switch (state) {
1605 		case B_THREAD_READY:
1606 			return "ready";
1607 
1608 		case B_THREAD_RUNNING:
1609 			return "running";
1610 
1611 		case B_THREAD_WAITING:
1612 		{
1613 			if (thread != NULL) {
1614 				switch (thread->wait.type) {
1615 					case THREAD_BLOCK_TYPE_SNOOZE:
1616 						return "zzz";
1617 
1618 					case THREAD_BLOCK_TYPE_SEMAPHORE:
1619 					{
1620 						sem_id sem = (sem_id)(addr_t)thread->wait.object;
1621 						if (sem == thread->msg.read_sem)
1622 							return "receive";
1623 						break;
1624 					}
1625 				}
1626 			}
1627 
1628 			return "waiting";
1629 		}
1630 
1631 		case B_THREAD_SUSPENDED:
1632 			return "suspended";
1633 
1634 		case THREAD_STATE_FREE_ON_RESCHED:
1635 			return "death";
1636 
1637 		default:
1638 			return "UNKNOWN";
1639 	}
1640 }
1641 
1642 
1643 static void
1644 print_thread_list_table_head()
1645 {
1646 	kprintf("%-*s       id  state     wait for  %-*s    cpu pri  %-*s   team  "
1647 		"name\n",
1648 		B_PRINTF_POINTER_WIDTH, "thread", B_PRINTF_POINTER_WIDTH, "object",
1649 		B_PRINTF_POINTER_WIDTH, "stack");
1650 }
1651 
1652 
1653 static void
1654 _dump_thread_info(Thread *thread, bool shortInfo)
1655 {
1656 	if (shortInfo) {
1657 		kprintf("%p %6" B_PRId32 "  %-10s", thread, thread->id,
1658 			state_to_text(thread, thread->state));
1659 
1660 		// does it block on a semaphore or a condition variable?
1661 		if (thread->state == B_THREAD_WAITING) {
1662 			switch (thread->wait.type) {
1663 				case THREAD_BLOCK_TYPE_SEMAPHORE:
1664 				{
1665 					sem_id sem = (sem_id)(addr_t)thread->wait.object;
1666 					if (sem == thread->msg.read_sem)
1667 						kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, "");
1668 					else {
1669 						kprintf("sem       %-*" B_PRId32,
1670 							B_PRINTF_POINTER_WIDTH + 5, sem);
1671 					}
1672 					break;
1673 				}
1674 
1675 				case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1676 					kprintf("cvar      %p   ", thread->wait.object);
1677 					break;
1678 
1679 				case THREAD_BLOCK_TYPE_SNOOZE:
1680 					kprintf("%*s", B_PRINTF_POINTER_WIDTH + 15, "");
1681 					break;
1682 
1683 				case THREAD_BLOCK_TYPE_SIGNAL:
1684 					kprintf("signal%*s", B_PRINTF_POINTER_WIDTH + 9, "");
1685 					break;
1686 
1687 				case THREAD_BLOCK_TYPE_MUTEX:
1688 					kprintf("mutex     %p   ", thread->wait.object);
1689 					break;
1690 
1691 				case THREAD_BLOCK_TYPE_RW_LOCK:
1692 					kprintf("rwlock    %p   ", thread->wait.object);
1693 					break;
1694 
1695 				case THREAD_BLOCK_TYPE_OTHER:
1696 					kprintf("other%*s", B_PRINTF_POINTER_WIDTH + 10, "");
1697 					break;
1698 
1699 				default:
1700 					kprintf("???       %p   ", thread->wait.object);
1701 					break;
1702 			}
1703 		} else
1704 			kprintf("-%*s", B_PRINTF_POINTER_WIDTH + 14, "");
1705 
1706 		// on which CPU does it run?
1707 		if (thread->cpu)
1708 			kprintf("%2d", thread->cpu->cpu_num);
1709 		else
1710 			kprintf(" -");
1711 
1712 		kprintf("%4" B_PRId32 "  %p%5" B_PRId32 "  %s\n", thread->priority,
1713 			(void *)thread->kernel_stack_base, thread->team->id, thread->name);
1714 
1715 		return;
1716 	}
1717 
1718 	// print the long info
1719 
1720 	struct thread_death_entry *death = NULL;
1721 
1722 	kprintf("THREAD: %p\n", thread);
1723 	kprintf("id:                 %" B_PRId32 " (%#" B_PRIx32 ")\n", thread->id,
1724 		thread->id);
1725 	kprintf("serial_number:      %" B_PRId64 "\n", thread->serial_number);
1726 	kprintf("name:               \"%s\"\n", thread->name);
1727 	kprintf("hash_next:          %p\nteam_next:          %p\n",
1728 		thread->hash_next, thread->team_next);
1729 	kprintf("priority:           %" B_PRId32 " (I/O: %" B_PRId32 ")\n",
1730 		thread->priority, thread->io_priority);
1731 	kprintf("state:              %s\n", state_to_text(thread, thread->state));
1732 	kprintf("cpu:                %p ", thread->cpu);
1733 	if (thread->cpu)
1734 		kprintf("(%d)\n", thread->cpu->cpu_num);
1735 	else
1736 		kprintf("\n");
1737 	kprintf("sig_pending:        %#" B_PRIx64 " (blocked: %#" B_PRIx64
1738 		", before sigsuspend(): %#" B_PRIx64 ")\n",
1739 		(int64)thread->ThreadPendingSignals(),
1740 		(int64)thread->sig_block_mask,
1741 		(int64)thread->sigsuspend_original_unblocked_mask);
1742 	kprintf("in_kernel:          %d\n", thread->in_kernel);
1743 
1744 	if (thread->state == B_THREAD_WAITING) {
1745 		kprintf("waiting for:        ");
1746 
1747 		switch (thread->wait.type) {
1748 			case THREAD_BLOCK_TYPE_SEMAPHORE:
1749 			{
1750 				sem_id sem = (sem_id)(addr_t)thread->wait.object;
1751 				if (sem == thread->msg.read_sem)
1752 					kprintf("data\n");
1753 				else
1754 					kprintf("semaphore %" B_PRId32 "\n", sem);
1755 				break;
1756 			}
1757 
1758 			case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
1759 				kprintf("condition variable %p\n", thread->wait.object);
1760 				break;
1761 
1762 			case THREAD_BLOCK_TYPE_SNOOZE:
1763 				kprintf("snooze()\n");
1764 				break;
1765 
1766 			case THREAD_BLOCK_TYPE_SIGNAL:
1767 				kprintf("signal\n");
1768 				break;
1769 
1770 			case THREAD_BLOCK_TYPE_MUTEX:
1771 				kprintf("mutex %p\n", thread->wait.object);
1772 				break;
1773 
1774 			case THREAD_BLOCK_TYPE_RW_LOCK:
1775 				kprintf("rwlock %p\n", thread->wait.object);
1776 				break;
1777 
1778 			case THREAD_BLOCK_TYPE_OTHER:
1779 				kprintf("other (%s)\n", (char*)thread->wait.object);
1780 				break;
1781 
1782 			default:
1783 				kprintf("unknown (%p)\n", thread->wait.object);
1784 				break;
1785 		}
1786 	}
1787 
1788 	kprintf("fault_handler:      %p\n", (void *)thread->fault_handler);
1789 	kprintf("team:               %p, \"%s\"\n", thread->team,
1790 		thread->team->Name());
1791 	kprintf("  exit.sem:         %" B_PRId32 "\n", thread->exit.sem);
1792 	kprintf("  exit.status:      %#" B_PRIx32 " (%s)\n", thread->exit.status,
1793 		strerror(thread->exit.status));
1794 	kprintf("  exit.waiters:\n");
1795 	while ((death = (struct thread_death_entry*)list_get_next_item(
1796 			&thread->exit.waiters, death)) != NULL) {
1797 		kprintf("\t%p (thread %" B_PRId32 ")\n", death, death->thread);
1798 	}
1799 
1800 	kprintf("kernel_stack_area:  %" B_PRId32 "\n", thread->kernel_stack_area);
1801 	kprintf("kernel_stack_base:  %p\n", (void *)thread->kernel_stack_base);
1802 	kprintf("user_stack_area:    %" B_PRId32 "\n", thread->user_stack_area);
1803 	kprintf("user_stack_base:    %p\n", (void *)thread->user_stack_base);
1804 	kprintf("user_local_storage: %p\n", (void *)thread->user_local_storage);
1805 	kprintf("user_thread:        %p\n", (void *)thread->user_thread);
1806 	kprintf("kernel_errno:       %#x (%s)\n", thread->kernel_errno,
1807 		strerror(thread->kernel_errno));
1808 	kprintf("kernel_time:        %" B_PRId64 "\n", thread->kernel_time);
1809 	kprintf("user_time:          %" B_PRId64 "\n", thread->user_time);
1810 	kprintf("flags:              0x%" B_PRIx32 "\n", thread->flags);
1811 	kprintf("architecture dependant section:\n");
1812 	arch_thread_dump_info(&thread->arch_info);
1813 	kprintf("scheduler data:\n");
1814 	scheduler_dump_thread_data(thread);
1815 }
1816 
1817 
1818 static int
1819 dump_thread_info(int argc, char **argv)
1820 {
1821 	bool shortInfo = false;
1822 	int argi = 1;
1823 	if (argi < argc && strcmp(argv[argi], "-s") == 0) {
1824 		shortInfo = true;
1825 		print_thread_list_table_head();
1826 		argi++;
1827 	}
1828 
1829 	if (argi == argc) {
1830 		_dump_thread_info(thread_get_current_thread(), shortInfo);
1831 		return 0;
1832 	}
1833 
1834 	for (; argi < argc; argi++) {
1835 		const char *name = argv[argi];
1836 		ulong arg = strtoul(name, NULL, 0);
1837 
1838 		if (IS_KERNEL_ADDRESS(arg)) {
1839 			// semi-hack
1840 			_dump_thread_info((Thread *)arg, shortInfo);
1841 			continue;
1842 		}
1843 
1844 		// walk through the thread list, trying to match name or id
1845 		bool found = false;
1846 		for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1847 				Thread* thread = it.Next();) {
1848 			if (!strcmp(name, thread->name) || thread->id == (thread_id)arg) {
1849 				_dump_thread_info(thread, shortInfo);
1850 				found = true;
1851 				break;
1852 			}
1853 		}
1854 
1855 		if (!found)
1856 			kprintf("thread \"%s\" (%" B_PRId32 ") doesn't exist!\n", name, (thread_id)arg);
1857 	}
1858 
1859 	return 0;
1860 }
1861 
1862 
1863 static int
1864 dump_thread_list(int argc, char **argv)
1865 {
1866 	bool realTimeOnly = false;
1867 	bool calling = false;
1868 	const char *callSymbol = NULL;
1869 	addr_t callStart = 0;
1870 	addr_t callEnd = 0;
1871 	int32 requiredState = 0;
1872 	team_id team = -1;
1873 	sem_id sem = -1;
1874 
1875 	if (!strcmp(argv[0], "realtime"))
1876 		realTimeOnly = true;
1877 	else if (!strcmp(argv[0], "ready"))
1878 		requiredState = B_THREAD_READY;
1879 	else if (!strcmp(argv[0], "running"))
1880 		requiredState = B_THREAD_RUNNING;
1881 	else if (!strcmp(argv[0], "waiting")) {
1882 		requiredState = B_THREAD_WAITING;
1883 
1884 		if (argc > 1) {
1885 			sem = strtoul(argv[1], NULL, 0);
1886 			if (sem == 0)
1887 				kprintf("ignoring invalid semaphore argument.\n");
1888 		}
1889 	} else if (!strcmp(argv[0], "calling")) {
1890 		if (argc < 2) {
1891 			kprintf("Need to give a symbol name or start and end arguments.\n");
1892 			return 0;
1893 		} else if (argc == 3) {
1894 			callStart = parse_expression(argv[1]);
1895 			callEnd = parse_expression(argv[2]);
1896 		} else
1897 			callSymbol = argv[1];
1898 
1899 		calling = true;
1900 	} else if (argc > 1) {
1901 		team = strtoul(argv[1], NULL, 0);
1902 		if (team == 0)
1903 			kprintf("ignoring invalid team argument.\n");
1904 	}
1905 
1906 	print_thread_list_table_head();
1907 
1908 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
1909 			Thread* thread = it.Next();) {
1910 		// filter out threads not matching the search criteria
1911 		if ((requiredState && thread->state != requiredState)
1912 			|| (calling && !arch_debug_contains_call(thread, callSymbol,
1913 					callStart, callEnd))
1914 			|| (sem > 0 && get_thread_wait_sem(thread) != sem)
1915 			|| (team > 0 && thread->team->id != team)
1916 			|| (realTimeOnly && thread->priority < B_REAL_TIME_DISPLAY_PRIORITY))
1917 			continue;
1918 
1919 		_dump_thread_info(thread, true);
1920 	}
1921 	return 0;
1922 }
1923 
1924 
1925 //	#pragma mark - private kernel API
1926 
1927 
1928 void
1929 thread_exit(void)
1930 {
1931 	cpu_status state;
1932 	Thread* thread = thread_get_current_thread();
1933 	Team* team = thread->team;
1934 	Team* kernelTeam = team_get_kernel_team();
1935 	status_t status;
1936 	struct thread_debug_info debugInfo;
1937 	team_id teamID = team->id;
1938 
1939 	TRACE(("thread %" B_PRId32 " exiting w/return code %#" B_PRIx32 "\n",
1940 		thread->id, thread->exit.status));
1941 
1942 	if (!are_interrupts_enabled())
1943 		panic("thread_exit() called with interrupts disabled!\n");
1944 
1945 	// boost our priority to get this over with
1946 	scheduler_set_thread_priority(thread, B_URGENT_DISPLAY_PRIORITY);
1947 
1948 	if (team != kernelTeam) {
1949 		// Delete all user timers associated with the thread.
1950 		ThreadLocker threadLocker(thread);
1951 		thread->DeleteUserTimers(false);
1952 
1953 		// detach the thread's user thread
1954 		user_thread* userThread = thread->user_thread;
1955 		thread->user_thread = NULL;
1956 
1957 		threadLocker.Unlock();
1958 
1959 		// Delete the thread's user thread, if it's not the main thread. If it
1960 		// is, we can save the work, since it will be deleted with the team's
1961 		// address space.
1962 		if (thread != team->main_thread)
1963 			team_free_user_thread(team, userThread);
1964 	}
1965 
1966 	// remember the user stack area -- we will delete it below
1967 	area_id userStackArea = -1;
1968 	if (team->address_space != NULL && thread->user_stack_area >= 0) {
1969 		userStackArea = thread->user_stack_area;
1970 		thread->user_stack_area = -1;
1971 	}
1972 
1973 	struct job_control_entry *death = NULL;
1974 	struct thread_death_entry* threadDeathEntry = NULL;
1975 	bool deleteTeam = false;
1976 	port_id debuggerPort = -1;
1977 
1978 	if (team != kernelTeam) {
1979 		user_debug_thread_exiting(thread);
1980 
1981 		if (team->main_thread == thread) {
1982 			// The main thread is exiting. Shut down the whole team.
1983 			deleteTeam = true;
1984 
1985 			// kill off all other threads and the user debugger facilities
1986 			debuggerPort = team_shutdown_team(team);
1987 
1988 			// acquire necessary locks, which are: process group lock, kernel
1989 			// team lock, parent team lock, and the team lock
1990 			team->LockProcessGroup();
1991 			kernelTeam->Lock();
1992 			team->LockTeamAndParent(true);
1993 		} else {
1994 			threadDeathEntry
1995 				= (thread_death_entry*)malloc(sizeof(thread_death_entry));
1996 
1997 			// acquire necessary locks, which are: kernel team lock and the team
1998 			// lock
1999 			kernelTeam->Lock();
2000 			team->Lock();
2001 		}
2002 
2003 		ThreadLocker threadLocker(thread);
2004 
2005 		state = disable_interrupts();
2006 
2007 		// swap address spaces, to make sure we're running on the kernel's pgdir
2008 		vm_swap_address_space(team->address_space, VMAddressSpace::Kernel());
2009 
2010 		WriteSpinLocker teamLocker(thread->team_lock);
2011 		SpinLocker threadCreationLocker(gThreadCreationLock);
2012 			// removing the thread and putting its death entry to the parent
2013 			// team needs to be an atomic operation
2014 
2015 		// remember how long this thread lasted
2016 		bigtime_t now = system_time();
2017 
2018 		InterruptsSpinLocker signalLocker(kernelTeam->signal_lock);
2019 		SpinLocker teamTimeLocker(kernelTeam->time_lock);
2020 		SpinLocker threadTimeLocker(thread->time_lock);
2021 
2022 		thread->kernel_time += now - thread->last_time;
2023 		thread->last_time = now;
2024 
2025 		team->dead_threads_kernel_time += thread->kernel_time;
2026 		team->dead_threads_user_time += thread->user_time;
2027 
2028 		// stop/update thread/team CPU time user timers
2029 		if (thread->HasActiveCPUTimeUserTimers()
2030 			|| team->HasActiveCPUTimeUserTimers()) {
2031 			user_timer_stop_cpu_timers(thread, NULL);
2032 		}
2033 
2034 		// deactivate CPU time user timers for the thread
2035 		if (thread->HasActiveCPUTimeUserTimers())
2036 			thread->DeactivateCPUTimeUserTimers();
2037 
2038 		threadTimeLocker.Unlock();
2039 
2040 		// put the thread into the kernel team until it dies
2041 		remove_thread_from_team(team, thread);
2042 		insert_thread_into_team(kernelTeam, thread);
2043 
2044 		teamTimeLocker.Unlock();
2045 		signalLocker.Unlock();
2046 
2047 		teamLocker.Unlock();
2048 
2049 		if (team->death_entry != NULL) {
2050 			if (--team->death_entry->remaining_threads == 0)
2051 				team->death_entry->condition.NotifyOne();
2052 		}
2053 
2054 		if (deleteTeam) {
2055 			Team* parent = team->parent;
2056 
2057 			// Set the team job control state to "dead" and detach the job
2058 			// control entry from our team struct.
2059 			team_set_job_control_state(team, JOB_CONTROL_STATE_DEAD, NULL);
2060 			death = team->job_control_entry;
2061 			team->job_control_entry = NULL;
2062 
2063 			if (death != NULL) {
2064 				death->InitDeadState();
2065 
2066 				// team_set_job_control_state() already moved our entry
2067 				// into the parent's list. We just check the soft limit of
2068 				// death entries.
2069 				if (parent->dead_children.count > MAX_DEAD_CHILDREN) {
2070 					death = parent->dead_children.entries.RemoveHead();
2071 					parent->dead_children.count--;
2072 				} else
2073 					death = NULL;
2074 			}
2075 
2076 			threadCreationLocker.Unlock();
2077 			restore_interrupts(state);
2078 
2079 			threadLocker.Unlock();
2080 
2081 			// Get a temporary reference to the team's process group
2082 			// -- team_remove_team() removes the team from the group, which
2083 			// might destroy it otherwise and we wouldn't be able to unlock it.
2084 			ProcessGroup* group = team->group;
2085 			group->AcquireReference();
2086 
2087 			pid_t foregroundGroupToSignal;
2088 			team_remove_team(team, foregroundGroupToSignal);
2089 
2090 			// unlock everything but the parent team
2091 			team->Unlock();
2092 			if (parent != kernelTeam)
2093 				kernelTeam->Unlock();
2094 			group->Unlock();
2095 			group->ReleaseReference();
2096 
2097 			// Send SIGCHLD to the parent as long as we still have its lock.
2098 			// This makes job control state change + signalling atomic.
2099 			Signal childSignal(SIGCHLD, team->exit.reason, B_OK, team->id);
2100 			if (team->exit.reason == CLD_EXITED) {
2101 				childSignal.SetStatus(team->exit.status);
2102 			} else {
2103 				childSignal.SetStatus(team->exit.signal);
2104 				childSignal.SetSendingUser(team->exit.signaling_user);
2105 			}
2106 			send_signal_to_team(parent, childSignal, B_DO_NOT_RESCHEDULE);
2107 
2108 			// also unlock the parent
2109 			parent->Unlock();
2110 
2111 			// If the team was a session leader with controlling TTY, we have
2112 			// to send SIGHUP to the foreground process group.
2113 			if (foregroundGroupToSignal >= 0) {
2114 				Signal groupSignal(SIGHUP, SI_USER, B_OK, team->id);
2115 				send_signal_to_process_group(foregroundGroupToSignal,
2116 					groupSignal, B_DO_NOT_RESCHEDULE);
2117 			}
2118 		} else {
2119 			// The thread is not the main thread. We store a thread death entry
2120 			// for it, unless someone is already waiting for it.
2121 			if (threadDeathEntry != NULL
2122 				&& list_is_empty(&thread->exit.waiters)) {
2123 				threadDeathEntry->thread = thread->id;
2124 				threadDeathEntry->status = thread->exit.status;
2125 
2126 				// add entry -- remove an old one, if we hit the limit
2127 				list_add_item(&team->dead_threads, threadDeathEntry);
2128 				team->dead_threads_count++;
2129 				threadDeathEntry = NULL;
2130 
2131 				if (team->dead_threads_count > MAX_DEAD_THREADS) {
2132 					threadDeathEntry
2133 						= (thread_death_entry*)list_remove_head_item(
2134 							&team->dead_threads);
2135 					team->dead_threads_count--;
2136 				}
2137 			}
2138 
2139 			threadCreationLocker.Unlock();
2140 			restore_interrupts(state);
2141 
2142 			threadLocker.Unlock();
2143 			team->Unlock();
2144 			kernelTeam->Unlock();
2145 		}
2146 
2147 		TRACE(("thread_exit: thread %" B_PRId32 " now a kernel thread!\n",
2148 			thread->id));
2149 	}
2150 
2151 	free(threadDeathEntry);
2152 
2153 	// delete the team if we're its main thread
2154 	if (deleteTeam) {
2155 		team_delete_team(team, debuggerPort);
2156 
2157 		// we need to delete any death entry that made it to here
2158 		delete death;
2159 	}
2160 
2161 	ThreadLocker threadLocker(thread);
2162 
2163 	state = disable_interrupts();
2164 	SpinLocker threadCreationLocker(gThreadCreationLock);
2165 
2166 	// mark invisible in global hash/list, so it's no longer accessible
2167 	SpinLocker threadHashLocker(sThreadHashLock);
2168 	thread->visible = false;
2169 	sUsedThreads--;
2170 	threadHashLocker.Unlock();
2171 
2172 	// Stop debugging for this thread
2173 	SpinLocker threadDebugInfoLocker(thread->debug_info.lock);
2174 	debugInfo = thread->debug_info;
2175 	clear_thread_debug_info(&thread->debug_info, true);
2176 	threadDebugInfoLocker.Unlock();
2177 
2178 	// Remove the select infos. We notify them a little later.
2179 	select_info* selectInfos = thread->select_infos;
2180 	thread->select_infos = NULL;
2181 
2182 	threadCreationLocker.Unlock();
2183 	restore_interrupts(state);
2184 
2185 	threadLocker.Unlock();
2186 
2187 	destroy_thread_debug_info(&debugInfo);
2188 
2189 	// notify select infos
2190 	select_info* info = selectInfos;
2191 	while (info != NULL) {
2192 		select_sync* sync = info->sync;
2193 
2194 		notify_select_events(info, B_EVENT_INVALID);
2195 		info = info->next;
2196 		put_select_sync(sync);
2197 	}
2198 
2199 	// notify listeners
2200 	sNotificationService.Notify(THREAD_REMOVED, thread);
2201 
2202 	// shutdown the thread messaging
2203 
2204 	status = acquire_sem_etc(thread->msg.write_sem, 1, B_RELATIVE_TIMEOUT, 0);
2205 	if (status == B_WOULD_BLOCK) {
2206 		// there is data waiting for us, so let us eat it
2207 		thread_id sender;
2208 
2209 		delete_sem(thread->msg.write_sem);
2210 			// first, let's remove all possibly waiting writers
2211 		receive_data_etc(&sender, NULL, 0, B_RELATIVE_TIMEOUT);
2212 	} else {
2213 		// we probably own the semaphore here, and we're the last to do so
2214 		delete_sem(thread->msg.write_sem);
2215 	}
2216 	// now we can safely remove the msg.read_sem
2217 	delete_sem(thread->msg.read_sem);
2218 
2219 	// fill all death entries and delete the sem that others will use to wait
2220 	// for us
2221 	{
2222 		sem_id cachedExitSem = thread->exit.sem;
2223 
2224 		ThreadLocker threadLocker(thread);
2225 
2226 		// make sure no one will grab this semaphore again
2227 		thread->exit.sem = -1;
2228 
2229 		// fill all death entries
2230 		thread_death_entry* entry = NULL;
2231 		while ((entry = (thread_death_entry*)list_get_next_item(
2232 				&thread->exit.waiters, entry)) != NULL) {
2233 			entry->status = thread->exit.status;
2234 		}
2235 
2236 		threadLocker.Unlock();
2237 
2238 		delete_sem(cachedExitSem);
2239 	}
2240 
2241 	// delete the user stack, if this was a user thread
2242 	if (!deleteTeam && userStackArea >= 0) {
2243 		// We postponed deleting the user stack until now, since this way all
2244 		// notifications for the thread's death are out already and all other
2245 		// threads waiting for this thread's death and some object on its stack
2246 		// will wake up before we (try to) delete the stack area. Of most
2247 		// relevance is probably the case where this is the main thread and
2248 		// other threads use objects on its stack -- so we want them terminated
2249 		// first.
2250 		// When the team is deleted, all areas are deleted anyway, so we don't
2251 		// need to do that explicitly in that case.
2252 		vm_delete_area(teamID, userStackArea, true);
2253 	}
2254 
2255 	// notify the debugger
2256 	if (teamID != kernelTeam->id)
2257 		user_debug_thread_deleted(teamID, thread->id);
2258 
2259 	// enqueue in the undertaker list and reschedule for the last time
2260 	UndertakerEntry undertakerEntry(thread, teamID);
2261 
2262 	disable_interrupts();
2263 
2264 	SpinLocker schedulerLocker(thread->scheduler_lock);
2265 
2266 	SpinLocker undertakerLocker(sUndertakerLock);
2267 	sUndertakerEntries.Add(&undertakerEntry);
2268 	sUndertakerCondition.NotifyOne();
2269 	undertakerLocker.Unlock();
2270 
2271 	scheduler_reschedule(THREAD_STATE_FREE_ON_RESCHED);
2272 
2273 	panic("never can get here\n");
2274 }
2275 
2276 
2277 /*!	Called in the interrupt handler code when a thread enters
2278 	the kernel for any reason.
2279 	Only tracks time for now.
2280 	Interrupts are disabled.
2281 */
2282 void
2283 thread_at_kernel_entry(bigtime_t now)
2284 {
2285 	Thread *thread = thread_get_current_thread();
2286 
2287 	TRACE(("thread_at_kernel_entry: entry thread %" B_PRId32 "\n", thread->id));
2288 
2289 	// track user time
2290 	SpinLocker threadTimeLocker(thread->time_lock);
2291 	thread->user_time += now - thread->last_time;
2292 	thread->last_time = now;
2293 	thread->in_kernel = true;
2294 	threadTimeLocker.Unlock();
2295 }
2296 
2297 
2298 /*!	Called whenever a thread exits kernel space to user space.
2299 	Tracks time, handles signals, ...
2300 	Interrupts must be enabled. When the function returns, interrupts will be
2301 	disabled.
2302 	The function may not return. This e.g. happens when the thread has received
2303 	a deadly signal.
2304 */
2305 void
2306 thread_at_kernel_exit(void)
2307 {
2308 	Thread *thread = thread_get_current_thread();
2309 
2310 	TRACE(("thread_at_kernel_exit: exit thread %" B_PRId32 "\n", thread->id));
2311 
2312 	handle_signals(thread);
2313 
2314 	disable_interrupts();
2315 
2316 	// track kernel time
2317 	bigtime_t now = system_time();
2318 	SpinLocker threadTimeLocker(thread->time_lock);
2319 	thread->in_kernel = false;
2320 	thread->kernel_time += now - thread->last_time;
2321 	thread->last_time = now;
2322 }
2323 
2324 
2325 /*!	The quick version of thread_kernel_exit(), in case no signals are pending
2326 	and no debugging shall be done.
2327 	Interrupts must be disabled.
2328 */
2329 void
2330 thread_at_kernel_exit_no_signals(void)
2331 {
2332 	Thread *thread = thread_get_current_thread();
2333 
2334 	TRACE(("thread_at_kernel_exit_no_signals: exit thread %" B_PRId32 "\n",
2335 		thread->id));
2336 
2337 	// track kernel time
2338 	bigtime_t now = system_time();
2339 	SpinLocker threadTimeLocker(thread->time_lock);
2340 	thread->in_kernel = false;
2341 	thread->kernel_time += now - thread->last_time;
2342 	thread->last_time = now;
2343 }
2344 
2345 
2346 void
2347 thread_reset_for_exec(void)
2348 {
2349 	Thread* thread = thread_get_current_thread();
2350 
2351 	ThreadLocker threadLocker(thread);
2352 
2353 	// delete user-defined timers
2354 	thread->DeleteUserTimers(true);
2355 
2356 	// cancel pre-defined timer
2357 	if (UserTimer* timer = thread->UserTimerFor(USER_TIMER_REAL_TIME_ID))
2358 		timer->Cancel();
2359 
2360 	// reset user_thread and user stack
2361 	thread->user_thread = NULL;
2362 	thread->user_stack_area = -1;
2363 	thread->user_stack_base = 0;
2364 	thread->user_stack_size = 0;
2365 
2366 	// reset signals
2367 	thread->ResetSignalsOnExec();
2368 
2369 	// reset thread CPU time clock
2370 	InterruptsSpinLocker timeLocker(thread->time_lock);
2371 	thread->cpu_clock_offset = -thread->CPUTime(false);
2372 }
2373 
2374 
2375 thread_id
2376 allocate_thread_id()
2377 {
2378 	InterruptsSpinLocker threadHashLocker(sThreadHashLock);
2379 
2380 	// find the next unused ID
2381 	thread_id id;
2382 	do {
2383 		id = sNextThreadID++;
2384 
2385 		// deal with integer overflow
2386 		if (sNextThreadID < 0)
2387 			sNextThreadID = 2;
2388 
2389 		// check whether the ID is already in use
2390 	} while (sThreadHash.Lookup(id, false) != NULL);
2391 
2392 	return id;
2393 }
2394 
2395 
2396 thread_id
2397 peek_next_thread_id()
2398 {
2399 	InterruptsSpinLocker threadHashLocker(sThreadHashLock);
2400 	return sNextThreadID;
2401 }
2402 
2403 
2404 /*!	Yield the CPU to other threads.
2405 	Thread will continue to run, if there's no other thread in ready
2406 	state, and if it has a higher priority than the other ready threads, it
2407 	still has a good chance to continue.
2408 */
2409 void
2410 thread_yield(void)
2411 {
2412 	Thread *thread = thread_get_current_thread();
2413 	if (thread == NULL)
2414 		return;
2415 
2416 	InterruptsSpinLocker _(thread->scheduler_lock);
2417 
2418 	thread->has_yielded = true;
2419 	scheduler_reschedule(B_THREAD_READY);
2420 }
2421 
2422 
2423 void
2424 thread_map(void (*function)(Thread* thread, void* data), void* data)
2425 {
2426 	InterruptsSpinLocker threadHashLocker(sThreadHashLock);
2427 
2428 	for (ThreadHashTable::Iterator it = sThreadHash.GetIterator();
2429 		Thread* thread = it.Next();) {
2430 		function(thread, data);
2431 	}
2432 }
2433 
2434 
2435 /*!	Kernel private thread creation function.
2436 */
2437 thread_id
2438 spawn_kernel_thread_etc(thread_func function, const char *name, int32 priority,
2439 	void *arg, team_id team)
2440 {
2441 	return thread_create_thread(
2442 		ThreadCreationAttributes(function, name, priority, arg, team),
2443 		true);
2444 }
2445 
2446 
2447 status_t
2448 wait_for_thread_etc(thread_id id, uint32 flags, bigtime_t timeout,
2449 	status_t *_returnCode)
2450 {
2451 	if (id < 0)
2452 		return B_BAD_THREAD_ID;
2453 
2454 	// get the thread, queue our death entry, and fetch the semaphore we have to
2455 	// wait on
2456 	sem_id exitSem = B_BAD_THREAD_ID;
2457 	struct thread_death_entry death;
2458 
2459 	Thread* thread = Thread::GetAndLock(id);
2460 	if (thread != NULL) {
2461 		// remember the semaphore we have to wait on and place our death entry
2462 		exitSem = thread->exit.sem;
2463 		if (exitSem >= 0)
2464 			list_add_link_to_head(&thread->exit.waiters, &death);
2465 
2466 		thread->UnlockAndReleaseReference();
2467 
2468 		if (exitSem < 0)
2469 			return B_BAD_THREAD_ID;
2470 	} else {
2471 		// we couldn't find this thread -- maybe it's already gone, and we'll
2472 		// find its death entry in our team
2473 		Team* team = thread_get_current_thread()->team;
2474 		TeamLocker teamLocker(team);
2475 
2476 		// check the child death entries first (i.e. main threads of child
2477 		// teams)
2478 		bool deleteEntry;
2479 		job_control_entry* freeDeath
2480 			= team_get_death_entry(team, id, &deleteEntry);
2481 		if (freeDeath != NULL) {
2482 			death.status = freeDeath->status;
2483 			if (deleteEntry)
2484 				delete freeDeath;
2485 		} else {
2486 			// check the thread death entries of the team (non-main threads)
2487 			thread_death_entry* threadDeathEntry = NULL;
2488 			while ((threadDeathEntry = (thread_death_entry*)list_get_next_item(
2489 					&team->dead_threads, threadDeathEntry)) != NULL) {
2490 				if (threadDeathEntry->thread == id) {
2491 					list_remove_item(&team->dead_threads, threadDeathEntry);
2492 					team->dead_threads_count--;
2493 					death.status = threadDeathEntry->status;
2494 					free(threadDeathEntry);
2495 					break;
2496 				}
2497 			}
2498 
2499 			if (threadDeathEntry == NULL)
2500 				return B_BAD_THREAD_ID;
2501 		}
2502 
2503 		// we found the thread's death entry in our team
2504 		if (_returnCode)
2505 			*_returnCode = death.status;
2506 
2507 		return B_OK;
2508 	}
2509 
2510 	// we need to wait for the death of the thread
2511 
2512 	resume_thread(id);
2513 		// make sure we don't wait forever on a suspended thread
2514 
2515 	status_t status = acquire_sem_etc(exitSem, 1, flags, timeout);
2516 
2517 	if (status == B_OK) {
2518 		// this should never happen as the thread deletes the semaphore on exit
2519 		panic("could acquire exit_sem for thread %" B_PRId32 "\n", id);
2520 	} else if (status == B_BAD_SEM_ID) {
2521 		// this is the way the thread normally exits
2522 		status = B_OK;
2523 	} else {
2524 		// We were probably interrupted or the timeout occurred; we need to
2525 		// remove our death entry now.
2526 		thread = Thread::GetAndLock(id);
2527 		if (thread != NULL) {
2528 			list_remove_link(&death);
2529 			thread->UnlockAndReleaseReference();
2530 		} else {
2531 			// The thread is already gone, so we need to wait uninterruptibly
2532 			// for its exit semaphore to make sure our death entry stays valid.
2533 			// It won't take long, since the thread is apparently already in the
2534 			// middle of the cleanup.
2535 			acquire_sem(exitSem);
2536 			status = B_OK;
2537 		}
2538 	}
2539 
2540 	if (status == B_OK && _returnCode != NULL)
2541 		*_returnCode = death.status;
2542 
2543 	return status;
2544 }
2545 
2546 
2547 status_t
2548 select_thread(int32 id, struct select_info* info, bool kernel)
2549 {
2550 	// get and lock the thread
2551 	Thread* thread = Thread::GetAndLock(id);
2552 	if (thread == NULL)
2553 		return B_BAD_THREAD_ID;
2554 	BReference<Thread> threadReference(thread, true);
2555 	ThreadLocker threadLocker(thread, true);
2556 
2557 	// We support only B_EVENT_INVALID at the moment.
2558 	info->selected_events &= B_EVENT_INVALID;
2559 
2560 	// add info to list
2561 	if (info->selected_events != 0) {
2562 		info->next = thread->select_infos;
2563 		thread->select_infos = info;
2564 
2565 		// we need a sync reference
2566 		atomic_add(&info->sync->ref_count, 1);
2567 	}
2568 
2569 	return B_OK;
2570 }
2571 
2572 
2573 status_t
2574 deselect_thread(int32 id, struct select_info* info, bool kernel)
2575 {
2576 	// get and lock the thread
2577 	Thread* thread = Thread::GetAndLock(id);
2578 	if (thread == NULL)
2579 		return B_BAD_THREAD_ID;
2580 	BReference<Thread> threadReference(thread, true);
2581 	ThreadLocker threadLocker(thread, true);
2582 
2583 	// remove info from list
2584 	select_info** infoLocation = &thread->select_infos;
2585 	while (*infoLocation != NULL && *infoLocation != info)
2586 		infoLocation = &(*infoLocation)->next;
2587 
2588 	if (*infoLocation != info)
2589 		return B_OK;
2590 
2591 	*infoLocation = info->next;
2592 
2593 	threadLocker.Unlock();
2594 
2595 	// surrender sync reference
2596 	put_select_sync(info->sync);
2597 
2598 	return B_OK;
2599 }
2600 
2601 
2602 int32
2603 thread_max_threads(void)
2604 {
2605 	return sMaxThreads;
2606 }
2607 
2608 
2609 int32
2610 thread_used_threads(void)
2611 {
2612 	InterruptsSpinLocker threadHashLocker(sThreadHashLock);
2613 	return sUsedThreads;
2614 }
2615 
2616 
2617 /*!	Returns a user-readable string for a thread state.
2618 	Only for use in the kernel debugger.
2619 */
2620 const char*
2621 thread_state_to_text(Thread* thread, int32 state)
2622 {
2623 	return state_to_text(thread, state);
2624 }
2625 
2626 
2627 int32
2628 thread_get_io_priority(thread_id id)
2629 {
2630 	Thread* thread = Thread::GetAndLock(id);
2631 	if (thread == NULL)
2632 		return B_BAD_THREAD_ID;
2633 	BReference<Thread> threadReference(thread, true);
2634 	ThreadLocker threadLocker(thread, true);
2635 
2636 	int32 priority = thread->io_priority;
2637 	if (priority < 0) {
2638 		// negative I/O priority means using the (CPU) priority
2639 		priority = thread->priority;
2640 	}
2641 
2642 	return priority;
2643 }
2644 
2645 
2646 void
2647 thread_set_io_priority(int32 priority)
2648 {
2649 	Thread* thread = thread_get_current_thread();
2650 	ThreadLocker threadLocker(thread);
2651 
2652 	thread->io_priority = priority;
2653 }
2654 
2655 
2656 status_t
2657 thread_init(kernel_args *args)
2658 {
2659 	TRACE(("thread_init: entry\n"));
2660 
2661 	// create the thread hash table
2662 	new(&sThreadHash) ThreadHashTable();
2663 	if (sThreadHash.Init(128) != B_OK)
2664 		panic("thread_init(): failed to init thread hash table!");
2665 
2666 	// create the thread structure object cache
2667 	sThreadCache = create_object_cache("threads", sizeof(Thread), 16, NULL,
2668 		NULL, NULL);
2669 		// Note: The x86 port requires 16 byte alignment of thread structures.
2670 	if (sThreadCache == NULL)
2671 		panic("thread_init(): failed to allocate thread object cache!");
2672 
2673 	if (arch_thread_init(args) < B_OK)
2674 		panic("arch_thread_init() failed!\n");
2675 
2676 	// skip all thread IDs including B_SYSTEM_TEAM, which is reserved
2677 	sNextThreadID = B_SYSTEM_TEAM + 1;
2678 
2679 	// create an idle thread for each cpu
2680 	for (uint32 i = 0; i < args->num_cpus; i++) {
2681 		Thread *thread;
2682 		area_info info;
2683 		char name[64];
2684 
2685 		sprintf(name, "idle thread %" B_PRIu32, i + 1);
2686 		thread = new(&sIdleThreads[i]) Thread(name,
2687 			i == 0 ? team_get_kernel_team_id() : -1, &gCPU[i]);
2688 		if (thread == NULL || thread->Init(true) != B_OK) {
2689 			panic("error creating idle thread struct\n");
2690 			return B_NO_MEMORY;
2691 		}
2692 
2693 		gCPU[i].running_thread = thread;
2694 
2695 		thread->team = team_get_kernel_team();
2696 		thread->priority = B_IDLE_PRIORITY;
2697 		thread->state = B_THREAD_RUNNING;
2698 		sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1);
2699 		thread->kernel_stack_area = find_area(name);
2700 
2701 		if (get_area_info(thread->kernel_stack_area, &info) != B_OK)
2702 			panic("error finding idle kstack area\n");
2703 
2704 		thread->kernel_stack_base = (addr_t)info.address;
2705 		thread->kernel_stack_top = thread->kernel_stack_base + info.size;
2706 
2707 		thread->visible = true;
2708 		insert_thread_into_team(thread->team, thread);
2709 
2710 		scheduler_on_thread_init(thread);
2711 	}
2712 	sUsedThreads = args->num_cpus;
2713 
2714 	// init the notification service
2715 	new(&sNotificationService) ThreadNotificationService();
2716 
2717 	sNotificationService.Register();
2718 
2719 	// start the undertaker thread
2720 	new(&sUndertakerEntries) DoublyLinkedList<UndertakerEntry>();
2721 	sUndertakerCondition.Init(&sUndertakerEntries, "undertaker entries");
2722 
2723 	thread_id undertakerThread = spawn_kernel_thread(&undertaker, "undertaker",
2724 		B_DISPLAY_PRIORITY, NULL);
2725 	if (undertakerThread < 0)
2726 		panic("Failed to create undertaker thread!");
2727 	resume_thread(undertakerThread);
2728 
2729 	// set up some debugger commands
2730 	add_debugger_command_etc("threads", &dump_thread_list, "List all threads",
2731 		"[ <team> ]\n"
2732 		"Prints a list of all existing threads, or, if a team ID is given,\n"
2733 		"all threads of the specified team.\n"
2734 		"  <team>  - The ID of the team whose threads shall be listed.\n", 0);
2735 	add_debugger_command_etc("ready", &dump_thread_list,
2736 		"List all ready threads",
2737 		"\n"
2738 		"Prints a list of all threads in ready state.\n", 0);
2739 	add_debugger_command_etc("running", &dump_thread_list,
2740 		"List all running threads",
2741 		"\n"
2742 		"Prints a list of all threads in running state.\n", 0);
2743 	add_debugger_command_etc("waiting", &dump_thread_list,
2744 		"List all waiting threads (optionally for a specific semaphore)",
2745 		"[ <sem> ]\n"
2746 		"Prints a list of all threads in waiting state. If a semaphore is\n"
2747 		"specified, only the threads waiting on that semaphore are listed.\n"
2748 		"  <sem>  - ID of the semaphore.\n", 0);
2749 	add_debugger_command_etc("realtime", &dump_thread_list,
2750 		"List all realtime threads",
2751 		"\n"
2752 		"Prints a list of all threads with realtime priority.\n", 0);
2753 	add_debugger_command_etc("thread", &dump_thread_info,
2754 		"Dump info about a particular thread",
2755 		"[ -s ] ( <id> | <address> | <name> )*\n"
2756 		"Prints information about the specified thread. If no argument is\n"
2757 		"given the current thread is selected.\n"
2758 		"  -s         - Print info in compact table form (like \"threads\").\n"
2759 		"  <id>       - The ID of the thread.\n"
2760 		"  <address>  - The address of the thread structure.\n"
2761 		"  <name>     - The thread's name.\n", 0);
2762 	add_debugger_command_etc("calling", &dump_thread_list,
2763 		"Show all threads that have a specific address in their call chain",
2764 		"{ <symbol-pattern> | <start> <end> }\n", 0);
2765 	add_debugger_command_etc("unreal", &make_thread_unreal,
2766 		"Set realtime priority threads to normal priority",
2767 		"[ <id> ]\n"
2768 		"Sets the priority of all realtime threads or, if given, the one\n"
2769 		"with the specified ID to \"normal\" priority.\n"
2770 		"  <id>  - The ID of the thread.\n", 0);
2771 	add_debugger_command_etc("suspend", &make_thread_suspended,
2772 		"Suspend a thread",
2773 		"[ <id> ]\n"
2774 		"Suspends the thread with the given ID. If no ID argument is given\n"
2775 		"the current thread is selected.\n"
2776 		"  <id>  - The ID of the thread.\n", 0);
2777 	add_debugger_command_etc("resume", &make_thread_resumed, "Resume a thread",
2778 		"<id>\n"
2779 		"Resumes the specified thread, if it is currently suspended.\n"
2780 		"  <id>  - The ID of the thread.\n", 0);
2781 	add_debugger_command_etc("drop", &drop_into_debugger,
2782 		"Drop a thread into the userland debugger",
2783 		"<id>\n"
2784 		"Drops the specified (userland) thread into the userland debugger\n"
2785 		"after leaving the kernel debugger.\n"
2786 		"  <id>  - The ID of the thread.\n", 0);
2787 	add_debugger_command_etc("priority", &set_thread_prio,
2788 		"Set a thread's priority",
2789 		"<priority> [ <id> ]\n"
2790 		"Sets the priority of the thread with the specified ID to the given\n"
2791 		"priority. If no thread ID is given, the current thread is selected.\n"
2792 		"  <priority>  - The thread's new priority (0 - 120)\n"
2793 		"  <id>        - The ID of the thread.\n", 0);
2794 
2795 	return B_OK;
2796 }
2797 
2798 
2799 status_t
2800 thread_preboot_init_percpu(struct kernel_args *args, int32 cpuNum)
2801 {
2802 	// set up the cpu pointer in the not yet initialized per-cpu idle thread
2803 	// so that get_current_cpu and friends will work, which is crucial for
2804 	// a lot of low level routines
2805 	sIdleThreads[cpuNum].cpu = &gCPU[cpuNum];
2806 	arch_thread_set_current_thread(&sIdleThreads[cpuNum]);
2807 	return B_OK;
2808 }
2809 
2810 
2811 //	#pragma mark - thread blocking API
2812 
2813 
2814 static status_t
2815 thread_block_timeout(timer* timer)
2816 {
2817 	Thread* thread = (Thread*)timer->user_data;
2818 	thread_unblock(thread, B_TIMED_OUT);
2819 
2820 	return B_HANDLED_INTERRUPT;
2821 }
2822 
2823 
2824 /*!	Blocks the current thread.
2825 
2826 	The thread is blocked until someone else unblock it. Must be called after a
2827 	call to thread_prepare_to_block(). If the thread has already been unblocked
2828 	after the previous call to thread_prepare_to_block(), this function will
2829 	return immediately. Cf. the documentation of thread_prepare_to_block() for
2830 	more details.
2831 
2832 	The caller must hold the scheduler lock.
2833 
2834 	\param thread The current thread.
2835 	\return The error code passed to the unblocking function. thread_interrupt()
2836 		uses \c B_INTERRUPTED. By convention \c B_OK means that the wait was
2837 		successful while another error code indicates a failure (what that means
2838 		depends on the client code).
2839 */
2840 static inline status_t
2841 thread_block_locked(Thread* thread)
2842 {
2843 	if (thread->wait.status == 1) {
2844 		// check for signals, if interruptible
2845 		if (thread_is_interrupted(thread, thread->wait.flags)) {
2846 			thread->wait.status = B_INTERRUPTED;
2847 		} else
2848 			scheduler_reschedule(B_THREAD_WAITING);
2849 	}
2850 
2851 	return thread->wait.status;
2852 }
2853 
2854 
2855 /*!	Blocks the current thread.
2856 
2857 	The function acquires the scheduler lock and calls thread_block_locked().
2858 	See there for more information.
2859 */
2860 status_t
2861 thread_block()
2862 {
2863 	InterruptsSpinLocker _(thread_get_current_thread()->scheduler_lock);
2864 	return thread_block_locked(thread_get_current_thread());
2865 }
2866 
2867 
2868 /*!	Blocks the current thread with a timeout.
2869 
2870 	The current thread is blocked until someone else unblock it or the specified
2871 	timeout occurs. Must be called after a call to thread_prepare_to_block(). If
2872 	the thread has already been unblocked after the previous call to
2873 	thread_prepare_to_block(), this function will return immediately. See
2874 	thread_prepare_to_block() for more details.
2875 
2876 	The caller must not hold the scheduler lock.
2877 
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