From d8dd74308eb3ed09b1c04fa9f0416faa6f0f6916 Mon Sep 17 00:00:00 2001 From: beveloper Date: Sat, 23 Nov 2002 17:43:36 +0000 Subject: [PATCH] Optimized (yes, we shouldn't do it now) to consume less power on P4, and to have better performance on Hyper Threading systems. Should be backward compatible with all x86 systems, according to Intel documentation. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2068 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/smp.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/kernel/core/smp.c b/src/kernel/core/smp.c index d901424f21..13b1218064 100644 --- a/src/kernel/core/smp.c +++ b/src/kernel/core/smp.c @@ -26,6 +26,12 @@ #define DEBUG_SPINLOCKS 1 +#if __INTEL__ + #define PAUSE() asm volatile ("rep; nop;") +#else + #define PAUSE() +#endif + #define MSG_POOL_SIZE (SMP_MAX_CPUS * 4) struct smp_msg { @@ -71,8 +77,10 @@ acquire_spinlock(spinlock *lock) if (are_interrupts_enabled()) panic("acquire_spinlock: attempt to acquire lock %p with interrupts enabled\n", lock); while (1) { - while (*lock != 0) + while (*lock != 0) { smp_process_pending_ici(curr_cpu); + PAUSE(); + } if (atomic_set((int32 *)lock, 1) == 0) break; } @@ -85,7 +93,7 @@ acquire_spinlock(spinlock *lock) #endif } } - + static void acquire_spinlock_nocheck(spinlock *lock) @@ -97,7 +105,7 @@ acquire_spinlock_nocheck(spinlock *lock) #endif while (1) { while(*lock != 0) - ; + PAUSE(); if (atomic_set((int32 *)lock, 1) == 0) break; } @@ -143,8 +151,8 @@ find_free_message(struct smp_msg **msg) // dprintf("find_free_message: entry\n"); retry: - while(free_msg_count <= 0) - ; + while (free_msg_count <= 0) + PAUSE(); state = disable_interrupts(); acquire_spinlock(&free_msg_spinlock); @@ -394,8 +402,10 @@ smp_send_ici(int target_cpu, int message, unsigned long data, unsigned long data // wait for the other cpu to finish processing it // the interrupt handler will ref count it to <0 // if the message is sync after it has removed it from the mailbox - while (msg->done == false) + while (msg->done == false) { smp_process_pending_ici(curr_cpu); + PAUSE(); + } // for SYNC messages, it's our responsibility to put it // back into the free list return_free_message(msg); @@ -450,8 +460,10 @@ smp_send_broadcast_ici(int message, unsigned long data, unsigned long data2, uns // the interrupt handler will ref count it to <0 // if the message is sync after it has removed it from the mailbox // dprintf("smp_send_broadcast_ici: waiting for ack\n"); - while (msg->done == false) + while (msg->done == false) { smp_process_pending_ici(curr_cpu); + PAUSE(); + } // dprintf("smp_send_broadcast_ici: returning message to free list\n"); // for SYNC messages, it's our responsibility to put it // back into the free list