[haiku-commits] BRANCH pdziepak-github.scheduler [879ceb6] in src/system/kernel/scheduler: . src/system/kernel

  • From: pdziepak-github.scheduler <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 9 Oct 2013 02:00:34 +0200 (CEST)

added 8 changesets to branch 'refs/remotes/pdziepak-github/scheduler'
old head: 03e3a8295375a672734943bcaa489ad09b22ac35
new head: 879ceb60d824345ff90f2f1d6a1e22a086dbe29f
overview: https://github.com/pdziepak/Haiku/compare/03e3a82...879ceb6

----------------------------------------------------------------------------

94f4574: kernel: Move thread retrieving code to separate function

346e789: kernel: Fix style issues

9363e99: kernel: Remove Thread::next_priority

ee69e53: kernel: Minor improvements, separate priority and yield logic

0896565: kernel: Support sched_yield() properly
  
  sched_yield() should not yield to the threads with lower priority.

f256b4a: kernel: Use SimpleRunQueue as run queue type everywhere

130000e: kernel: Dump scheduler specific thread data

879ceb6: kernel: Remove suporfluous casts

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

5 files changed, 157 insertions(+), 144 deletions(-)
headers/private/kernel/thread_types.h            |   4 +-
src/system/kernel/scheduler/scheduler_affine.cpp |  11 +-
src/system/kernel/scheduler/scheduler_simple.cpp | 225 ++++++++++---------
.../kernel/scheduler/scheduler_simple_smp.cpp    |  11 +-
src/system/kernel/thread.cpp                     |  50 ++---

############################################################################

Commit:      94f4574d78aca6445d60c0c04105f91b1ff01558
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Oct  8 18:13:10 2013 UTC

kernel: Move thread retrieving code to separate function

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp 
b/src/system/kernel/scheduler/scheduler_simple.cpp
index db51e53..2cafe65 100644
--- a/src/system/kernel/scheduler/scheduler_simple.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple.cpp
@@ -346,6 +346,35 @@ static inline bigtime_t simple_compute_quantum(Thread* 
thread)
 }
 
 
+static inline Thread*
+simple_get_next_thread(void)
+{
+       Thread* thread;
+       do {
+               thread = sRunQueue->PeekMaximum();
+
+               if (sYieldedThreadPriority >= 0 && thread != NULL
+                       && thread_is_idle_thread(thread)) {
+                       sRunQueue->Remove(thread);
+                       simple_enqueue_in_run_queue(thread);
+                       continue;
+               }
+
+               break;
+       } while (true);
+       if (thread == NULL && sYieldedThreadPriority >= 0) {
+               SimpleRunQueue* temp = sRunQueue;
+               sRunQueue = sExpiredQueue;
+               sExpiredQueue = temp;
+               sYieldedThreadPriority = -1;
+
+               thread = sRunQueue->PeekMaximum();
+       }
+
+       return thread;
+}
+
+
 /*!    Runs the scheduler.
        Note: expects thread spinlock to be held
 */
@@ -353,7 +382,6 @@ static void
 simple_reschedule(void)
 {
        Thread* oldThread = thread_get_current_thread();
-       Thread* nextThread;
 
        // check whether we're only supposed to reschedule, if the current 
thread
        // is idle
@@ -417,29 +445,9 @@ simple_reschedule(void)
        schedulerOldThreadData->lost_cpu = false;
 
        // select thread with the biggest priority
-       do {
-               nextThread = sRunQueue->PeekMaximum();
-
-               if (sYieldedThreadPriority >= 0 && nextThread != NULL
-                       && thread_is_idle_thread(nextThread)) {
-                       sRunQueue->Remove(nextThread);
-                       simple_enqueue_in_run_queue(nextThread);
-                       continue;
-               }
-
-               break;
-       } while (true);
-       if (nextThread == NULL && sYieldedThreadPriority >= 0) {
-               RunQueue<Thread, THREAD_MAX_SET_PRIORITY>* temp = sRunQueue;
-               sRunQueue = sExpiredQueue;
-               sExpiredQueue = temp;
-               sYieldedThreadPriority = -1;
-
-               nextThread = sRunQueue->PeekMaximum();
-       }
+       Thread* nextThread = simple_get_next_thread();
        if (!nextThread)
-               panic("reschedule(): run queue is empty!\n");
-
+               panic("reschedule(): run queues are empty!\n");
        sRunQueue->Remove(nextThread);
 
        T(ScheduleThread(nextThread, oldThread));

############################################################################

Commit:      346e789a21882595ca008f58303ab76787691dc7
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Oct  8 18:15:21 2013 UTC

kernel: Fix style issues

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp 
b/src/system/kernel/scheduler/scheduler_simple.cpp
index 2cafe65..3601c0a 100644
--- a/src/system/kernel/scheduler/scheduler_simple.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple.cpp
@@ -92,7 +92,7 @@ dump_queue(RunQueue<Thread, 
THREAD_MAX_SET_PRIORITY>::ConstIterator& iterator)
        else {
                kprintf("thread      id      priority penalty  name\n");
                while (iterator.HasNext()) {
-                       Thread *thread = iterator.Next();
+                       Thread* thread = iterator.Next();
                        scheduler_thread_data* schedulerThreadData
                                = reinterpret_cast<scheduler_thread_data*>(
                                        thread->scheduler_data);
@@ -105,7 +105,7 @@ dump_queue(RunQueue<Thread, 
THREAD_MAX_SET_PRIORITY>::ConstIterator& iterator)
 
 
 static int
-dump_run_queue(int argc, char **argv)
+dump_run_queue(int argc, char** argv)
 {
        RunQueue<Thread, THREAD_MAX_SET_PRIORITY>::ConstIterator iterator;
        kprintf("Current run queue:\n");
@@ -129,7 +129,7 @@ simple_yield(Thread* thread)
 
 
 static inline int32
-simple_get_effective_priority(Thread *thread)
+simple_get_effective_priority(Thread* thread)
 {
        if (thread->priority == B_IDLE_PRIORITY)
                return thread->priority;
@@ -157,7 +157,7 @@ simple_get_effective_priority(Thread *thread)
 
 
 static inline void
-simple_increase_penalty(Thread *thread)
+simple_increase_penalty(Thread* thread)
 {
        if (thread->priority <= B_LOWEST_ACTIVE_PRIORITY)
                return;
@@ -181,7 +181,7 @@ simple_increase_penalty(Thread *thread)
 
 
 static inline void
-simple_cancel_penalty(Thread *thread)
+simple_cancel_penalty(Thread* thread)
 {
        scheduler_thread_data* schedulerThreadData
                = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
@@ -200,7 +200,7 @@ simple_cancel_penalty(Thread *thread)
        Note: thread lock must be held when entering this function
 */
 static void
-simple_enqueue_in_run_queue(Thread *thread)
+simple_enqueue_in_run_queue(Thread* thread)
 {
        thread->state = thread->next_state = B_THREAD_READY;
 
@@ -243,7 +243,7 @@ simple_enqueue_in_run_queue(Thread *thread)
        Note: thread lock must be held when entering this function
 */
 static void
-simple_set_thread_priority(Thread *thread, int32 priority)
+simple_set_thread_priority(Thread* thread, int32 priority)
 {
        if (priority == thread->priority)
                return;
@@ -290,7 +290,7 @@ simple_estimate_max_scheduling_latency(Thread* thread)
 
 
 static int32
-reschedule_event(timer *unused)
+reschedule_event(timer* /* unused */)
 {
        // This function is called as a result of the timer event set by the
        // scheduler. Make sure the reschedule() is invoked.

############################################################################

Commit:      9363e99b19d122db7d6684b06d7240fb73255cd2
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Oct  8 18:21:35 2013 UTC

kernel: Remove Thread::next_priority

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/thread_types.h 
b/headers/private/kernel/thread_types.h
index 637c5be..3e4ec90 100644
--- a/headers/private/kernel/thread_types.h
+++ b/headers/private/kernel/thread_types.h
@@ -422,7 +422,6 @@ struct Thread : TeamThreadIteratorEntry<thread_id>, 
KernelReferenceable,
        timer                   alarm;                  // protected by 
scheduler lock
        char                    name[B_OS_NAME_LENGTH]; // protected by fLock
        int32                   priority;               // protected by 
scheduler lock
-       int32                   next_priority;  // protected by scheduler lock
        int32                   io_priority;    // protected by fLock
        int32                   state;                  // protected by 
scheduler lock
        int32                   next_state;             // protected by 
scheduler lock
diff --git a/src/system/kernel/scheduler/scheduler_affine.cpp 
b/src/system/kernel/scheduler/scheduler_affine.cpp
index 059df02..f5b7294 100644
--- a/src/system/kernel/scheduler/scheduler_affine.cpp
+++ b/src/system/kernel/scheduler/scheduler_affine.cpp
@@ -154,7 +154,7 @@ affine_enqueue_in_run_queue(Thread *thread)
        } else {
                Thread *curr, *prev;
                for (curr = sRunQueue[targetCPU], prev = NULL; curr
-                       && curr->priority >= thread->next_priority;
+                       && curr->priority >= thread->priority;
                        curr = curr->queue_next) {
                        if (prev)
                                prev = prev->queue_next;
@@ -173,8 +173,6 @@ affine_enqueue_in_run_queue(Thread *thread)
                thread->scheduler_data->fLastQueue = targetCPU;
        }
 
-       thread->next_priority = thread->priority;
-
        // notify listeners
        NotifySchedulerListeners(&SchedulerListener::ThreadEnqueuedInRunQueue,
                thread);
@@ -304,7 +302,7 @@ affine_set_thread_priority(Thread *thread, int32 priority)
        thread = dequeue_from_run_queue(prev, targetCPU);
 
        // set priority and re-insert
-       thread->priority = thread->next_priority = priority;
+       thread->priority = priority;
        affine_enqueue_in_run_queue(thread);
 }
 
diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp 
b/src/system/kernel/scheduler/scheduler_simple.cpp
index 3601c0a..99818d8 100644
--- a/src/system/kernel/scheduler/scheduler_simple.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple.cpp
@@ -152,7 +152,7 @@ simple_get_effective_priority(Thread* thread)
        ASSERT(schedulerThreadData->priority_penalty >= 0);
        ASSERT(effectivePriority >= B_LOWEST_ACTIVE_PRIORITY);
 
-       return min_c(effectivePriority, thread->next_priority);
+       return effectivePriority;
 }
 
 
@@ -217,7 +217,6 @@ simple_enqueue_in_run_queue(Thread* thread)
        else
                sRunQueue->PushBack(thread, threadPriority);
 
-       thread->next_priority = thread->priority;
        schedulerThreadData->cpu_bound = true;
        schedulerThreadData->time_left = 0;
        schedulerThreadData->stolen_time = 0;
@@ -267,7 +266,7 @@ simple_set_thread_priority(Thread* thread, int32 priority)
 
        // set priority and re-insert
        simple_cancel_penalty(thread);
-       thread->priority = thread->next_priority = priority;
+       thread->priority = priority;
 
        simple_enqueue_in_run_queue(thread);
 }
diff --git a/src/system/kernel/scheduler/scheduler_simple_smp.cpp 
b/src/system/kernel/scheduler/scheduler_simple_smp.cpp
index 6665612..092fd70 100644
--- a/src/system/kernel/scheduler/scheduler_simple_smp.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple_smp.cpp
@@ -118,7 +118,7 @@ enqueue_in_run_queue(Thread *thread)
 
        Thread *curr, *prev;
        for (curr = sRunQueue, prev = NULL; curr
-                       && curr->priority >= thread->next_priority;
+                       && curr->priority >= thread->priority;
                        curr = curr->queue_next) {
                if (prev)
                        prev = prev->queue_next;
@@ -134,8 +134,6 @@ enqueue_in_run_queue(Thread *thread)
        else
                sRunQueue = thread;
 
-       thread->next_priority = thread->priority;
-
        if (thread->priority != B_IDLE_PRIORITY) {
                // Select a CPU for the thread to run on. It's not certain that 
the
                // thread will actually run on it, but we will notify the CPU to
@@ -211,7 +209,7 @@ set_thread_priority(Thread *thread, int32 priority)
                sRunQueue = item->queue_next;
 
        // set priority and re-insert
-       thread->priority = thread->next_priority = priority;
+       thread->priority = priority;
        enqueue_in_run_queue(thread);
 }
 
diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
index 0c785a2..e2dc89c 100644
--- a/src/system/kernel/thread.cpp
+++ b/src/system/kernel/thread.cpp
@@ -167,7 +167,6 @@ Thread::Thread(const char* name, thread_id threadID, struct 
cpu_ent* cpu)
        team_next(NULL),
        queue_next(NULL),
        priority(-1),
-       next_priority(-1),
        io_priority(-1),
        cpu(cpu),
        previous_cpu(NULL),
@@ -901,7 +900,6 @@ thread_create_thread(const ThreadCreationAttributes& 
attributes, bool kernel)
                // available for deinitialization
        thread->priority = attributes.priority == -1
                ? B_NORMAL_PRIORITY : attributes.priority;
-       thread->next_priority = thread->priority;
        thread->state = B_THREAD_SUSPENDED;
        thread->next_state = B_THREAD_SUSPENDED;
 
@@ -1427,7 +1425,7 @@ make_thread_unreal(int argc, char **argv)
                        continue;
 
                if (thread->priority > B_DISPLAY_PRIORITY) {
-                       thread->priority = thread->next_priority = 
B_NORMAL_PRIORITY;
+                       thread->priority = B_NORMAL_PRIORITY;
                        kprintf("thread %" B_PRId32 " made unreal\n", 
thread->id);
                }
        }
@@ -1463,7 +1461,7 @@ set_thread_prio(int argc, char **argv)
                        Thread* thread = it.Next();) {
                if (thread->id != id)
                        continue;
-               thread->priority = thread->next_priority = prio;
+               thread->priority = prio;
                kprintf("thread %" B_PRId32 " set to priority %" B_PRId32 "\n", 
id, prio);
                found = true;
                break;
@@ -1702,9 +1700,8 @@ _dump_thread_info(Thread *thread, bool shortInfo)
        kprintf("name:               \"%s\"\n", thread->name);
        kprintf("hash_next:          %p\nteam_next:          %p\nq_next:        
     %p\n",
                thread->hash_next, thread->team_next, thread->queue_next);
-       kprintf("priority:           %" B_PRId32 " (next %" B_PRId32 ", "
-               "I/O: %" B_PRId32 ")\n", thread->priority, 
thread->next_priority,
-               thread->io_priority);
+       kprintf("priority:           %" B_PRId32 " (I/O: %" B_PRId32 ")\n",
+               thread->priority, thread->io_priority);
        kprintf("state:              %s\n", state_to_text(thread, 
thread->state));
        kprintf("next_state:         %s\n", state_to_text(thread, 
thread->next_state));
        kprintf("cpu:                %p ", thread->cpu);
@@ -1919,7 +1916,7 @@ thread_exit(void)
                panic("thread_exit() called with interrupts disabled!\n");
 
        // boost our priority to get this over with
-       thread->priority = thread->next_priority = B_URGENT_DISPLAY_PRIORITY;
+       thread->priority = B_URGENT_DISPLAY_PRIORITY;
 
        if (team != kernelTeam) {
                // Cancel previously installed alarm timer, if any. Hold the 
scheduler
@@ -2730,7 +2727,7 @@ thread_init(kernel_args *args)
                gCPU[i].running_thread = thread;
 
                thread->team = team_get_kernel_team();
-               thread->priority = thread->next_priority = B_IDLE_PRIORITY;
+               thread->priority = B_IDLE_PRIORITY;
                thread->state = B_THREAD_RUNNING;
                thread->next_state = B_THREAD_READY;
                sprintf(name, "idle thread %" B_PRIu32 " kstack", i + 1);
@@ -3217,7 +3214,7 @@ set_thread_priority(thread_id id, int32 priority)
                // It's ourself, so we know we aren't in the run queue, and we 
can
                // manipulate our structure directly.
                oldPriority = thread->priority;
-               thread->priority = thread->next_priority = priority;
+               thread->priority = priority;
        } else {
                oldPriority = thread->priority;
                scheduler_set_thread_priority(thread, priority);

############################################################################

Commit:      ee69e536309045ba557e9defc2436eefb06d88d3
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Oct  8 19:36:49 2013 UTC

kernel: Minor improvements, separate priority and yield logic

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp 
b/src/system/kernel/scheduler/scheduler_simple.cpp
index 99818d8..bf1a402 100644
--- a/src/system/kernel/scheduler/scheduler_simple.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple.cpp
@@ -120,36 +120,21 @@ dump_run_queue(int argc, char** argv)
 }
 
 
-static inline void
-simple_yield(Thread* thread)
-{
-       TRACE("thread %ld yielded\n", thread->id);
-       sYieldedThreadPriority = max_c(sYieldedThreadPriority, 
thread->priority);
-}
-
-
 static inline int32
 simple_get_effective_priority(Thread* thread)
 {
        if (thread->priority == B_IDLE_PRIORITY)
                return thread->priority;
+       if (thread->priority >= B_FIRST_REAL_TIME_PRIORITY)
+               return thread->priority;
 
        scheduler_thread_data* schedulerThreadData
                = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
 
        int32 effectivePriority = thread->priority;
-       if (effectivePriority < B_FIRST_REAL_TIME_PRIORITY) {
-               const int kYieldFrequency = 1 << (min_c(thread->priority, 25) / 
5 + 1);
-               if (schedulerThreadData->forced_yield_count != 0
-                       && schedulerThreadData->forced_yield_count % 
kYieldFrequency == 0) {
-                       TRACE("forcing thread %ld to yield\n", thread->id);
-                       simple_yield(thread);
-               }
+       effectivePriority -= schedulerThreadData->priority_penalty;
 
-               effectivePriority -= schedulerThreadData->priority_penalty;
-       }
-
-       ASSERT(schedulerThreadData->priority_penalty >= 0);
+       ASSERT(effectivePriority < B_FIRST_REAL_TIME_PRIORITY);
        ASSERT(effectivePriority >= B_LOWEST_ACTIVE_PRIORITY);
 
        return effectivePriority;
@@ -157,6 +142,31 @@ simple_get_effective_priority(Thread* thread)
 
 
 static inline void
+simple_yield(Thread* thread)
+{
+       TRACE("thread %ld yielded\n", thread->id);
+       int32 effectivePriority = simple_get_effective_priority(thread);
+       sYieldedThreadPriority = max_c(sYieldedThreadPriority, 
effectivePriority);
+}
+
+
+static inline bool
+simple_should_force_yield(Thread* thread)
+{
+       if (thread->priority >= B_FIRST_REAL_TIME_PRIORITY)
+               return false;
+
+       scheduler_thread_data* schedulerThreadData
+               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
+
+       const int kYieldFrequency = 1 << (min_c(thread->priority, 25) / 5 + 1);
+
+       return schedulerThreadData->forced_yield_count != 0
+               && schedulerThreadData->forced_yield_count % kYieldFrequency == 
0;
+}
+
+
+static inline void
 simple_increase_penalty(Thread* thread)
 {
        if (thread->priority <= B_LOWEST_ACTIVE_PRIORITY)
@@ -186,9 +196,6 @@ simple_cancel_penalty(Thread* thread)
        scheduler_thread_data* schedulerThreadData
                = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
 
-       if (schedulerThreadData->went_sleep < 0
-               || system_time() - schedulerThreadData->went_sleep <= 
kThreadQuantum)
-               return;
        if (schedulerThreadData->priority_penalty != 0)
                TRACE("cancelling thread %ld penalty\n", thread->id);
        schedulerThreadData->priority_penalty = 0;
@@ -196,22 +203,24 @@ simple_cancel_penalty(Thread* thread)
 }
 
 
-/*!    Enqueues the thread into the run queue.
-       Note: thread lock must be held when entering this function
-*/
 static void
-simple_enqueue_in_run_queue(Thread* thread)
+simple_enqueue(Thread* thread, bool newOne)
 {
        thread->state = thread->next_state = B_THREAD_READY;
 
-       simple_cancel_penalty(thread);
+       scheduler_thread_data* schedulerThreadData
+               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
+
+       bigtime_t hasSlept = system_time() - schedulerThreadData->went_sleep;
+       if (newOne && hasSlept > kThreadQuantum)
+               simple_cancel_penalty(thread);
+
+       if (simple_should_force_yield(thread))
+               simple_yield(thread);
 
        int32 threadPriority = simple_get_effective_priority(thread);
        T(EnqueueThread(thread, threadPriority));
 
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
-
        if (threadPriority <= sYieldedThreadPriority)
                sExpiredQueue->PushBack(thread, threadPriority);
        else
@@ -226,7 +235,7 @@ simple_enqueue_in_run_queue(Thread* thread)
                thread);
 
        Thread* currentThread = thread_get_current_thread();
-       if (threadPriority > currentThread->priority) {
+       if (newOne && threadPriority > currentThread->priority) {
                scheduler_thread_data* schedulerCurrentThreadData
                        = reinterpret_cast<scheduler_thread_data*>(
                                currentThread->scheduler_data);
@@ -238,6 +247,16 @@ simple_enqueue_in_run_queue(Thread* thread)
 }
 
 
+/*!    Enqueues the thread into the run queue.
+       Note: thread lock must be held when entering this function
+*/
+static void
+simple_enqueue_in_run_queue(Thread* thread)
+{
+       simple_enqueue(thread, true);
+}
+
+
 /*!    Sets the priority of a thread.
        Note: thread lock must be held when entering this function
 */
@@ -406,8 +425,6 @@ simple_reschedule(void)
                                schedulerOldThreadData->cpu_bound = false;
 
                        if (simple_quantum_ended(oldThread, 
oldThread->cpu->preempted)) {
-                               schedulerOldThreadData->went_sleep = -1;
-
                                if (schedulerOldThreadData->cpu_bound)
                                        simple_increase_penalty(oldThread);
                                else
@@ -415,11 +432,10 @@ simple_reschedule(void)
 
                                if (oldThread->was_yielded)
                                        simple_yield(oldThread);
-                               oldThread->was_yielded = false;
 
                                TRACE("enqueueing thread %ld into run queue 
priority = %ld\n",
                                        oldThread->id, 
simple_get_effective_priority(oldThread));
-                               simple_enqueue_in_run_queue(oldThread);
+                               simple_enqueue(oldThread, false);
                        } else {
                                TRACE("putting thread %ld back in run queue 
priority = %ld\n",
                                        oldThread->id, 
simple_get_effective_priority(oldThread));
@@ -441,6 +457,7 @@ simple_reschedule(void)
                        break;
        }
 
+       oldThread->was_yielded = false;
        schedulerOldThreadData->lost_cpu = false;
 
        // select thread with the biggest priority
@@ -449,6 +466,8 @@ simple_reschedule(void)
                panic("reschedule(): run queues are empty!\n");
        sRunQueue->Remove(nextThread);
 
+       TRACE("reschedule(): next thread = %ld\n", nextThread->id);
+
        T(ScheduleThread(nextThread, oldThread));
 
        // notify listeners

############################################################################

Commit:      0896565a6e405d3543b15772571138d622c7fba9
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Oct  8 23:18:55 2013 UTC

kernel: Support sched_yield() properly

sched_yield() should not yield to the threads with lower priority.

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/thread_types.h 
b/headers/private/kernel/thread_types.h
index 3e4ec90..23e10e9 100644
--- a/headers/private/kernel/thread_types.h
+++ b/headers/private/kernel/thread_types.h
@@ -443,7 +443,8 @@ struct Thread : TeamThreadIteratorEntry<thread_id>, 
KernelReferenceable,
 
        bool                    in_kernel;              // protected by 
time_lock, only written by
                                                                        // this 
thread
-       bool                    was_yielded;    // protected by scheduler lock
+       bool                    has_yielded;    // protected by scheduler lock
+       bool                    has_fully_yielded;      // protected by 
scheduler lock
        struct scheduler_thread_data* scheduler_data; // protected by scheduler 
lock
 
        struct user_thread*     user_thread;    // write-protected by fLock, 
only
diff --git a/src/system/kernel/scheduler/scheduler_affine.cpp 
b/src/system/kernel/scheduler/scheduler_affine.cpp
index f5b7294..fde10f0 100644
--- a/src/system/kernel/scheduler/scheduler_affine.cpp
+++ b/src/system/kernel/scheduler/scheduler_affine.cpp
@@ -447,7 +447,7 @@ affine_reschedule(void)
 
        nextThread->state = B_THREAD_RUNNING;
        nextThread->next_state = B_THREAD_READY;
-       oldThread->was_yielded = false;
+       oldThread->has_yielded = false;
 
        // track kernel time (user time is tracked in thread_at_kernel_entry())
        scheduler_update_thread_times(oldThread, nextThread);
diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp 
b/src/system/kernel/scheduler/scheduler_simple.cpp
index bf1a402..de317f1 100644
--- a/src/system/kernel/scheduler/scheduler_simple.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple.cpp
@@ -324,11 +324,17 @@ reschedule_event(timer* /* unused */)
 }
 
 
-static inline bool simple_quantum_ended(Thread* thread, bool wasPreempted)
+static inline bool 
+simple_quantum_ended(Thread* thread, bool wasPreempted, bool hasYielded)
 {
        scheduler_thread_data* schedulerThreadData
                = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
 
+       if (hasYielded) {
+               schedulerThreadData->time_left = 0;
+               return true;
+       }
+
        bigtime_t time_used = system_time() - 
schedulerThreadData->quantum_start;
        schedulerThreadData->time_left -= time_used;
        schedulerThreadData->time_left = max_c(0, 
schedulerThreadData->time_left);
@@ -343,7 +349,8 @@ static inline bool simple_quantum_ended(Thread* thread, 
bool wasPreempted)
 }
 
 
-static inline bigtime_t simple_compute_quantum(Thread* thread)
+static inline bigtime_t
+simple_compute_quantum(Thread* thread)
 {
        scheduler_thread_data* schedulerThreadData
                = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
@@ -424,13 +431,12 @@ simple_reschedule(void)
                        if (!schedulerOldThreadData->lost_cpu)
                                schedulerOldThreadData->cpu_bound = false;
 
-                       if (simple_quantum_ended(oldThread, 
oldThread->cpu->preempted)) {
+                       if (simple_quantum_ended(oldThread, 
oldThread->cpu->preempted,
+                                       oldThread->has_yielded)) {
                                if (schedulerOldThreadData->cpu_bound)
                                        simple_increase_penalty(oldThread);
-                               else
-                                       simple_cancel_penalty(oldThread);
 
-                               if (oldThread->was_yielded)
+                               if (oldThread->has_fully_yielded)
                                        simple_yield(oldThread);
 
                                TRACE("enqueueing thread %ld into run queue 
priority = %ld\n",
@@ -457,7 +463,8 @@ simple_reschedule(void)
                        break;
        }
 
-       oldThread->was_yielded = false;
+       oldThread->has_yielded = false;
+       oldThread->has_fully_yielded = false;
        schedulerOldThreadData->lost_cpu = false;
 
        // select thread with the biggest priority
diff --git a/src/system/kernel/scheduler/scheduler_simple_smp.cpp 
b/src/system/kernel/scheduler/scheduler_simple_smp.cpp
index 092fd70..d30ce9c 100644
--- a/src/system/kernel/scheduler/scheduler_simple_smp.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple_smp.cpp
@@ -384,7 +384,7 @@ reschedule(void)
 
        nextThread->state = B_THREAD_RUNNING;
        nextThread->next_state = B_THREAD_READY;
-       oldThread->was_yielded = false;
+       oldThread->has_yielded = false;
 
        // track kernel time (user time is tracked in thread_at_kernel_entry())
        scheduler_update_thread_times(oldThread, nextThread);
diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
index e2dc89c..781720c 100644
--- a/src/system/kernel/thread.cpp
+++ b/src/system/kernel/thread.cpp
@@ -178,7 +178,8 @@ Thread::Thread(const char* name, thread_id threadID, struct 
cpu_ent* cpu)
        signal_stack_size(0),
        signal_stack_enabled(false),
        in_kernel(true),
-       was_yielded(false),
+       has_yielded(false),
+       has_fully_yielded(false),
        user_thread(NULL),
        fault_handler(0),
        page_faults_allowed(1),
@@ -2443,25 +2444,15 @@ peek_next_thread_id()
 void
 thread_yield(bool force)
 {
-       if (force) {
-               Thread *thread = thread_get_current_thread();
-               if (thread == NULL)
-                       return;
-
-               InterruptsSpinLocker _(gSchedulerLock);
+       Thread *thread = thread_get_current_thread();
+       if (thread == NULL)
+               return;
 
-               // mark the thread as yielded, so it will not be scheduled next
-               thread->was_yielded = true;
-               scheduler_reschedule();
-       } else {
-               Thread *thread = thread_get_current_thread();
-               if (thread == NULL)
-                       return;
+       InterruptsSpinLocker _(gSchedulerLock);
 
-               // Don't force the thread off the CPU, just reschedule.
-               InterruptsSpinLocker _(gSchedulerLock);
-               scheduler_reschedule();
-       }
+       thread->has_yielded = true;
+       thread->has_fully_yielded = force;
+       scheduler_reschedule();
 }
 
 
@@ -3512,7 +3503,7 @@ _user_snooze_etc(bigtime_t timeout, int timebase, uint32 
flags,
 void
 _user_thread_yield(void)
 {
-       thread_yield(true);
+       thread_yield(false);
 }
 
 

############################################################################

Commit:      f256b4aca7aba52cafb5f405557d3470218f61a1
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Oct  8 23:20:40 2013 UTC

kernel: Use SimpleRunQueue as run queue type everywhere

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp 
b/src/system/kernel/scheduler/scheduler_simple.cpp
index de317f1..40a789a 100644
--- a/src/system/kernel/scheduler/scheduler_simple.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple.cpp
@@ -85,7 +85,7 @@ scheduler_thread_data::Init()
 
 
 static inline void
-dump_queue(RunQueue<Thread, THREAD_MAX_SET_PRIORITY>::ConstIterator& iterator)
+dump_queue(SimpleRunQueue::ConstIterator& iterator)
 {
        if (!iterator.HasNext())
                kprintf("Queue is empty.\n");
@@ -107,7 +107,7 @@ dump_queue(RunQueue<Thread, 
THREAD_MAX_SET_PRIORITY>::ConstIterator& iterator)
 static int
 dump_run_queue(int argc, char** argv)
 {
-       RunQueue<Thread, THREAD_MAX_SET_PRIORITY>::ConstIterator iterator;
+       SimpleRunQueue::ConstIterator iterator;
        kprintf("Current run queue:\n");
        iterator = sRunQueue->GetConstIterator();
        dump_queue(iterator);

############################################################################

Commit:      130000e068ec68a10fc632ee4ffc8a5fb563159b
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Oct  8 23:37:00 2013 UTC

kernel: Dump scheduler specific thread data

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler_affine.cpp 
b/src/system/kernel/scheduler/scheduler_affine.cpp
index fde10f0..471b53e 100644
--- a/src/system/kernel/scheduler/scheduler_affine.cpp
+++ b/src/system/kernel/scheduler/scheduler_affine.cpp
@@ -547,7 +547,8 @@ static scheduler_ops kAffineOps = {
        affine_on_thread_create,
        affine_on_thread_init,
        affine_on_thread_destroy,
-       affine_start
+       affine_start,
+       NULL
 };
 
 
diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp 
b/src/system/kernel/scheduler/scheduler_simple.cpp
index 40a789a..fe35929 100644
--- a/src/system/kernel/scheduler/scheduler_simple.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple.cpp
@@ -120,6 +120,18 @@ dump_run_queue(int argc, char** argv)
 }
 
 
+static void
+simple_dump_thread_data(scheduler_thread_data* schedulerThreadData)
+{
+       kprintf("\tpriority_penalty:\t%" B_PRId32 "\n",
+               schedulerThreadData->priority_penalty);
+       kprintf("\tforced_yield_count:\t%" B_PRId32 "\n",
+               schedulerThreadData->forced_yield_count);
+       kprintf("\tstolen_time:\t\t%" B_PRId64 "\n",
+               schedulerThreadData->stolen_time);
+}
+
+
 static inline int32
 simple_get_effective_priority(Thread* thread)
 {
@@ -563,7 +575,8 @@ static scheduler_ops kSimpleOps = {
        simple_on_thread_create,
        simple_on_thread_init,
        simple_on_thread_destroy,
-       simple_start
+       simple_start,
+       simple_dump_thread_data
 };
 
 
diff --git a/src/system/kernel/scheduler/scheduler_simple_smp.cpp 
b/src/system/kernel/scheduler/scheduler_simple_smp.cpp
index d30ce9c..e596014 100644
--- a/src/system/kernel/scheduler/scheduler_simple_smp.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple_smp.cpp
@@ -462,7 +462,8 @@ static scheduler_ops kSimpleSMPOps = {
        on_thread_create,
        on_thread_init,
        on_thread_destroy,
-       start
+       start,
+       NULL
 };
 
 
diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp
index 781720c..66972e7 100644
--- a/src/system/kernel/thread.cpp
+++ b/src/system/kernel/thread.cpp
@@ -1786,6 +1786,10 @@ _dump_thread_info(Thread *thread, bool shortInfo)
        kprintf("flags:              0x%" B_PRIx32 "\n", thread->flags);
        kprintf("architecture dependant section:\n");
        arch_thread_dump_info(&thread->arch_info);
+       if (gScheduler->dump_thread_data != NULL) {
+               kprintf("scheduler data:\n");
+               gScheduler->dump_thread_data(thread->scheduler_data);
+       }
 }
 
 

############################################################################

Commit:      879ceb60d824345ff90f2f1d6a1e22a086dbe29f
Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Tue Oct  8 23:45:07 2013 UTC

kernel: Remove suporfluous casts

----------------------------------------------------------------------------

diff --git a/src/system/kernel/scheduler/scheduler_simple.cpp 
b/src/system/kernel/scheduler/scheduler_simple.cpp
index fe35929..54bb110 100644
--- a/src/system/kernel/scheduler/scheduler_simple.cpp
+++ b/src/system/kernel/scheduler/scheduler_simple.cpp
@@ -93,12 +93,9 @@ dump_queue(SimpleRunQueue::ConstIterator& iterator)
                kprintf("thread      id      priority penalty  name\n");
                while (iterator.HasNext()) {
                        Thread* thread = iterator.Next();
-                       scheduler_thread_data* schedulerThreadData
-                               = reinterpret_cast<scheduler_thread_data*>(
-                                       thread->scheduler_data);
                        kprintf("%p  %-7" B_PRId32 " %-8" B_PRId32 " %-8" 
B_PRId32 " %s\n",
                                thread, thread->id, thread->priority,
-                               schedulerThreadData->priority_penalty, 
thread->name);
+                               thread->scheduler_data->priority_penalty, 
thread->name);
                }
        }
 }
@@ -140,11 +137,8 @@ simple_get_effective_priority(Thread* thread)
        if (thread->priority >= B_FIRST_REAL_TIME_PRIORITY)
                return thread->priority;
 
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
-
        int32 effectivePriority = thread->priority;
-       effectivePriority -= schedulerThreadData->priority_penalty;
+       effectivePriority -= thread->scheduler_data->priority_penalty;
 
        ASSERT(effectivePriority < B_FIRST_REAL_TIME_PRIORITY);
        ASSERT(effectivePriority >= B_LOWEST_ACTIVE_PRIORITY);
@@ -168,13 +162,10 @@ simple_should_force_yield(Thread* thread)
        if (thread->priority >= B_FIRST_REAL_TIME_PRIORITY)
                return false;
 
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
-
        const int kYieldFrequency = 1 << (min_c(thread->priority, 25) / 5 + 1);
 
-       return schedulerThreadData->forced_yield_count != 0
-               && schedulerThreadData->forced_yield_count % kYieldFrequency == 
0;
+       return thread->scheduler_data->forced_yield_count != 0
+               && thread->scheduler_data->forced_yield_count % kYieldFrequency 
== 0;
 }
 
 
@@ -188,8 +179,7 @@ simple_increase_penalty(Thread* thread)
 
        TRACE("increasing thread %ld penalty\n", thread->id);
 
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
+       scheduler_thread_data* schedulerThreadData = thread->scheduler_data;
        int32 oldPenalty = schedulerThreadData->priority_penalty++;
 
        ASSERT(thread->priority - oldPenalty >= B_LOWEST_ACTIVE_PRIORITY);
@@ -205,8 +195,7 @@ simple_increase_penalty(Thread* thread)
 static inline void
 simple_cancel_penalty(Thread* thread)
 {
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
+       scheduler_thread_data* schedulerThreadData = thread->scheduler_data;
 
        if (schedulerThreadData->priority_penalty != 0)
                TRACE("cancelling thread %ld penalty\n", thread->id);
@@ -220,8 +209,7 @@ simple_enqueue(Thread* thread, bool newOne)
 {
        thread->state = thread->next_state = B_THREAD_READY;
 
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
+       scheduler_thread_data* schedulerThreadData = thread->scheduler_data;
 
        bigtime_t hasSlept = system_time() - schedulerThreadData->went_sleep;
        if (newOne && hasSlept > kThreadQuantum)
@@ -248,11 +236,7 @@ simple_enqueue(Thread* thread, bool newOne)
 
        Thread* currentThread = thread_get_current_thread();
        if (newOne && threadPriority > currentThread->priority) {
-               scheduler_thread_data* schedulerCurrentThreadData
-                       = reinterpret_cast<scheduler_thread_data*>(
-                               currentThread->scheduler_data);
-
-               schedulerCurrentThreadData->lost_cpu = true;
+               currentThread->scheduler_data->lost_cpu = true;
                gCPU[0].invoke_scheduler = true;
                gCPU[0].invoke_scheduler_if_idle = false;
        }
@@ -325,10 +309,8 @@ reschedule_event(timer* /* unused */)
        // This function is called as a result of the timer event set by the
        // scheduler. Make sure the reschedule() is invoked.
        Thread* thread= thread_get_current_thread();
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
 
-       schedulerThreadData->lost_cpu = true;
+       thread->scheduler_data->lost_cpu = true;
        thread->cpu->invoke_scheduler = true;
        thread->cpu->invoke_scheduler_if_idle = false;
        thread->cpu->preempted = 1;
@@ -339,8 +321,7 @@ reschedule_event(timer* /* unused */)
 static inline bool 
 simple_quantum_ended(Thread* thread, bool wasPreempted, bool hasYielded)
 {
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
+       scheduler_thread_data* schedulerThreadData = thread->scheduler_data;
 
        if (hasYielded) {
                schedulerThreadData->time_left = 0;
@@ -364,8 +345,7 @@ simple_quantum_ended(Thread* thread, bool wasPreempted, 
bool hasYielded)
 static inline bigtime_t
 simple_compute_quantum(Thread* thread)
 {
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
+       scheduler_thread_data* schedulerThreadData = thread->scheduler_data;
 
        bigtime_t quantum;
        if (schedulerThreadData->time_left != 0)
@@ -434,8 +414,7 @@ simple_reschedule(void)
        TRACE("reschedule(): current thread = %ld\n", oldThread->id);
 
        oldThread->state = oldThread->next_state;
-       scheduler_thread_data* schedulerOldThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(oldThread->scheduler_data);
+       scheduler_thread_data* schedulerOldThreadData = 
oldThread->scheduler_data;
 
        switch (oldThread->next_state) {
                case B_THREAD_RUNNING:
@@ -542,9 +521,7 @@ simple_on_thread_create(Thread* thread, bool idleThread)
 static void
 simple_on_thread_init(Thread* thread)
 {
-       scheduler_thread_data* schedulerThreadData
-               = 
reinterpret_cast<scheduler_thread_data*>(thread->scheduler_data);
-       schedulerThreadData->Init();
+       thread->scheduler_data->Init();
 }
 
 


Other related posts:

  • » [haiku-commits] BRANCH pdziepak-github.scheduler [879ceb6] in src/system/kernel/scheduler: . src/system/kernel - pdziepak-github . scheduler