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:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user