Warning, cross-references for /kernel/include/smp/spinlock.h need to be fixed.
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef _SPINLOCK_H_
0019 #define _SPINLOCK_H_
0020 #include"smp/atomic.h"
0021
0022
0023 #define DEBUG_MAX_SPIN 1000000
0024
0025 struct _spinlock
0026 {
0027 uint32 lock;
0028 };
0029 typedef struct _spinlock spinlock;
0030
0031 extern volatile bool mp_enabled;
0032
0033 static inline void
0034 spinlock_lock (spinlock * lock)
0035 {
0036 extern void com1_putc (char);
0037 extern void com1_puts (char *);
0038 extern void com1_putx (uint32);
0039 uint8 LAPIC_get_physical_ID (void);
0040
0041 if (mp_enabled) {
0042 #ifdef DEBUG_SPINLOCK
0043 int count = 0;
0044 extern void panic (char *);
0045 extern void com1_printf (const char *, ...);
0046 #endif
0047 int x = 1;
0048 uint32 *addr = &lock->lock;
0049 for (;;) {
0050 asm volatile ("lock xchgl %1,(%0)":"=r" (addr),
0051 "=ir" (x):"0" (addr), "1" (x));
0052 if (x == 0)
0053 break;
0054 asm volatile ("pause");
0055 #ifdef DEBUG_SPINLOCK
0056 count++;
0057 if (count > DEBUG_MAX_SPIN) {
0058 com1_printf ("DEADLOCK (CPU %d)\n", LAPIC_get_physical_ID ());
0059 panic ("DEADLOCK\n");
0060 }
0061 #endif
0062 }
0063 }
0064 }
0065
0066 static inline void
0067 spinlock_unlock (spinlock * lock)
0068 {
0069 uint32 x = 0;
0070 uint32 *addr = &lock->lock;
0071 extern void com1_putc (char);
0072 extern void com1_puts (char *);
0073 extern void com1_putx (uint32);
0074 uint8 LAPIC_get_physical_ID (void);
0075 void stacktrace (void);
0076
0077 asm volatile ("lock xchgl %1,(%0)":"=r" (addr), "=ir" (x):"0" (addr),
0078 "1" (x));
0079 }
0080
0081 static inline void
0082 spinlock_init (spinlock * lock)
0083 {
0084 atomic_store_dword (&lock->lock, 0);
0085 }
0086
0087 #define SPINLOCK_INIT {0}
0088
0089 #endif
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100