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