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_init(struct kernel_args *args);
|
||||||
status_t thread_preboot_init_percpu(struct kernel_args *args, int32 cpuNum);
|
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);
|
void thread_exit(void);
|
||||||
|
|
||||||
int32 thread_max_threads(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
|
void
|
||||||
thread_yield(void)
|
thread_yield(bool force)
|
||||||
{
|
{
|
||||||
// snooze for roughly 3 thread quantums
|
if (force) {
|
||||||
snooze_etc(9000, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT);
|
// snooze for roughly 3 thread quantums
|
||||||
|
snooze_etc(9000, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT);
|
||||||
#if 0
|
#if 0
|
||||||
cpu_status state;
|
cpu_status state;
|
||||||
|
|
||||||
struct thread *thread = thread_get_current_thread();
|
struct thread *thread = thread_get_current_thread();
|
||||||
if (thread == NULL)
|
if (thread == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
GRAB_THREAD_LOCK();
|
GRAB_THREAD_LOCK();
|
||||||
|
|
||||||
// mark the thread as yielded, so it will not be scheduled next
|
// mark the thread as yielded, so it will not be scheduled next
|
||||||
//thread->was_yielded = true;
|
//thread->was_yielded = true;
|
||||||
thread->next_priority = B_LOWEST_ACTIVE_PRIORITY;
|
thread->next_priority = B_LOWEST_ACTIVE_PRIORITY;
|
||||||
scheduler_reschedule();
|
scheduler_reschedule();
|
||||||
|
|
||||||
RELEASE_THREAD_LOCK();
|
RELEASE_THREAD_LOCK();
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
#endif
|
#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
|
void
|
||||||
_user_thread_yield(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));
|
memcpy(fItems, originalItems, fCount * sizeof(lock_item));
|
||||||
|
|
||||||
if (yield)
|
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
|
// with his only consumer (cacheRef); since its pages are moved
|
||||||
// upwards, too, we try this cache again
|
// upwards, too, we try this cache again
|
||||||
mutex_unlock(&cache->lock);
|
mutex_unlock(&cache->lock);
|
||||||
thread_yield();
|
thread_yield(true);
|
||||||
mutex_lock(&cache->lock);
|
mutex_lock(&cache->lock);
|
||||||
if (cache->busy) {
|
if (cache->busy) {
|
||||||
// The cache became busy, which means, it is about to be
|
// 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)
|
if (cache->store->ops->acquire_unreferenced_ref(cache->store)
|
||||||
!= B_OK) {
|
!= B_OK) {
|
||||||
cacheLocker.Unlock();
|
cacheLocker.Unlock();
|
||||||
thread_yield();
|
thread_yield(true);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user