[haiku-commits] r33737 - haiku/trunk/src/system/kernel

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 23 Oct 2009 02:09:45 +0200 (CEST)

Author: axeld
Date: 2009-10-23 02:09:45 +0200 (Fri, 23 Oct 2009)
New Revision: 33737
Changeset: http://dev.haiku-os.org/changeset/33737/haiku

Modified:
   haiku/trunk/src/system/kernel/thread.cpp
Log:
* Reimplemented the insane _get_next_thread_info() which previously just
  iterated over all known thread *IDs* with interrupts disabled.
  Now it iterates over the team's thread list (going from back to front, since
  new threads are added at the front of the singly linked queue).
* Alexandre restarted Tracker quite a lot, and let the shell script run to
  reproduce a certain bug - and then wondered why ProcessController would
  take several seconds to open its windows until it passed through more than
  8 million IDs... :-)


Modified: haiku/trunk/src/system/kernel/thread.cpp
===================================================================
--- haiku/trunk/src/system/kernel/thread.cpp    2009-10-22 23:50:15 UTC (rev 
33736)
+++ haiku/trunk/src/system/kernel/thread.cpp    2009-10-23 00:09:45 UTC (rev 
33737)
@@ -6,6 +6,7 @@
  * Distributed under the terms of the NewOS License.
  */
 
+
 /*! Threading routines */
 
 
@@ -2453,49 +2454,50 @@
 
 
 status_t
-_get_next_thread_info(team_id team, int32 *_cookie, thread_info *info,
+_get_next_thread_info(team_id teamID, int32 *_cookie, thread_info *info,
        size_t size)
 {
-       status_t status = B_BAD_VALUE;
-       struct thread *thread = NULL;
-       cpu_status state;
-       int slot;
-       thread_id lastThreadID;
-
-       if (info == NULL || size != sizeof(thread_info) || team < B_OK)
+       if (info == NULL || size != sizeof(thread_info) || teamID < 0)
                return B_BAD_VALUE;
 
-       if (team == B_CURRENT_TEAM)
-               team = team_get_current_team_id();
-       else if (!team_is_valid(team))
-               return B_BAD_VALUE;
+       int32 lastID = *_cookie;
 
-       slot = *_cookie;
+       InterruptsSpinLocker teamLocker(gTeamSpinlock);
 
-       state = disable_interrupts();
-       GRAB_THREAD_LOCK();
+       struct team* team;
+       if (teamID == B_CURRENT_TEAM)
+               team = thread_get_current_thread()->team;
+       else
+               team = team_get_team_struct_locked(teamID);
 
-       lastThreadID = peek_next_thread_id();
-       if (slot >= lastThreadID)
-               goto err;
+       struct thread* thread = NULL;
 
-       while (slot < lastThreadID
-               && (!(thread = thread_get_thread_struct_locked(slot))
-                       || thread->team->id != team))
-               slot++;
+       if (lastID == 0) {
+               // We start with the main thread
+               thread = team->main_thread;
+       } else {
+               // Find the one thread with an ID higher than ours
+               // (as long as the IDs don't overlap they are always sorted from
+               // highest to lowest).
+               for (struct thread* next = team->thread_list; next != NULL;
+                               next = next->team_next) {
+                       if (next->id <= lastID)
+                               break;
 
-       if (thread != NULL && thread->team->id == team) {
-               fill_thread_info(thread, info, size);
-
-               *_cookie = slot + 1;
-               status = B_OK;
+                       thread = next;
+               }
        }
 
-err:
-       RELEASE_THREAD_LOCK();
-       restore_interrupts(state);
+       if (thread == NULL)
+               return B_BAD_VALUE;
 
-       return status;
+       lastID = thread->id;
+       *_cookie = lastID;
+
+       SpinLocker threadLocker(gThreadSpinlock);
+       fill_thread_info(thread, info, size);
+
+       return B_OK;
 }
 
 


Other related posts:

  • » [haiku-commits] r33737 - haiku/trunk/src/system/kernel - axeld