kernel: Rework ppc (and m68k) atomic functions post-scheduler
* Make atomic function more like current x86 * Remove fake fallback atomic code for ppc as hardware spinlocks exist
This commit is contained in:
@@ -298,8 +298,8 @@ dprintf("handling I/O interrupts done\n");
|
|||||||
|
|
||||||
int state = disable_interrupts();
|
int state = disable_interrupts();
|
||||||
if (thread->cpu->invoke_scheduler) {
|
if (thread->cpu->invoke_scheduler) {
|
||||||
SpinLocker schedulerLocker(gSchedulerLock);
|
SpinLocker schedulerLocker(thread->scheduler_lock);
|
||||||
scheduler_reschedule();
|
scheduler_reschedule(B_THREAD_READY);
|
||||||
schedulerLocker.Unlock();
|
schedulerLocker.Unlock();
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
} else if (hardwareInterrupt && thread->post_interrupt_callback != NULL) {
|
} else if (hardwareInterrupt && thread->post_interrupt_callback != NULL) {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ UsePrivateKernelHeaders ;
|
|||||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
|
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
|
||||||
|
|
||||||
KernelMergeObject kernel_arch_ppc.o :
|
KernelMergeObject kernel_arch_ppc.o :
|
||||||
arch_atomic.cpp
|
|
||||||
arch_commpage.cpp
|
arch_commpage.cpp
|
||||||
arch_cpu.cpp
|
arch_cpu.cpp
|
||||||
arch_cpu_asm.S
|
arch_cpu_asm.S
|
||||||
|
|||||||
@@ -1,237 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2003, Marcus Overhagen. All rights reserved.
|
|
||||||
* Distributed under the terms of the OpenBeOS License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <KernelExport.h>
|
|
||||||
|
|
||||||
#include <kernel.h>
|
|
||||||
#include <user_atomic.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Emulation of 64 bit atomic functions.
|
|
||||||
* Slow, using spinlocks...
|
|
||||||
*/
|
|
||||||
|
|
||||||
static spinlock atomic_lock = 0;
|
|
||||||
|
|
||||||
int64
|
|
||||||
atomic_set64(vint64 *value, int64 newValue)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
*value = newValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
if (oldValue == testAgainst)
|
|
||||||
*value = newValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
atomic_add64(vint64 *value, int64 addValue)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
*value += addValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
atomic_and64(vint64 *value, int64 andValue)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
*value &= andValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
atomic_or64(vint64 *value, int64 orValue)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
*value |= orValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
atomic_get64(vint64 *value)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
_user_atomic_set64(vint64 *value, int64 newValue)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
if (!IS_USER_ADDRESS(value)
|
|
||||||
|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
|
|
||||||
goto access_violation;
|
|
||||||
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
*value = newValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
unlock_memory((void *)value, 8, B_READ_DEVICE);
|
|
||||||
return oldValue;
|
|
||||||
|
|
||||||
access_violation:
|
|
||||||
// XXX kill application
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
_user_atomic_test_and_set64(vint64 *value, int64 newValue, int64 testAgainst)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
if (!IS_USER_ADDRESS(value)
|
|
||||||
|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
|
|
||||||
goto access_violation;
|
|
||||||
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
if (oldValue == testAgainst)
|
|
||||||
*value = newValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
unlock_memory((void *)value, 8, B_READ_DEVICE);
|
|
||||||
return oldValue;
|
|
||||||
|
|
||||||
access_violation:
|
|
||||||
// XXX kill application
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
_user_atomic_add64(vint64 *value, int64 addValue)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
if (!IS_USER_ADDRESS(value)
|
|
||||||
|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
|
|
||||||
goto access_violation;
|
|
||||||
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
*value += addValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
unlock_memory((void *)value, 8, B_READ_DEVICE);
|
|
||||||
return oldValue;
|
|
||||||
|
|
||||||
access_violation:
|
|
||||||
// XXX kill application
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
_user_atomic_and64(vint64 *value, int64 andValue)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
if (!IS_USER_ADDRESS(value)
|
|
||||||
|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
|
|
||||||
goto access_violation;
|
|
||||||
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
*value &= andValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
unlock_memory((void *)value, 8, B_READ_DEVICE);
|
|
||||||
return oldValue;
|
|
||||||
|
|
||||||
access_violation:
|
|
||||||
// XXX kill application
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
_user_atomic_or64(vint64 *value, int64 orValue)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
if (!IS_USER_ADDRESS(value)
|
|
||||||
|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
|
|
||||||
goto access_violation;
|
|
||||||
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
*value |= orValue;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
unlock_memory((void *)value, 8, B_READ_DEVICE);
|
|
||||||
return oldValue;
|
|
||||||
access_violation:
|
|
||||||
// XXX kill application
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64
|
|
||||||
_user_atomic_get64(vint64 *value)
|
|
||||||
{
|
|
||||||
cpu_status status;
|
|
||||||
int64 oldValue;
|
|
||||||
if (!IS_USER_ADDRESS(value)
|
|
||||||
|| lock_memory((void *)value, 8, B_READ_DEVICE) != B_OK)
|
|
||||||
goto access_violation;
|
|
||||||
|
|
||||||
status = disable_interrupts();
|
|
||||||
acquire_spinlock(&atomic_lock);
|
|
||||||
oldValue = *value;
|
|
||||||
release_spinlock(&atomic_lock);
|
|
||||||
restore_interrupts(status);
|
|
||||||
unlock_memory((void *)value, 8, B_READ_DEVICE);
|
|
||||||
return oldValue;
|
|
||||||
|
|
||||||
access_violation:
|
|
||||||
// XXX kill application
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
@@ -270,12 +270,6 @@ arch_cpu_shutdown(bool reboot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
arch_cpu_idle(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// The purpose of this function is to trick the compiler. When setting the
|
// The purpose of this function is to trick the compiler. When setting the
|
||||||
// page_handler to a label that is obviously (to the compiler) never used,
|
// page_handler to a label that is obviously (to the compiler) never used,
|
||||||
// it may reorganize the control flow, so that the labeled part is optimized
|
// it may reorganize the control flow, so that the labeled part is optimized
|
||||||
|
|||||||
@@ -245,8 +245,8 @@ dprintf("handling I/O interrupts done\n");
|
|||||||
|
|
||||||
cpu_status state = disable_interrupts();
|
cpu_status state = disable_interrupts();
|
||||||
if (thread->cpu->invoke_scheduler) {
|
if (thread->cpu->invoke_scheduler) {
|
||||||
SpinLocker schedulerLocker(gSchedulerLock);
|
SpinLocker schedulerLocker(thread->scheduler_lock);
|
||||||
scheduler_reschedule();
|
scheduler_reschedule(B_THREAD_READY);
|
||||||
schedulerLocker.Unlock();
|
schedulerLocker.Unlock();
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
} else if (thread->post_interrupt_callback != NULL) {
|
} else if (thread->post_interrupt_callback != NULL) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ arch_rtc_init(kernel_args *args, struct real_time_data *data)
|
|||||||
data->arch_data.version = 0;
|
data->arch_data.version = 0;
|
||||||
|
|
||||||
// init spinlock
|
// init spinlock
|
||||||
sSetArchDataLock = 0;
|
B_INITIALIZE_SPINLOCK(&sSetArchDataLock);
|
||||||
|
|
||||||
// init system_time() conversion factor
|
// init system_time() conversion factor
|
||||||
__ppc_setup_system_time(&data->arch_data.system_time_conversion_factor);
|
__ppc_setup_system_time(&data->arch_data.system_time_conversion_factor);
|
||||||
|
|||||||
Reference in New Issue
Block a user