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:
Alexander von Gluck IV
2014-01-19 19:33:21 -06:00
parent c9e66bfc9b
commit 88c54b5485
6 changed files with 5 additions and 249 deletions
+2 -2
View File
@@ -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) {
-1
View File
@@ -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
-237
View File
@@ -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;
}
-6
View File
@@ -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
+2 -2
View File
@@ -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);