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