Lines Matching refs:thread

15 #include <thread.h>
74 // thread list
90 Thread* thread;
93 UndertakerEntry(Thread* thread, team_id teamID)
95 thread(thread),
126 Thread* thread = NULL)
133 event.AddInt32("thread", threadID);
134 if (thread != NULL)
135 event.AddPointer("threadStruct", thread);
140 void Notify(uint32 eventCode, Thread* thread)
142 return Notify(eventCode, thread->id, thread->team->id, thread);
153 // object cache to allocate thread structures from
160 /*! Constructs a thread.
162 \param name The thread's name.
163 \param threadID The ID to be assigned to the new thread. If
165 \param cpu The CPU the thread shall be assigned.
220 strcpy(this->name, "unnamed thread");
230 // add to thread table -- yet invisible
238 // Delete resources that should actually be deleted by the thread itself,
239 // when it exited, but that might still exist, if the thread was never run.
264 // remove from thread table
273 Thread* thread = new Thread(name, -1, NULL);
274 if (thread == NULL)
277 status_t error = thread->Init(false);
279 delete thread;
283 _thread = thread;
292 Thread* thread = sThreadHash.Lookup(id);
293 if (thread != NULL)
294 thread->AcquireReference();
295 return thread;
304 Thread* thread = sThreadHash.Lookup(id);
305 if (thread == NULL)
308 thread->AcquireReference();
312 thread->Lock();
315 if (sThreadHash.Lookup(id) == thread)
316 return thread;
320 // nope, the thread is no longer in the hash table
321 thread->UnlockAndReleaseReference();
394 /*! Checks whether the thread is still in the thread hash table.
419 /*! Adds the given user timer to the thread and, if user-defined, assigns it an
422 The caller must hold the thread's lock.
443 /*! Removes the given user timer from the thread.
445 The caller must hold the thread's lock.
460 /*! Deletes all (or all user-defined) user timers of the thread.
462 The caller must hold the thread's lock.
508 Thread* thread = sThreadHash.NextElement(&fEntry);
509 if (thread != NULL)
510 thread->AcquireReference();
512 return thread;
521 Thread* thread)
534 this->thread = thread;
575 name = name != NULL ? nameBuffer : "user thread";
580 thread = NULL;
582 // inherit the current thread's signal mask
595 /*! Inserts a thread into a team.
596 The caller must hold the team's lock, the thread's lock, and the scheduler
600 insert_thread_into_team(Team *team, Thread *thread)
602 thread->team_next = team->thread_list;
603 team->thread_list = thread;
607 // this was the first thread
608 team->main_thread = thread;
610 thread->team = team;
614 /*! Removes a thread from a team.
615 The caller must hold the team's lock, the thread's lock, and the scheduler
619 remove_thread_from_team(Team *team, Thread *thread)
624 if (temp == thread) {
639 enter_userspace(Thread* thread, UserThreadEntryArguments* args)
641 status_t error = arch_thread_init_tls(thread);
643 dprintf("Failed to init TLS for new userland thread \"%s\" (%" B_PRId32
644 ")\n", thread->name, thread->id);
649 user_debug_update_new_thread_flags(thread);
651 // init the thread's user_thread
652 user_thread* userThread = thread->user_thread;
665 tls[TLS_BASE_ADDRESS_SLOT] = thread->user_local_storage;
666 tls[TLS_THREAD_ID_SLOT] = thread->id;
667 tls[TLS_USER_THREAD_SLOT] = (addr_t)thread->user_thread;
670 if (user_memcpy((void*)thread->user_local_storage, tls, sizeof(tls)) != B_OK)
673 // This is a fork()ed thread.
677 addr_t* userTls = (addr_t*)thread->user_local_storage;
678 ASSERT(userTls[TLS_BASE_ADDRESS_SLOT] == thread->user_local_storage);
693 return arch_thread_enter_userspace(thread, args->userlandEntry,
699 thread_enter_userspace_new_team(Thread* thread, addr_t entryFunction,
713 return enter_userspace(thread, &entryArgs);
720 Thread* thread = thread_get_current_thread();
722 // The thread is new and has been scheduled the first time.
724 scheduler_new_thread_entry(thread);
727 release_spinlock(&thread->scheduler_lock);
737 enter_userspace(thread, (UserThreadEntryArguments*)args);
740 // If that's the team's main thread, init the team exit info.
741 if (thread == thread->team->main_thread)
742 team_init_exit_info_on_error(thread->team);
750 /*! Prepares the given thread's kernel stack for executing its entry function.
753 thread's kernel stack. A pointer to the copy's data is passed to the entry
756 \param thread The thread.
757 \param data Pointer to data to be copied to the thread's stack and passed
762 init_thread_kernel_stack(Thread* thread, const void* data, size_t dataSize)
764 uint8* stack = (uint8*)thread->kernel_stack_base;
765 uint8* stackTop = (uint8*)thread->kernel_stack_top;
791 arch_thread_init_kthread_stack(thread, stack, stackTop,
797 create_thread_user_stack(Team* team, Thread* thread, void* _stackBase,
814 // will be between USER_STACK_REGION and the main thread stack area. For
815 // a main thread the position is fixed.
820 // Use the default size (a different one for a main thread).
821 stackSize = thread->id == team->id
835 thread->name, thread->id);
854 ThreadLocker threadLocker(thread);
856 thread->user_stack_base = (addr_t)stackBase + guardSize;
858 thread->user_stack_base = (addr_t)stackBase;
860 thread->user_stack_size = stackSize;
861 thread->user_stack_area = stackArea;
868 thread_create_user_stack(Team* team, Thread* thread, void* stackBase,
872 return create_thread_user_stack(team, thread, stackBase, stackSize,
877 /*! Creates a new thread.
879 \param attributes The thread creation attributes, specifying the team in
880 which to create the thread, as well as a whole bunch of other arguments.
881 \param kernel \c true, if a kernel-only thread shall be created, \c false,
882 if the thread shall also be able to run in userland.
883 \return The ID of the newly created thread (>= 0) or an error code on
891 TRACE(("thread_create_thread(%s, thread = %p, %s)\n", attributes.name,
892 attributes.thread, kernel ? "kernel" : "user"));
900 // If a thread object is given, acquire a reference to it, otherwise create
901 // a new thread object with the given attributes.
902 Thread* thread = attributes.thread;
903 if (thread != NULL) {
904 thread->AcquireReference();
906 status = Thread::Create(attributes.name, thread);
910 BReference<Thread> threadReference(thread, true);
912 thread->team = team;
915 thread->priority = attributes.priority == -1
917 thread->priority = std::max(thread->priority,
919 thread->priority = std::min(thread->priority,
921 thread->state = B_THREAD_SUSPENDED;
923 thread->sig_block_mask = attributes.signal_mask;
926 init_thread_debug_info(&thread->debug_info);
931 thread->name, thread->id);
936 thread->kernel_stack_area = create_area_etc(B_SYSTEM_TEAM, stackName,
941 (void**)&thread->kernel_stack_base);
943 if (thread->kernel_stack_area < 0) {
945 status = thread->kernel_stack_area;
953 thread->kernel_stack_top = thread->kernel_stack_base + KERNEL_STACK_SIZE
957 // Init the thread's kernel stack. It will start executing
964 init_thread_kernel_stack(thread, &entryArgs, sizeof(entryArgs));
966 // create the userland stack, if the thread doesn't have one yet
967 if (thread->user_stack_base == 0) {
968 status = create_thread_user_stack(team, thread,
976 // Init the thread's kernel stack. It will start executing
989 init_thread_kernel_stack(thread, &entryArgs, sizeof(entryArgs));
991 // create the pre-defined thread timers
992 status = user_timer_create_thread_timers(team, thread);
1005 if (thread->user_thread == NULL) {
1006 thread->user_thread = team_allocate_user_thread(team);
1007 if (thread->user_thread == NULL)
1011 // If the new thread belongs to the same team as the current thread, it
1012 // may inherit some of the thread debug flags.
1025 thread->debug_info.flags = debugFlags;
1027 // stop the new thread, if desired
1032 // We're going to make the thread live, now. The thread itself will take
1036 ThreadLocker threadLocker(thread);
1041 // check the thread limit
1048 user_thread* userThread = thread->user_thread;
1049 thread->user_thread = NULL;
1060 // make thread visible in global hash/list
1061 thread->visible = true;
1064 scheduler_on_thread_init(thread);
1066 thread->AcquireReference();
1068 // Debug the new thread, if the parent thread required that (see above),
1076 thread->debug_info.flags |= B_THREAD_DEBUG_STOP;
1084 // insert thread into team
1085 insert_thread_into_team(team, thread);
1094 sNotificationService.Notify(THREAD_ADDED, thread);
1096 return thread->id;
1104 // wait for a thread to bury
1121 // we need a copy, since the original entry is on the thread's stack
1124 Thread* thread = entry.thread;
1126 // make sure the thread isn't running anymore
1127 InterruptsSpinLocker schedulerLocker(thread->scheduler_lock);
1128 ASSERT(thread->state == THREAD_STATE_FREE_ON_RESCHED);
1131 // remove this thread from from the kernel team -- this makes it
1135 thread->Lock();
1141 remove_thread_from_team(kernelTeam, thread);
1149 // free the thread structure
1150 thread->UnlockAndReleaseReference();
1158 /*! Returns the semaphore the thread is currently waiting on.
1163 \param thread The thread.
1164 \return The ID of the semaphore the thread is currently waiting on or \c -1,
1168 get_thread_wait_sem(Thread* thread)
1170 if (thread->state == B_THREAD_WAITING
1171 && thread->wait.type == THREAD_BLOCK_TYPE_SEMAPHORE) {
1172 return (sem_id)(addr_t)thread->wait.object;
1178 /*! Fills the thread_info structure with information from the specified thread.
1179 The caller must hold the thread's lock and the scheduler lock.
1182 fill_thread_info(Thread *thread, thread_info *info, size_t size)
1184 info->thread = thread->id;
1185 info->team = thread->team->id;
1187 strlcpy(info->name, thread->name, B_OS_NAME_LENGTH);
1191 if (thread->state == B_THREAD_WAITING) {
1194 switch (thread->wait.type) {
1201 sem_id sem = (sem_id)(addr_t)thread->wait.object;
1202 if (sem == thread->msg.read_sem)
1214 info->state = (thread_state)thread->state;
1216 info->priority = thread->priority;
1217 info->stack_base = (void *)thread->user_stack_base;
1218 info->stack_end = (void *)(thread->user_stack_base
1219 + thread->user_stack_size);
1221 InterruptsSpinLocker threadTimeLocker(thread->time_lock);
1222 info->user_time = thread->user_time;
1223 info->kernel_time = thread->kernel_time;
1231 // get the thread
1251 // Any other acquisition problems may be due to thread deletion
1269 // The target thread could have been deleted at this point.
1294 Thread *thread = thread_get_current_thread();
1298 status_t status = acquire_sem_etc(thread->msg.read_sem, 1, flags, 0);
1307 if (buffer != NULL && bufferSize != 0 && thread->msg.buffer != NULL) {
1308 size = min_c(bufferSize, thread->msg.size);
1309 status = user_memcpy(buffer, thread->msg.buffer, size);
1311 free(thread->msg.buffer);
1312 release_sem(thread->msg.write_sem);
1317 *_sender = thread->msg.sender;
1318 code = thread->msg.code;
1320 free(thread->msg.buffer);
1321 release_sem(thread->msg.write_sem);
1418 Thread* thread = thread_get_current_thread();
1420 thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_SNOOZE,
1474 Thread* thread = it.Next();) {
1475 if (id != -1 && thread->id != id)
1478 if (thread->priority > B_DISPLAY_PRIORITY) {
1479 scheduler_set_thread_priority(thread, B_NORMAL_PRIORITY);
1480 kprintf("thread %" B_PRId32 " made unreal\n", thread->id);
1512 Thread* thread = it.Next();) {
1513 if (thread->id != id)
1515 scheduler_set_thread_priority(thread, prio);
1516 kprintf("thread %" B_PRId32 " set to priority %" B_PRId32 "\n", id, prio);
1521 kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1544 Thread* thread = it.Next();) {
1545 if (thread->id != id)
1549 send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE);
1551 kprintf("thread %" B_PRId32 " suspended\n", id);
1556 kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1572 // force user to enter a thread id, as using
1573 // the current thread is usually not intended
1578 Thread* thread = it.Next();) {
1579 if (thread->id != id)
1582 if (thread->state == B_THREAD_SUSPENDED || thread->state == B_THREAD_ASLEEP
1583 || thread->state == B_THREAD_WAITING) {
1584 scheduler_enqueue_in_run_queue(thread);
1585 kprintf("thread %" B_PRId32 " resumed\n", thread->id);
1587 kprintf("thread %" B_PRId32 " is already running\n", thread->id);
1592 kprintf("thread %" B_PRId32 " (%#" B_PRIx32 ") not found\n", id, id);
1620 kprintf("thread %" B_PRId32 " dropped into user debugger\n", id);
1626 /*! Returns a user-readable string for a thread state.
1630 state_to_text(Thread *thread, int32 state)
1641 if (thread != NULL) {
1642 switch (thread->wait.type) {
1648 sem_id sem = (sem_id)(addr_t)thread->wait.object;
1649 if (sem == thread->msg.read_sem)
1676 B_PRINTF_POINTER_WIDTH, "thread", B_PRINTF_POINTER_WIDTH, "object",
1682 _dump_thread_info(Thread *thread, bool shortInfo)
1685 kprintf("%p %6" B_PRId32 " %-10s", thread, thread->id,
1686 state_to_text(thread, thread->state));
1689 if (thread->state == B_THREAD_WAITING) {
1690 switch (thread->wait.type) {
1693 sem_id sem = (sem_id)(addr_t)thread->wait.object;
1694 if (sem == thread->msg.read_sem)
1707 (ConditionVariable*)thread->wait.object, name, sizeof(name));
1709 kprintf("cvar:%*s %p ", 4, name, thread->wait.object);
1711 kprintf("cvar %p ", thread->wait.object);
1724 kprintf("mutex %p ", thread->wait.object);
1728 kprintf("rwlock %p ", thread->wait.object);
1740 kprintf("other %p ", thread->wait.object);
1744 kprintf("??? %p ", thread->wait.object);
1751 if (thread->cpu)
1752 kprintf("%2d", thread->cpu->cpu_num);
1756 kprintf("%4" B_PRId32 " %p%5" B_PRId32 " %s\n", thread->priority,
1757 (void *)thread->kernel_stack_base, thread->team->id, thread->name);
1766 kprintf("THREAD: %p\n", thread);
1767 kprintf("id: %" B_PRId32 " (%#" B_PRIx32 ")\n", thread->id,
1768 thread->id);
1769 kprintf("serial_number: %" B_PRId64 "\n", thread->serial_number);
1770 kprintf("name: \"%s\"\n", thread->name);
1772 thread->hash_next, thread->team_next);
1774 thread->priority, thread->io_priority);
1775 kprintf("state: %s\n", state_to_text(thread, thread->state));
1776 kprintf("cpu: %p ", thread->cpu);
1777 if (thread->cpu)
1778 kprintf("(%d)\n", thread->cpu->cpu_num);
1783 (int64)thread->ThreadPendingSignals(),
1784 (int64)thread->sig_block_mask,
1785 (int64)thread->sigsuspend_original_unblocked_mask);
1786 kprintf("in_kernel: %d\n", thread->in_kernel);
1788 if (thread->state == B_THREAD_WAITING) {
1791 switch (thread->wait.type) {
1794 sem_id sem = (sem_id)(addr_t)thread->wait.object;
1795 if (sem == thread->msg.read_sem)
1803 kprintf("condition variable %p\n", thread->wait.object);
1815 kprintf("mutex %p\n", thread->wait.object);
1819 kprintf("rwlock %p\n", thread->wait.object);
1827 kprintf("other (%s)\n", (char*)thread->wait.object);
1831 kprintf("other (%p)\n", thread->wait.object);
1835 kprintf("unknown (%p)\n", thread->wait.object);
1840 kprintf("fault_handler: %p\n", (void *)thread->fault_handler);
1841 kprintf("team: %p, \"%s\"\n", thread->team,
1842 thread->team->Name());
1843 kprintf(" exit.sem: %" B_PRId32 "\n", thread->exit.sem);
1844 kprintf(" exit.status: %#" B_PRIx32 " (%s)\n", thread->exit.status,
1845 strerror(thread->exit.status));
1848 &thread->exit.waiters, death)) != NULL) {
1849 kprintf("\t%p (thread %" B_PRId32 ")\n", death, death->thread);
1852 kprintf("kernel_stack_area: %" B_PRId32 "\n", thread->kernel_stack_area);
1853 kprintf("kernel_stack_base: %p\n", (void *)thread->kernel_stack_base);
1854 kprintf("user_stack_area: %" B_PRId32 "\n", thread->user_stack_area);
1855 kprintf("user_stack_base: %p\n", (void *)thread->user_stack_base);
1856 kprintf("user_local_storage: %p\n", (void *)thread->user_local_storage);
1857 kprintf("user_thread: %p\n", (void *)thread->user_thread);
1858 kprintf("kernel_errno: %#x (%s)\n", thread->kernel_errno,
1859 strerror(thread->kernel_errno));
1860 kprintf("kernel_time: %" B_PRId64 "\n", thread->kernel_time);
1861 kprintf("user_time: %" B_PRId64 "\n", thread->user_time);
1862 kprintf("flags: 0x%" B_PRIx32 "\n", thread->flags);
1864 arch_thread_dump_info(&thread->arch_info);
1866 scheduler_dump_thread_data(thread);
1896 // walk through the thread list, trying to match name or id
1899 Thread* thread = it.Next();) {
1900 if (!strcmp(name, thread->name) || thread->id == (thread_id)arg) {
1901 _dump_thread_info(thread, shortInfo);
1908 kprintf("thread \"%s\" (%" B_PRId32 ") doesn't exist!\n", name, (thread_id)arg);
1961 Thread* thread = it.Next();) {
1963 if ((requiredState && thread->state != requiredState)
1964 || (calling && !arch_debug_contains_call(thread, callSymbol,
1966 || (sem > 0 && get_thread_wait_sem(thread) != sem)
1967 || (team > 0 && thread->team->id != team)
1968 || (realTimeOnly && thread->priority < B_REAL_TIME_DISPLAY_PRIORITY))
1971 _dump_thread_info(thread, true);
1978 update_thread_sigmask_on_exit(Thread* thread)
1980 if ((thread->flags & THREAD_FLAGS_OLD_SIGMASK) != 0) {
1981 thread->flags &= ~THREAD_FLAGS_OLD_SIGMASK;
1982 sigprocmask(SIG_SETMASK, &thread->old_sig_block_mask, NULL);
1994 Thread* thread = thread_get_current_thread();
1995 Team* team = thread->team;
2001 TRACE(("thread %" B_PRId32 " exiting w/return code %#" B_PRIx32 "\n",
2002 thread->id, thread->exit.status));
2008 scheduler_set_thread_priority(thread, B_URGENT_DISPLAY_PRIORITY);
2011 // Delete all user timers associated with the thread.
2012 ThreadLocker threadLocker(thread);
2013 thread->DeleteUserTimers(false);
2015 // detach the thread's user thread
2016 user_thread* userThread = thread->user_thread;
2017 thread->user_thread = NULL;
2021 // Delete the thread's user thread, if it's not the main thread. If it
2024 if (thread != team->main_thread)
2030 if (team->address_space != NULL && thread->user_stack_area >= 0) {
2031 userStackArea = thread->user_stack_area;
2032 thread->user_stack_area = -1;
2041 user_debug_thread_exiting(thread);
2043 if (team->main_thread == thread) {
2044 // The main thread is exiting. Shut down the whole team.
2065 ThreadLocker threadLocker(thread);
2072 WriteSpinLocker teamLocker(thread->team_lock);
2074 // removing the thread and putting its death entry to the parent
2077 // remember how long this thread lasted
2082 SpinLocker threadTimeLocker(thread->time_lock);
2084 thread->kernel_time += now - thread->last_time;
2085 thread->last_time = now;
2087 team->dead_threads_kernel_time += thread->kernel_time;
2088 team->dead_threads_user_time += thread->user_time;
2090 // stop/update thread/team CPU time user timers
2091 if (thread->HasActiveCPUTimeUserTimers()
2093 user_timer_stop_cpu_timers(thread, NULL);
2096 // deactivate CPU time user timers for the thread
2097 if (thread->HasActiveCPUTimeUserTimers())
2098 thread->DeactivateCPUTimeUserTimers();
2102 // put the thread into the kernel team until it dies
2103 remove_thread_from_team(team, thread);
2104 insert_thread_into_team(kernelTeam, thread);
2181 // The thread is not the main thread. We store a thread death entry
2184 && list_is_empty(&thread->exit.waiters)) {
2185 threadDeathEntry->thread = thread->id;
2186 threadDeathEntry->status = thread->exit.status;
2188 // add entry to dead thread list
2200 TRACE(("thread_exit: thread %" B_PRId32 " now a kernel thread!\n",
2201 thread->id));
2204 // delete the team if we're its main thread
2212 ThreadLocker threadLocker(thread);
2219 thread->visible = false;
2223 // Stop debugging for this thread
2224 SpinLocker threadDebugInfoLocker(thread->debug_info.lock);
2225 debugInfo = thread->debug_info;
2226 clear_thread_debug_info(&thread->debug_info, true);
2230 select_info* selectInfos = thread->select_infos;
2231 thread->select_infos = NULL;
2252 sNotificationService.Notify(THREAD_REMOVED, thread);
2254 // shutdown the thread messaging
2256 status = acquire_sem_etc(thread->msg.write_sem, 1, B_RELATIVE_TIMEOUT, 0);
2261 delete_sem(thread->msg.write_sem);
2266 delete_sem(thread->msg.write_sem);
2269 delete_sem(thread->msg.read_sem);
2274 sem_id cachedExitSem = thread->exit.sem;
2276 ThreadLocker threadLocker(thread);
2279 thread->exit.sem = -1;
2284 &thread->exit.waiters, entry)) != NULL) {
2285 entry->status = thread->exit.status;
2293 // delete the user stack, if this was a user thread
2296 // notifications for the thread's death are out already and all other
2297 // threads waiting for this thread's death and some object on its stack
2299 // relevance is probably the case where this is the main thread and
2309 user_debug_thread_deleted(teamID, thread->id);
2312 UndertakerEntry undertakerEntry(thread, teamID);
2316 SpinLocker schedulerLocker(thread->scheduler_lock);
2329 /*! Called in the interrupt handler code when a thread enters
2337 Thread *thread = thread_get_current_thread();
2339 TRACE(("thread_at_kernel_entry: entry thread %" B_PRId32 "\n", thread->id));
2342 SpinLocker threadTimeLocker(thread->time_lock);
2343 thread->user_time += now - thread->last_time;
2344 thread->last_time = now;
2345 thread->in_kernel = true;
2350 /*! Called whenever a thread exits kernel space to user space.
2354 The function may not return. This e.g. happens when the thread has received
2360 Thread *thread = thread_get_current_thread();
2362 TRACE(("thread_at_kernel_exit: exit thread %" B_PRId32 "\n", thread->id));
2364 handle_signals(thread);
2368 update_thread_sigmask_on_exit(thread);
2372 SpinLocker threadTimeLocker(thread->time_lock);
2373 thread->in_kernel = false;
2374 thread->kernel_time += now - thread->last_time;
2375 thread->last_time = now;
2386 Thread *thread = thread_get_current_thread();
2388 TRACE(("thread_at_kernel_exit_no_signals: exit thread %" B_PRId32 "\n",
2389 thread->id));
2391 update_thread_sigmask_on_exit(thread);
2395 SpinLocker threadTimeLocker(thread->time_lock);
2396 thread->in_kernel = false;
2397 thread->kernel_time += now - thread->last_time;
2398 thread->last_time = now;
2405 Thread* thread = thread_get_current_thread();
2407 ThreadLocker threadLocker(thread);
2410 thread->DeleteUserTimers(true);
2413 if (UserTimer* timer = thread->UserTimerFor(USER_TIMER_REAL_TIME_ID))
2417 thread->user_thread = NULL;
2418 thread->user_stack_area = -1;
2419 thread->user_stack_base = 0;
2420 thread->user_stack_size = 0;
2423 thread->ResetSignalsOnExec();
2425 // reset thread CPU time clock
2426 InterruptsSpinLocker timeLocker(thread->time_lock);
2427 thread->cpu_clock_offset = -thread->CPUTime(false);
2461 Thread will continue to run, if there's no other thread in ready
2468 Thread *thread = thread_get_current_thread();
2469 if (thread == NULL)
2472 InterruptsSpinLocker _(thread->scheduler_lock);
2474 thread->has_yielded = true;
2480 thread_map(void (*function)(Thread* thread, void* data), void* data)
2485 Thread* thread = it.Next();) {
2486 function(thread, data);
2491 /*! Kernel private thread creation function.
2512 // get the thread, queue our death entry, and fetch the semaphore we have to
2517 Thread* thread = Thread::GetAndLock(id);
2518 if (thread != NULL) {
2520 exitSem = thread->exit.sem;
2522 list_add_link_to_head(&thread->exit.waiters, &death);
2524 thread->UnlockAndReleaseReference();
2529 // we couldn't find this thread -- maybe it's already gone, and we'll
2544 // check the thread death entries of the team (non-main threads)
2548 if (threadDeathEntry->thread == id) {
2560 // we found the thread's death entry in our team
2567 // we need to wait for the death of the thread
2570 // make sure we don't wait forever on a suspended thread
2575 // this should never happen as the thread deletes the semaphore on exit
2576 panic("could acquire exit_sem for thread %" B_PRId32 "\n", id);
2578 // this is the way the thread normally exits
2583 thread = Thread::GetAndLock(id);
2584 if (thread != NULL) {
2586 thread->UnlockAndReleaseReference();
2588 // The thread is already gone, so we need to wait uninterruptibly
2590 // It won't take long, since the thread is apparently already in the
2607 // get and lock the thread
2608 Thread* thread = Thread::GetAndLock(id);
2609 if (thread == NULL)
2611 BReference<Thread> threadReference(thread, true);
2612 ThreadLocker threadLocker(thread, true);
2619 info->next = thread->select_infos;
2620 thread->select_infos = info;
2633 // get and lock the thread
2634 Thread* thread = Thread::GetAndLock(id);
2635 if (thread == NULL)
2637 BReference<Thread> threadReference(thread, true);
2638 ThreadLocker threadLocker(thread, true);
2641 select_info** infoLocation = &thread->select_infos;
2674 /*! Returns a user-readable string for a thread state.
2678 thread_state_to_text(Thread* thread, int32 state)
2680 return state_to_text(thread, state);
2687 Thread* thread = Thread::GetAndLock(id);
2688 if (thread == NULL)
2690 BReference<Thread> threadReference(thread, true);
2691 ThreadLocker threadLocker(thread, true);
2693 int32 priority = thread->io_priority;
2696 priority = thread->priority;
2706 Thread* thread = thread_get_current_thread();
2707 ThreadLocker threadLocker(thread);
2709 thread->io_priority = priority;
2718 // create the thread hash table
2721 panic("thread_init(): failed to init thread hash table!");
2723 // create the thread structure object cache
2726 // Note: The x86 port requires 64 byte alignment of thread structures.
2728 panic("thread_init(): failed to allocate thread object cache!");
2733 // skip all thread IDs including B_SYSTEM_TEAM, which is reserved
2736 // create an idle thread for each cpu
2738 Thread *thread;
2742 sprintf(name, "idle thread %" B_PRIu32, i + 1);
2743 thread = new(&sIdleThreads[i]) Thread(name,
2745 if (thread == NULL || thread->Init(true) != B_OK) {
2746 panic("error creating idle thread struct\n");
2750 gCPU[i].running_thread = thread;
2752 thread->team = team_get_kernel_team();
2753 thread->priority = B_IDLE_PRIORITY;
2754 thread->state = B_THREAD_RUNNING;
2755 sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1);
2756 thread->kernel_stack_area = find_area(name);
2758 if (get_area_info(thread->kernel_stack_area, &info) != B_OK)
2761 thread->kernel_stack_base = (addr_t)info.address;
2762 thread->kernel_stack_top = thread->kernel_stack_base + info.size;
2764 thread->visible = true;
2765 insert_thread_into_team(thread->team, thread);
2767 scheduler_on_thread_init(thread);
2776 // start the undertaker thread
2783 panic("Failed to create undertaker thread!");
2810 add_debugger_command_etc("thread", &dump_thread_info,
2811 "Dump info about a particular thread",
2813 "Prints information about the specified thread. If no argument is\n"
2814 "given the current thread is selected.\n"
2816 " <id> - The ID of the thread.\n"
2817 " <address> - The address of the thread structure.\n"
2818 " <name> - The thread's name.\n", 0);
2827 " <id> - The ID of the thread.\n", 0);
2829 "Suspend a thread",
2831 "Suspends the thread with the given ID. If no ID argument is given\n"
2832 "the current thread is selected.\n"
2833 " <id> - The ID of the thread.\n", 0);
2834 add_debugger_command_etc("resume", &make_thread_resumed, "Resume a thread",
2836 "Resumes the specified thread, if it is currently suspended.\n"
2837 " <id> - The ID of the thread.\n", 0);
2839 "Drop a thread into the userland debugger",
2841 "Drops the specified (userland) thread into the userland debugger\n"
2843 " <id> - The ID of the thread.\n", 0);
2845 "Set a thread's priority",
2847 "Sets the priority of the thread with the specified ID to the given\n"
2848 "priority. If no thread ID is given, the current thread is selected.\n"
2849 " <priority> - The thread's new priority (0 - 120)\n"
2850 " <id> - The ID of the thread.\n", 0);
2859 // set up the cpu pointer in the not yet initialized per-cpu idle thread
2868 // #pragma mark - thread blocking API
2874 Thread* thread = (Thread*)timer->user_data;
2875 thread_unblock(thread, B_TIMED_OUT);
2881 /*! Blocks the current thread.
2883 The thread is blocked until someone else unblock it. Must be called after a
2884 call to thread_prepare_to_block(). If the thread has already been unblocked
2891 \param thread The current thread.
2898 thread_block_locked(Thread* thread)
2900 if (thread->wait.status == 1) {
2902 if (thread_is_interrupted(thread, thread->wait.flags)) {
2903 thread->wait.status = B_INTERRUPTED;
2908 return thread->wait.status;
2912 /*! Blocks the current thread.
2925 /*! Blocks the current thread with a timeout.
2927 The current thread is blocked until someone else unblock it or the specified
2929 the thread has already been unblocked after the previous call to
2954 Thread* thread = thread_get_current_thread();
2956 InterruptsSpinLocker locker(thread->scheduler_lock);
2958 if (thread->wait.status != 1)
2959 return thread->wait.status;
2976 thread->wait.unblock_timer.user_data = thread;
2977 add_timer(&thread->wait.unblock_timer, &thread_block_timeout, timeout,
2982 status_t error = thread_block_locked(thread);
2988 cancel_timer(&thread->wait.unblock_timer);
2994 /*! Unblocks a thread.
3000 thread_unblock(Thread* thread, status_t status)
3002 InterruptsSpinLocker locker(thread->scheduler_lock);
3003 thread_unblock_locked(thread, status);
3007 /*! Unblocks a userland-blocked thread.
3013 // get the thread
3014 Thread* thread = Thread::GetAndLock(threadID);
3015 if (thread == NULL)
3017 BReference<Thread> threadReference(thread, true);
3018 ThreadLocker threadLocker(thread, true);
3020 if (thread->user_thread == NULL)
3023 InterruptsSpinLocker locker(thread->scheduler_lock);
3026 if (user_memcpy(&waitStatus, &thread->user_thread->wait_status,
3031 if (user_memcpy(&thread->user_thread->wait_status, &status,
3037 // case that this thread is actually blocked on something else.
3038 if (thread->wait.status > 0
3039 && thread->wait.type == THREAD_BLOCK_TYPE_USER) {
3040 thread_unblock_locked(thread, status);
3048 thread_check_permissions(const Thread* currentThread, const Thread* thread,
3054 if (thread->team->id == team_get_kernel_team_id())
3057 if (thread->team == currentThread->team
3059 || thread->team->real_uid == currentThread->team->real_uid)
3074 Thread* thread = Thread::Get(id);
3075 if (thread == NULL)
3077 BReference<Thread> threadReference(thread, true);
3080 if (!thread_check_permissions(currentThread, thread, kernel))
3084 return send_signal_to_thread(thread, signal, 0);
3094 Thread *thread = thread_get_current_thread();
3095 Team* team = thread->team;
3097 thread->exit.status = returnValue;
3099 // if called from a kernel thread, we don't deliver the signal,
3103 // If this is its main thread, set the team's exit status.
3104 if (thread == team->main_thread) {
3119 send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE);
3140 send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize)
3142 return send_data_etc(thread, code, buffer, bufferSize, 0);
3157 Thread* thread;
3160 thread = currentThread;
3162 thread = Thread::Get(id);
3163 if (thread == NULL)
3166 threadReference.SetTo(thread, true);
3169 if (!kernel && thread->team != currentThread->team)
3173 if (get_sem_count(thread->msg.read_sem, &count) != B_OK)
3181 has_data(thread_id thread)
3183 return thread_has_data(thread, true);
3193 // get the thread
3194 Thread* thread = Thread::GetAndLock(id);
3195 if (thread == NULL)
3197 BReference<Thread> threadReference(thread, true);
3198 ThreadLocker threadLocker(thread, true);
3201 InterruptsSpinLocker locker(thread->scheduler_lock);
3203 fill_thread_info(thread, info, size);
3225 Thread* thread = NULL;
3228 // We start with the main thread
3229 thread = team->main_thread;
3231 // Find the one thread with an ID greater than ours (as long as the IDs
3240 thread = next;
3244 if (thread == NULL)
3247 lastID = thread->id;
3250 ThreadLocker threadLocker(thread);
3251 InterruptsSpinLocker locker(thread->scheduler_lock);
3253 fill_thread_info(thread, info, size);
3267 // Scanning the whole hash with the thread hash lock held isn't exactly
3272 Thread* thread = it.Next();) {
3273 if (!thread->visible)
3276 if (strcmp(thread->name, name) == 0)
3277 return thread->id;
3290 // get the thread
3291 Thread* thread = Thread::GetAndLock(id);
3292 if (thread == NULL)
3294 BReference<Thread> threadReference(thread, true);
3295 ThreadLocker threadLocker(thread, true);
3298 if (thread->team != thread_get_current_thread()->team)
3301 strlcpy(thread->name, name, B_OS_NAME_LENGTH);
3303 team_id teamID = thread->team->id;
3309 // don't pass the thread structure, as it's unsafe, if it isn't ours
3324 // get the thread
3325 Thread* thread = Thread::GetAndLock(id);
3326 if (thread == NULL)
3328 BReference<Thread> threadReference(thread, true);
3329 ThreadLocker threadLocker(thread, true);
3332 if (thread_is_idle_thread(thread) || !thread_check_permissions(
3333 thread_get_current_thread(), thread, kernel))
3336 return scheduler_set_thread_priority(thread, priority);
3373 wait_for_thread(thread_id thread, status_t *_returnCode)
3375 return wait_for_thread_etc(thread, 0, 0, _returnCode);
3457 _user_kill_thread(thread_id thread)
3459 return thread_kill_thread(thread, false);
3470 // get and lock the thread
3471 Thread* thread = Thread::GetAndLock(threadID);
3472 if (thread == NULL)
3474 BReference<Thread> threadReference(thread, true);
3475 ThreadLocker threadLocker(thread, true);
3478 if (thread->team != thread_get_current_thread()->team)
3482 thread->cancel_function = cancelFunction;
3484 // send the cancellation signal to the thread
3485 InterruptsReadSpinLocker teamLocker(thread->team_lock);
3486 SpinLocker locker(thread->team->signal_lock);
3487 return send_signal_to_thread_locked(thread, SIGNAL_CANCEL_THREAD, NULL, 0);
3492 _user_resume_thread(thread_id thread)
3494 return thread_resume_thread(thread, false);
3499 _user_suspend_thread(thread_id thread)
3501 return thread_suspend_thread(thread, false);
3506 _user_rename_thread(thread_id thread, const char *userName)
3515 // rename_thread() forbids thread renames across teams, so we don't
3517 return rename_thread(thread, name);
3522 _user_set_thread_priority(thread_id thread, int32 newPriority)
3524 return thread_set_thread_priority(thread, newPriority, false);
3539 // create the thread
3562 Thread* thread = thread_get_current_thread();
3564 if ((thread->flags & THREAD_FLAGS_SYSCALL_RESTARTED) != 0) {
3568 = (restart_parameters*)thread->syscall_restart.parameters;
3618 = (restart_parameters*)thread->syscall_restart.parameters;
3624 atomic_or(&thread->flags, THREAD_FLAGS_RESTART_SYSCALL);
3740 _user_has_data(thread_id thread)
3742 return thread_has_data(thread, false);
3747 _user_send_data(thread_id thread, int32 code, const void *buffer,
3753 return send_data_etc(thread, code, buffer, bufferSize,
3787 Thread* thread = thread_get_current_thread();
3788 ThreadLocker threadLocker(thread);
3792 if (user_memcpy(&waitStatus, &thread->user_thread->wait_status,
3800 // Note: GCC 13 marks the following call as potentially overflowing, since it thinks `thread`
3805 thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_USER, NULL);
3815 // Favor a wake-up by another thread, i.e. if someone changed the wait
3818 if (user_memcpy(&oldStatus, &thread->user_thread->wait_status,
3823 if (user_memcpy(&thread->user_thread->wait_status, &status,
3923 Thread* thread = thread_get_current_thread();
3924 return thread->cpu->cpu_num;