kernel: Add CPUSet::{Clear, Set}BitAtomic() functions
This commit is contained in:
parent
03451e4cc1
commit
82bcd89b92
@ -50,6 +50,9 @@ public:
|
||||
inline void SetBit(int32 cpu);
|
||||
inline void ClearBit(int32 cpu);
|
||||
|
||||
inline void SetBitAtomic(int32 cpu);
|
||||
inline void ClearBitAtomic(int32 cpu);
|
||||
|
||||
inline bool GetBit(int32 cpu) const;
|
||||
|
||||
inline bool IsEmpty() const;
|
||||
@ -118,12 +121,28 @@ inline void
|
||||
CPUSet::SetBit(int32 cpu)
|
||||
{
|
||||
int32* element = (int32*)&fBitmap[cpu % kArraySize];
|
||||
atomic_or(element, 1u << (cpu / kArraySize));
|
||||
*element |= 1u << (cpu / kArraySize);
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
CPUSet::ClearBit(int32 cpu)
|
||||
{
|
||||
int32* element = (int32*)&fBitmap[cpu % kArraySize];
|
||||
*element &= ~uint32(1u << (cpu / kArraySize));
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
CPUSet::SetBitAtomic(int32 cpu)
|
||||
{
|
||||
int32* element = (int32*)&fBitmap[cpu % kArraySize];
|
||||
atomic_or(element, 1u << (cpu / kArraySize));
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
CPUSet::ClearBitAtomic(int32 cpu)
|
||||
{
|
||||
int32* element = (int32*)&fBitmap[cpu % kArraySize];
|
||||
atomic_and(element, ~uint32(1u << (cpu / kArraySize)));
|
||||
|
@ -229,8 +229,8 @@ arch_thread_context_switch(Thread* from, Thread* to)
|
||||
!= activePagingStructures) {
|
||||
// update on which CPUs the address space is used
|
||||
int cpu = cpuData->cpu_num;
|
||||
activePagingStructures->active_on_cpus.ClearBit(cpu);
|
||||
toPagingStructures->active_on_cpus.SetBit(cpu);
|
||||
activePagingStructures->active_on_cpus.ClearBitAtomic(cpu);
|
||||
toPagingStructures->active_on_cpus.SetBitAtomic(cpu);
|
||||
|
||||
// assign the new paging structures to the CPU
|
||||
toPagingStructures->AddReference();
|
||||
|
@ -822,7 +822,7 @@ check_for_message(int currentCPU, mailbox_source& sourceMailbox)
|
||||
}
|
||||
|
||||
// mark it so we wont try to process this one again
|
||||
msg->proc_bitmap.ClearBit(currentCPU);
|
||||
msg->proc_bitmap.ClearBitAtomic(currentCPU);
|
||||
atomic_add(&gCPU[currentCPU].ici_counter, 1);
|
||||
|
||||
sourceMailbox = MAILBOX_BCAST;
|
||||
@ -1000,7 +1000,7 @@ static void
|
||||
process_early_cpu_call(int32 cpu)
|
||||
{
|
||||
sEarlyCPUCallFunction(sEarlyCPUCallCookie, cpu);
|
||||
sEarlyCPUCallSet.ClearBit(cpu);
|
||||
sEarlyCPUCallSet.ClearBitAtomic(cpu);
|
||||
atomic_add(&sEarlyCPUCallCount, 1);
|
||||
}
|
||||
|
||||
@ -1112,21 +1112,25 @@ smp_send_multicast_ici(CPUSet& cpuMask, int32 message, addr_t data,
|
||||
return;
|
||||
|
||||
int currentCPU = smp_get_current_cpu();
|
||||
bool broadcast = true;
|
||||
|
||||
// count target CPUs
|
||||
int32 targetCPUs = 0;
|
||||
for (int32 i = 0; i < sNumCPUs; i++) {
|
||||
if (cpuMask.GetBit(i))
|
||||
targetCPUs++;
|
||||
else if (i != currentCPU)
|
||||
broadcast = false;
|
||||
}
|
||||
|
||||
// find_free_message leaves interrupts disabled
|
||||
struct smp_msg *msg;
|
||||
int state = find_free_message(&msg);
|
||||
|
||||
msg->proc_bitmap = cpuMask;
|
||||
msg->proc_bitmap.ClearBit(currentCPU);
|
||||
|
||||
int32 targetCPUs = 0;
|
||||
for (int32 i = 0; i < sNumCPUs; i++) {
|
||||
if (msg->proc_bitmap.GetBit(i))
|
||||
targetCPUs++;
|
||||
}
|
||||
|
||||
if (targetCPUs == 0) {
|
||||
panic("smp_send_multicast_ici(): 0 CPU mask");
|
||||
return;
|
||||
}
|
||||
|
||||
msg->message = message;
|
||||
msg->data = data;
|
||||
msg->data2 = data2;
|
||||
@ -1136,13 +1140,7 @@ smp_send_multicast_ici(CPUSet& cpuMask, int32 message, addr_t data,
|
||||
msg->flags = flags;
|
||||
msg->done = 0;
|
||||
|
||||
msg->proc_bitmap = cpuMask;
|
||||
msg->proc_bitmap.ClearBit(currentCPU);
|
||||
if (msg->proc_bitmap.IsEmpty()) {
|
||||
panic("smp_send_multicast_ici(): 0 CPU mask");
|
||||
return;
|
||||
}
|
||||
|
||||
bool broadcast = targetCPUs == sNumCPUs - 1;
|
||||
|
||||
// stick it in the broadcast mailbox
|
||||
acquire_spinlock_nocheck(&sBroadcastMessageSpinlock);
|
||||
|
Loading…
Reference in New Issue
Block a user