Added a real yield function to the kernel (using the next_priority approach).
The test application lets run a thread at the highest priority that calls yield all the time - the system stays responsible when it runs, so it seems to work fine :) Changed the malloc implementation to use _kern_thread_yield() instead of snoozing. We should think about making this call public, too. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16166 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d14af9fde6
commit
204131dc97
@ -96,6 +96,7 @@ extern status_t _kern_rename_thread(thread_id thread, const char *newName);
|
||||
extern status_t _kern_set_thread_priority(thread_id thread, int32 newPriority);
|
||||
extern status_t _kern_kill_thread(thread_id thread);
|
||||
extern void _kern_exit_thread(status_t returnValue);
|
||||
extern void _kern_thread_yield(void);
|
||||
extern status_t _kern_wait_for_thread(thread_id thread, status_t *_returnCode);
|
||||
extern bool _kern_has_data(thread_id thread);
|
||||
extern status_t _kern_send_data(thread_id thread, int32 code, const void *buffer, size_t bufferSize);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@ -31,6 +31,7 @@ void thread_at_kernel_exit(void);
|
||||
|
||||
status_t thread_init(struct kernel_args *args);
|
||||
status_t thread_per_cpu_init(int32 cpuNum);
|
||||
void thread_yield(void);
|
||||
void thread_exit(void);
|
||||
|
||||
bigtime_t thread_get_active_cpu_time(int32 cpuNum);
|
||||
@ -66,6 +67,7 @@ thread_id _user_spawn_thread(thread_entry_func entry, const char *name, int32 pr
|
||||
status_t _user_wait_for_thread(thread_id id, status_t *_returnCode);
|
||||
status_t _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags);
|
||||
status_t _user_kill_thread(thread_id thread);
|
||||
void _user_thread_yield(void);
|
||||
void _user_exit_thread(status_t return_value);
|
||||
bool _user_has_data(thread_id thread);
|
||||
status_t _user_send_data(thread_id thread, int32 code, const void *buffer, size_t buffer_size);
|
||||
|
@ -1232,19 +1232,40 @@ thread_dequeue_id(struct thread_queue *q, thread_id id)
|
||||
|
||||
|
||||
thread_id
|
||||
allocate_thread_id()
|
||||
allocate_thread_id(void)
|
||||
{
|
||||
return atomic_add(&sNextThreadID, 1);
|
||||
}
|
||||
|
||||
|
||||
thread_id
|
||||
peek_next_thread_id()
|
||||
peek_next_thread_id(void)
|
||||
{
|
||||
return atomic_get(&sNextThreadID);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
thread_yield(void)
|
||||
{
|
||||
cpu_status state;
|
||||
|
||||
struct thread *thread = thread_get_current_thread();
|
||||
if (thread == NULL)
|
||||
return;
|
||||
|
||||
state = disable_interrupts();
|
||||
GRAB_THREAD_LOCK();
|
||||
|
||||
// just add the thread at the end of the run queue
|
||||
thread->next_priority = B_LOWEST_ACTIVE_PRIORITY;
|
||||
scheduler_reschedule();
|
||||
|
||||
RELEASE_THREAD_LOCK();
|
||||
restore_interrupts(state);
|
||||
}
|
||||
|
||||
|
||||
/** Kernel private thread creation function.
|
||||
*
|
||||
* \param threadID The ID to be assigned to the new thread. If
|
||||
@ -2044,6 +2065,13 @@ _user_snooze_etc(bigtime_t timeout, int timebase, uint32 flags)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_user_thread_yield(void)
|
||||
{
|
||||
thread_yield();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_user_get_thread_info(thread_id id, thread_info *userInfo)
|
||||
{
|
||||
|
@ -317,10 +317,7 @@ hoardUnlock(hoardLockType &lock)
|
||||
void
|
||||
hoardYield(void)
|
||||
{
|
||||
// We need to snooze longer than a thread quantum (3ms) to ensure
|
||||
// real-time threads won't hog the CPU completely
|
||||
// ToDo: we should have a real one in the kernel
|
||||
snooze(4000);
|
||||
_kern_thread_yield();
|
||||
}
|
||||
|
||||
} // namespace BPrivate
|
||||
|
@ -1,20 +1,19 @@
|
||||
SubDir HAIKU_TOP src tests system kernel ;
|
||||
|
||||
UsePrivateHeaders kernel ;
|
||||
|
||||
if $(TARGET_PLATFORM) = r5 {
|
||||
LIBROOT = root ;
|
||||
} else {
|
||||
LIBROOT = libroot.so ;
|
||||
}
|
||||
UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ;
|
||||
|
||||
SimpleTest transfer_area_test :
|
||||
transfer_area_test.cpp
|
||||
: libroot.so ;
|
||||
;
|
||||
|
||||
SimpleTest syscall_time :
|
||||
syscall_time.cpp
|
||||
: $(LIBROOT) ;
|
||||
;
|
||||
|
||||
SimpleTest yield_test :
|
||||
yield_test.cpp
|
||||
;
|
||||
|
||||
SubInclude HAIKU_TOP src tests system kernel cache ;
|
||||
#SubInclude HAIKU_TOP src tests system kernel disk_device_manager ;
|
||||
|
33
src/tests/system/kernel/yield_test.cpp
Normal file
33
src/tests/system/kernel/yield_test.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2006, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include <syscalls.h>
|
||||
|
||||
|
||||
status_t
|
||||
looper(void *)
|
||||
{
|
||||
while (true) {
|
||||
_kern_thread_yield();
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
thread_id thread = spawn_thread(looper, "Real-Time Looper", B_REAL_TIME_PRIORITY, NULL);
|
||||
if (thread < B_OK)
|
||||
return -1;
|
||||
|
||||
resume_thread(thread);
|
||||
wait_for_thread(thread, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user