diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 72370a86dc..2af9d0a7f5 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -222,7 +222,7 @@ struct Thread : TeamThreadIteratorEntry, KernelReferenceable { // enabled, etc.) int64 serial_number; // immutable after adding thread to hash Thread *hash_next; // protected by thread hash lock - Thread *team_next; // protected by team lock and fLock + DoublyLinkedListLink team_link; // protected by team lock and fLock char name[B_OS_NAME_LENGTH]; // protected by fLock bool going_to_suspend; // protected by scheduler lock int32 priority; // protected by scheduler lock @@ -467,8 +467,8 @@ struct Team : TeamThreadIteratorEntry, KernelReferenceable, VMAddressSpace *address_space; Thread *main_thread; // protected by fLock, immutable // after first set - Thread *thread_list; // protected by fLock, signal_lock and - // gThreadCreationLock + DoublyLinkedList > + thread_list; // protected by fLock, signal_lock and gThreadCreationLock struct team_loading_info *loading_info; // protected by fLock DoublyLinkedList image_list; // protected by sImageMutex struct list watcher_list; diff --git a/src/system/kernel/debug/core_dump.cpp b/src/system/kernel/debug/core_dump.cpp index c1ec010418..506bdc1da4 100644 --- a/src/system/kernel/debug/core_dump.cpp +++ b/src/system/kernel/debug/core_dump.cpp @@ -877,8 +877,8 @@ private: { int32 count = 0; - for (Thread* thread = fTeam->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = fTeam->thread_list.First(); thread != NULL; + thread = fTeam->thread_list.GetNext(thread)) { count++; if (setFlag) { atomic_or(&thread->flags, THREAD_FLAGS_TRAP_FOR_CORE_DUMP); @@ -907,8 +907,8 @@ private: fThreadCount = 0; int32 missing = 0; - for (Thread* thread = fTeam->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = fTeam->thread_list.First(); thread != NULL; + thread = fTeam->thread_list.GetNext(thread)) { fThreadCount++; ThreadState* state = fPreAllocatedThreadStates.RemoveHead(); if (state != NULL) { diff --git a/src/system/kernel/debug/user_debugger.cpp b/src/system/kernel/debug/user_debugger.cpp index ceceef730a..b884212294 100644 --- a/src/system/kernel/debug/user_debugger.cpp +++ b/src/system/kernel/debug/user_debugger.cpp @@ -171,14 +171,16 @@ update_threads_breakpoints_flag() TeamLocker teamLocker(team); - Thread* thread = team->thread_list; - if (arch_has_breakpoints(&team->debug_info.arch_info)) { - for (; thread != NULL; thread = thread->team_next) + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { atomic_or(&thread->flags, THREAD_FLAGS_BREAKPOINTS_DEFINED); + } } else { - for (; thread != NULL; thread = thread->team_next) + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { atomic_and(&thread->flags, ~THREAD_FLAGS_BREAKPOINTS_DEFINED); + } } } @@ -205,14 +207,16 @@ update_thread_debugger_installed_flag(Thread* thread) static void update_threads_debugger_installed_flag(Team* team) { - Thread* thread = team->thread_list; - if (atomic_get(&team->debug_info.flags) & B_TEAM_DEBUG_DEBUGGER_INSTALLED) { - for (; thread != NULL; thread = thread->team_next) + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { atomic_or(&thread->flags, THREAD_FLAGS_DEBUGGER_INSTALLED); + } } else { - for (; thread != NULL; thread = thread->team_next) + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { atomic_and(&thread->flags, ~THREAD_FLAGS_DEBUGGER_INSTALLED); + } } } @@ -2606,8 +2610,8 @@ install_team_debugger_init_debug_infos(Team *team, team_id debuggerTeam, arch_clear_team_debug_info(&team->debug_info.arch_info); // set the user debug flags and signal masks of all threads to the default - for (Thread *thread = team->thread_list; thread; - thread = thread->team_next) { + for (Thread *thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { SpinLocker threadDebugInfoLocker(thread->debug_info.lock); if (thread->id == nubThread) { diff --git a/src/system/kernel/signal.cpp b/src/system/kernel/signal.cpp index e7ab42c68c..923eb8c973 100644 --- a/src/system/kernel/signal.cpp +++ b/src/system/kernel/signal.cpp @@ -785,8 +785,8 @@ update_current_thread_signals_flag() static void update_team_threads_signal_flag(Team* team) { - for (Thread* thread = team->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { update_thread_signals_flag(thread); } } @@ -1307,8 +1307,8 @@ is_team_signal_blocked(Team* team, int signal) { sigset_t mask = SIGNAL_TO_MASK(signal); - for (Thread* thread = team->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { if ((thread->sig_block_mask & mask) == 0) return false; } @@ -1672,8 +1672,8 @@ send_signal_to_team_locked(Team* team, uint32 signalNumber, Signal* signal, case SIGCONT: // Wake up any suspended threads, interrupt the others, if they // don't block the signal. - for (Thread* thread = team->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { thread->going_to_suspend = false; SpinLocker _(thread->scheduler_lock); @@ -1698,8 +1698,8 @@ send_signal_to_team_locked(Team* team, uint32 signalNumber, Signal* signal, case SIGTTOU: // send the stop signal to all threads // TODO: Is that correct or should we only target the main thread? - for (Thread* thread = team->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { thread->AddPendingSignal(signalNumber); } @@ -1714,8 +1714,8 @@ send_signal_to_team_locked(Team* team, uint32 signalNumber, Signal* signal, default: // Interrupt all interruptibly waiting threads, if the signal is // not masked. - for (Thread* thread = team->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { sigset_t nonBlocked = ~thread->sig_block_mask | SIGNAL_TO_MASK(SIGCHLD); if ((thread->AllPendingSignals() & nonBlocked) != 0) { @@ -2030,8 +2030,8 @@ sigaction_internal(int signal, const struct sigaction* act, team->RemovePendingSignal(signal); - for (Thread* thread = team->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { thread->RemovePendingSignal(signal); } } diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 1cf9bf61eb..c93905d2dd 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -461,7 +461,6 @@ Team::Team(team_id id, bool kernel) address_space = NULL; main_thread = NULL; - thread_list = NULL; loading_info = NULL; list_init(&watcher_list); @@ -938,8 +937,8 @@ Team::CPUTime(bool ignoreCurrentRun, Thread* lockedThread) const Thread* currentThread = thread_get_current_thread(); bigtime_t now = system_time(); - for (Thread* thread = thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = thread_list.First(); thread != NULL; + thread = thread_list.GetNext(thread)) { bool alreadyLocked = thread == lockedThread; SpinLocker threadTimeLocker(thread->time_lock, alreadyLocked); time += thread->kernel_time + thread->user_time; @@ -970,8 +969,8 @@ Team::UserCPUTime() const bigtime_t now = system_time(); - for (Thread* thread = thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = thread_list.First(); thread != NULL; + thread = thread_list.GetNext(thread)) { SpinLocker threadTimeLocker(thread->time_lock); time += thread->user_time; @@ -1161,7 +1160,7 @@ _dump_team_info(Team* team) (void*)team->user_data, team->user_data_area); kprintf("free user thread: %p\n", team->free_user_threads); kprintf("main_thread: %p\n", team->main_thread); - kprintf("thread_list: %p\n", team->thread_list); + kprintf("thread_list: %p\n", team->thread_list.First()); kprintf("group_id: %" B_PRId32 "\n", team->group_id); kprintf("session_id: %" B_PRId32 "\n", team->session_id); } @@ -1963,8 +1962,8 @@ exec_team(const char* path, char**& _flatArgs, size_t flatArgsSize, debugInfoLocker.Unlock(); - for (Thread* thread = team->thread_list; thread != NULL; - thread = thread->team_next) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { if (thread != team->main_thread && thread->id != nubThreadID) return B_NOT_ALLOWED; } @@ -2785,9 +2784,8 @@ common_get_team_usage_info(team_id id, int32 who, team_usage_info* info, switch (who) { case B_TEAM_USAGE_SELF: { - Thread* thread = team->thread_list; - - for (; thread != NULL; thread = thread->team_next) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { InterruptsSpinLocker threadTimeLocker(thread->time_lock); kernelTime += thread->kernel_time; userTime += thread->user_time; @@ -2804,9 +2802,8 @@ common_get_team_usage_info(team_id id, int32 who, team_usage_info* info, for (; child != NULL; child = team->children.GetNext(child)) { TeamLocker childLocker(child); - Thread* thread = child->thread_list; - - for (; thread != NULL; thread = thread->team_next) { + for (Thread* thread = child->thread_list.First(); thread != NULL; + thread = child->thread_list.GetNext(thread)) { InterruptsSpinLocker threadTimeLocker(thread->time_lock); kernelTime += thread->kernel_time; userTime += thread->user_time; @@ -3236,15 +3233,13 @@ team_shutdown_team(Team* team) team->death_entry = &deathEntry; deathEntry.remaining_threads = 0; - Thread* thread = team->thread_list; - while (thread != NULL) { + for (Thread* thread = team->thread_list.First(); thread != NULL; + thread = team->thread_list.GetNext(thread)) { if (thread != team->main_thread) { Signal signal(SIGKILLTHR, SI_USER, B_OK, team->id); send_signal_to_thread(thread, signal, B_DO_NOT_RESCHEDULE); deathEntry.remaining_threads++; } - - thread = thread->team_next; } if (deathEntry.remaining_threads == 0) @@ -3255,9 +3250,7 @@ team_shutdown_team(Team* team) deathEntry.condition.Add(&entry); teamLocker.Unlock(); - entry.Wait(); - teamLocker.Lock(); } diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index fe686c0cf6..b486582530 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -264,7 +264,6 @@ Thread::Thread(const char* name, thread_id threadID, struct cpu_ent* cpu) flags(0), serial_number(-1), hash_next(NULL), - team_next(NULL), priority(-1), io_priority(-1), cpu(cpu), @@ -708,8 +707,7 @@ ThreadCreationAttributes::InitFromUserAttributes( static void insert_thread_into_team(Team *team, Thread *thread) { - thread->team_next = team->thread_list; - team->thread_list = thread; + team->thread_list.Add(thread, false); team->num_threads++; if (team->num_threads == 1) { @@ -727,20 +725,8 @@ insert_thread_into_team(Team *team, Thread *thread) static void remove_thread_from_team(Team *team, Thread *thread) { - Thread *temp, *last = NULL; - - for (temp = team->thread_list; temp != NULL; temp = temp->team_next) { - if (temp == thread) { - if (last == NULL) - team->thread_list = temp->team_next; - else - last->team_next = temp->team_next; - - team->num_threads--; - break; - } - last = temp; - } + team->thread_list.Remove(thread); + team->num_threads--; } @@ -1874,7 +1860,7 @@ _dump_thread_info(Thread *thread, bool shortInfo) kprintf("serial_number: %" B_PRId64 "\n", thread->serial_number); kprintf("name: \"%s\"\n", thread->name); kprintf("hash_next: %p\nteam_next: %p\n", - thread->hash_next, thread->team_next); + thread->hash_next, thread->team_link.next); kprintf("priority: %" B_PRId32 " (I/O: %" B_PRId32 ")\n", thread->priority, thread->io_priority); kprintf("state: %s\n", state_to_text(thread, thread->state)); @@ -3339,8 +3325,8 @@ _get_next_thread_info(team_id teamID, int32 *_cookie, thread_info *info, // don't wrap they are always sorted from highest to lowest). // TODO: That is broken not only when the IDs wrap, but also for the // kernel team, to which threads are added when they are dying. - for (Thread* next = team->thread_list; next != NULL; - next = next->team_next) { + for (Thread* next = team->thread_list.First(); next != NULL; + next = team->thread_list.GetNext(next)) { if (next->id <= lastID) break;