Added a boolean "force" parameter to thread_yield(). When true, the

function has the old behavior. When false, it just calls the scheduler
without any priority adjustment or other stuff.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23906 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-02-07 11:40:31 +00:00
parent d082779211
commit 9835c090a6
4 changed files with 36 additions and 20 deletions
+1 -1
View File
@@ -34,7 +34,7 @@ void thread_reset_for_exec(void);
status_t thread_init(struct kernel_args *args);
status_t thread_preboot_init_percpu(struct kernel_args *args, int32 cpuNum);
void thread_yield(void);
void thread_yield(bool force);
void thread_exit(void);
int32 thread_max_threads(void);
+32 -16
View File
@@ -1622,29 +1622,45 @@ peek_next_thread_id(void)
}
/*! Yield the CPU to other threads.
If \a force is \c true, the thread will almost guaranteedly be unscheduled.
If \c false, it will continue to run, if there's no other thread in ready
state, and if it has a higher priority than the other ready threads, it
still has a good chance to continue.
*/
void
thread_yield(void)
thread_yield(bool force)
{
// snooze for roughly 3 thread quantums
snooze_etc(9000, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT);
if (force) {
// snooze for roughly 3 thread quantums
snooze_etc(9000, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT);
#if 0
cpu_status state;
cpu_status state;
struct thread *thread = thread_get_current_thread();
if (thread == NULL)
return;
struct thread *thread = thread_get_current_thread();
if (thread == NULL)
return;
state = disable_interrupts();
GRAB_THREAD_LOCK();
state = disable_interrupts();
GRAB_THREAD_LOCK();
// mark the thread as yielded, so it will not be scheduled next
//thread->was_yielded = true;
thread->next_priority = B_LOWEST_ACTIVE_PRIORITY;
scheduler_reschedule();
// mark the thread as yielded, so it will not be scheduled next
//thread->was_yielded = true;
thread->next_priority = B_LOWEST_ACTIVE_PRIORITY;
scheduler_reschedule();
RELEASE_THREAD_LOCK();
restore_interrupts(state);
RELEASE_THREAD_LOCK();
restore_interrupts(state);
#endif
} else {
struct thread *thread = thread_get_current_thread();
if (thread == NULL)
return;
// Don't force the thread off the CPU, just reschedule.
InterruptsSpinLocker _(thread_spinlock);
scheduler_reschedule();
}
}
@@ -2463,7 +2479,7 @@ _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags)
void
_user_thread_yield(void)
{
thread_yield();
thread_yield(true);
}
+2 -2
View File
@@ -718,7 +718,7 @@ MultiAddressSpaceLocker::AddAreaCacheAndLock(area_id areaID,
memcpy(fItems, originalItems, fCount * sizeof(lock_item));
if (yield)
thread_yield();
thread_yield(true);
}
}
@@ -3941,7 +3941,7 @@ fault_find_page(vm_translation_map *map, vm_cache *topCache,
// with his only consumer (cacheRef); since its pages are moved
// upwards, too, we try this cache again
mutex_unlock(&cache->lock);
thread_yield();
thread_yield(true);
mutex_lock(&cache->lock);
if (cache->busy) {
// The cache became busy, which means, it is about to be
+1 -1
View File
@@ -959,7 +959,7 @@ page_writer(void* /*unused*/)
if (cache->store->ops->acquire_unreferenced_ref(cache->store)
!= B_OK) {
cacheLocker.Unlock();
thread_yield();
thread_yield(true);
continue;
}
}