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();
|
||||
if (thread->cpu->invoke_scheduler) {
|
||||
SpinLocker schedulerLocker(gSchedulerLock);
|
||||
scheduler_reschedule();
|
||||
SpinLocker schedulerLocker(thread->scheduler_lock);
|
||||
scheduler_reschedule(B_THREAD_READY);
|
||||
schedulerLocker.Unlock();
|
||||
restore_interrupts(state);
|
||||
} else if (hardwareInterrupt && thread->post_interrupt_callback != NULL) {
|
||||
|
||||
@@ -6,7 +6,6 @@ UsePrivateKernelHeaders ;
|
||||
SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) generic ] ;
|
||||
|
||||
KernelMergeObject kernel_arch_ppc.o :
|
||||
arch_atomic.cpp
|
||||
arch_commpage.cpp
|
||||
arch_cpu.cpp
|
||||
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
|
||||
// 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
|
||||
|
||||
@@ -245,8 +245,8 @@ dprintf("handling I/O interrupts done\n");
|
||||
|
||||
cpu_status state = disable_interrupts();
|
||||
if (thread->cpu->invoke_scheduler) {
|
||||
SpinLocker schedulerLocker(gSchedulerLock);
|
||||
scheduler_reschedule();
|
||||
SpinLocker schedulerLocker(thread->scheduler_lock);
|
||||
scheduler_reschedule(B_THREAD_READY);
|
||||
schedulerLocker.Unlock();
|
||||
restore_interrupts(state);
|
||||
} 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;
|
||||
|
||||
// init spinlock
|
||||
sSetArchDataLock = 0;
|
||||
B_INITIALIZE_SPINLOCK(&sSetArchDataLock);
|
||||
|
||||
// init system_time() conversion factor
|
||||
__ppc_setup_system_time(&data->arch_data.system_time_conversion_factor);
|
||||
|
||||
Reference in New Issue
Block a user